# Segment tree (Bitwise Or)
from operator import or_


class SegmentTree:
    _f = None
    _data = None
    _offset = None
    _size = None

    def __init__(self, size, f):
        self._f = f
        self._size = size
        t = 1
        while t < size:
            t *= 2
        self._offset = t - 1
        self._data = [0] * (t * 2 - 1)

    def build(self, iterable):
        f = self._f
        data = self._data
        data[self._offset:self._offset + self._size] = iterable
        for i in range(self._offset - 1, -1, -1):
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def update(self, index, value):
        f = self._f
        data = self._data
        i = self._offset + index
        data[i] = value
        while i >= 1:
            i = (i - 1) // 2
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def query(self, start, stop):
        def iter_segments(data, l, r):
            while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
        f = self._f
        it = iter_segments(self._data, start + self._offset,
                           stop + self._offset)
        result = next(it)
        for e in it:
            result = f(result, e)
        return result


def conv(c):
    return 1 << (ord(c) - ord('a'))


N = int(input())
S = input()

st = SegmentTree(N, or_)
st.build(conv(c) for c in S)

Q = int(input())
for _ in range(Q):
    q = input().split()
    if q[0] == '1':
        i, c = q[1:]
        i = int(i) - 1
        st.update(i, conv(c))
    elif q[0] == '2':
        l, r = map(int, q[1:])
        print(bin(st.query(l - 1, r)).count('1')) from operator import or_ class SegmentTree:
    _f = None
    _data = None
    _offset = None
    _size = None

    def __init__(self, size, f):
        self._f = f
        self._size = size
        t = 1
        while t < size:
            t *= 2
        self._offset = t - 1
        self._data = [0] * (t * 2 - 1)

    def build(self, iterable):
        f = self._f
        data = self._data
        data[self._offset:self._offset + self._size] = iterable
        for i in range(self._offset - 1, -1, -1):
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def update(self, index, value):
        f = self._f
        data = self._data
        i = self._offset + index
        data[i] = value
        while i >= 1:
            i = (i - 1) // 2
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def query(self, start, stop):
        def iter_segments(data, l, r):
            while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
        f = self._f
        it = iter_segments(self._data, start + self._offset,
                           stop + self._offset)
        result = next(it)
        for e in it:
            result = f(result, e)
        return result SegmentTree _f = None _f None _data = None _data None _offset = None _offset None _size = None _size None def __init__(self, size, f):
        self._f = f
        self._size = size
        t = 1
        while t < size:
            t *= 2
        self._offset = t - 1
        self._data = [0] * (t * 2 - 1)

     __init__ self._f = f self._f self _f f self._size = size self._size self _size size t = 1 t 1 while t < size:
            t *= 2
         t < size t size t *= 2 t 2 self._offset = t - 1 self._offset self _offset t - 1 t 1 self._data = [0] * (t * 2 - 1) self._data self _data [0] * (t * 2 - 1) [0] 0 t * 2 - 1 t * 2 t 2 1 self self size size f f def build(self, iterable):
        f = self._f
        data = self._data
        data[self._offset:self._offset + self._size] = iterable
        for i in range(self._offset - 1, -1, -1):
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

     build f = self._f f self._f self _f data = self._data data self._data self _data data[self._offset:self._offset + self._size] = iterable data[self._offset:self._offset + self._size] data self._offset:self._offset + self._size self._offset self _offset self._offset + self._size self._offset self _offset self._size self _size iterable for i in range(self._offset - 1, -1, -1):
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

     i range(self._offset - 1, -1, -1) range self._offset - 1 self._offset self _offset 1 -1 -1 data[i] = f(data[i * 2 + 1], data[i * 2 + 2]) data[i] data i f(data[i * 2 + 1], data[i * 2 + 2]) f data[i * 2 + 1] data i * 2 + 1 i * 2 i 2 1 data[i * 2 + 2] data i * 2 + 2 i * 2 i 2 2 self self iterable iterable def update(self, index, value):
        f = self._f
        data = self._data
        i = self._offset + index
        data[i] = value
        while i >= 1:
            i = (i - 1) // 2
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

     update f = self._f f self._f self _f data = self._data data self._data self _data i = self._offset + index i self._offset + index self._offset self _offset index data[i] = value data[i] data i value while i >= 1:
            i = (i - 1) // 2
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

     i >= 1 i 1 i = (i - 1) // 2 i (i - 1) // 2 i - 1 i 1 2 data[i] = f(data[i * 2 + 1], data[i * 2 + 2]) data[i] data i f(data[i * 2 + 1], data[i * 2 + 2]) f data[i * 2 + 1] data i * 2 + 1 i * 2 i 2 1 data[i * 2 + 2] data i * 2 + 2 i * 2 i 2 2 self self index index value value def query(self, start, stop):
        def iter_segments(data, l, r):
            while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
        f = self._f
        it = iter_segments(self._data, start + self._offset,
                           stop + self._offset)
        result = next(it)
        for e in it:
            result = f(result, e)
        return result query def iter_segments(data, l, r):
            while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
         iter_segments while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
         l < r l r if l & 1 == 0:
                    yield data[l]
                 l & 1 == 0 l & 1 l 1 0 yield data[l] data[l] data l if r & 1 == 0:
                    yield data[r - 1]
                 r & 1 == 0 r & 1 r 1 0 yield data[r - 1] data[r - 1] data r - 1 r 1 l = l // 2 l l // 2 l 2 r = (r - 1) // 2 r (r - 1) // 2 r - 1 r 1 2 data data l l r r f = self._f f self._f self _f it = iter_segments(self._data, start + self._offset,
                           stop + self._offset) it iter_segments(self._data, start + self._offset,
                           stop + self._offset) iter_segments self._data self _data start + self._offset start self._offset self _offset stop + self._offset stop self._offset self _offset result = next(it) result next(it) next it for e in it:
            result = f(result, e)
         e it result = f(result, e) result f(result, e) f result e return result result self self start start stop stop def conv(c):
    return 1 << (ord(c) - ord('a')) conv return 1 << (ord(c) - ord('a')) 1 << (ord(c) - ord('a')) 1 ord(c) - ord('a') ord(c) ord c ord('a') ord 'a' c c N = int(input()) N int(input()) int input() input S = input() S input() input st = SegmentTree(N, or_) st SegmentTree(N, or_) SegmentTree N or_ st.build(conv(c) for c in S) st.build st build conv(c) conv c Q = int(input()) Q int(input()) int input() input for _ in range(Q):
    q = input().split()
    if q[0] == '1':
        i, c = q[1:]
        i = int(i) - 1
        st.update(i, conv(c))
    elif q[0] == '2':
        l, r = map(int, q[1:])
        print(bin(st.query(l - 1, r)).count('1')) _ range(Q) range Q q = input().split() q input().split() ().split () input split if q[0] == '1':
        i, c = q[1:]
        i = int(i) - 1
        st.update(i, conv(c))
    elif q[0] == '2':
        l, r = map(int, q[1:])
        print(bin(st.query(l - 1, r)).count('1')) q[0] == '1' q[0] q 0 '1' i, c = q[1:] i q[1:] q 1: 1 c i = int(i) - 1 i int(i) - 1 int(i) int i 1 st.update(i, conv(c)) st.update st update i conv(c) conv c elif q[0] == '2':
        l, r = map(int, q[1:])
        print(bin(st.query(l - 1, r)).count('1')) q[0] == '2' q[0] q 0 '2' l, r = map(int, q[1:]) l map(int, q[1:]) map int q[1:] q 1: 1 r print(bin(st.query(l - 1, r)).count('1')) print bin(st.query(l - 1, r)).count('1') (st.query(l - 1, r)).count (st.query(l - 1, r)) bin st.query(l - 1, r) st.query st query l - 1 l 1 r count '1' r = map(int, q[1:]) map(int, q[1:]) r q = input().split() input().split() q i, c = q[1:] q[1:] i st = SegmentTree(N, or_) SegmentTree(N, or_) st l, r = map(int, q[1:]) map(int, q[1:]) l class SegmentTree:
    _f = None
    _data = None
    _offset = None
    _size = None

    def __init__(self, size, f):
        self._f = f
        self._size = size
        t = 1
        while t < size:
            t *= 2
        self._offset = t - 1
        self._data = [0] * (t * 2 - 1)

    def build(self, iterable):
        f = self._f
        data = self._data
        data[self._offset:self._offset + self._size] = iterable
        for i in range(self._offset - 1, -1, -1):
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def update(self, index, value):
        f = self._f
        data = self._data
        i = self._offset + index
        data[i] = value
        while i >= 1:
            i = (i - 1) // 2
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def query(self, start, stop):
        def iter_segments(data, l, r):
            while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
        f = self._f
        it = iter_segments(self._data, start + self._offset,
                           stop + self._offset)
        result = next(it)
        for e in it:
            result = f(result, e)
        return result class SegmentTree:
    _f = None
    _data = None
    _offset = None
    _size = None

    def __init__(self, size, f):
        self._f = f
        self._size = size
        t = 1
        while t < size:
            t *= 2
        self._offset = t - 1
        self._data = [0] * (t * 2 - 1)

    def build(self, iterable):
        f = self._f
        data = self._data
        data[self._offset:self._offset + self._size] = iterable
        for i in range(self._offset - 1, -1, -1):
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def update(self, index, value):
        f = self._f
        data = self._data
        i = self._offset + index
        data[i] = value
        while i >= 1:
            i = (i - 1) // 2
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def query(self, start, stop):
        def iter_segments(data, l, r):
            while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
        f = self._f
        it = iter_segments(self._data, start + self._offset,
                           stop + self._offset)
        result = next(it)
        for e in it:
            result = f(result, e)
        return result SegmentTree N = int(input()) int(input()) N S = input() input() S def conv(c):
    return 1 << (ord(c) - ord('a')) def conv(c):
    return 1 << (ord(c) - ord('a')) conv Q = int(input()) int(input()) Q i = int(i) - 1 int(i) - 1 i c = q[1:] q[1:] c
# Segment tree (Bitwise Or)
from operator import or_


class SegmentTree:
    _f = None
    _data = None
    _offset = None
    _size = None

    def __init__(self, size, f):
        self._f = f
        self._size = size
        t = 1
        while t < size:
            t *= 2
        self._offset = t - 1
        self._data = [0] * (t * 2 - 1)

    def build(self, iterable):
        f = self._f
        data = self._data
        data[self._offset:self._offset + self._size] = iterable
        for i in range(self._offset - 1, -1, -1):
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def update(self, index, value):
        f = self._f
        data = self._data
        i = self._offset + index
        data[i] = value
        while i >= 1:
            i = (i - 1) // 2
            data[i] = f(data[i * 2 + 1], data[i * 2 + 2])

    def query(self, start, stop):
        def iter_segments(data, l, r):
            while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
        f = self._f
        it = iter_segments(self._data, start + self._offset,
                           stop + self._offset)
        result = next(it)
        for e in it:
            result = f(result, e)
        return result


def conv(c):
    return 1 << (ord(c) - ord('a'))


N = int(input())
S = input()

st = SegmentTree(N, or_)
st.build(conv(c) for c in S)

Q = int(input())
for _ in range(Q):
    q = input().split()
    if q[0] == '1':
        i, c = q[1:]
        i = int(i) - 1
        st.update(i, conv(c))
    elif q[0] == '2':
        l, r = map(int, q[1:])
        print(bin(st.query(l - 1, r)).count('1'))
