class SegmentTree():

    _data = []

    _offset = 0

    _size = 0



    def __init__(self, size):

        _size = size

        t = 1

        while t < size:

            t *= 2

        self._offset = t - 1

        self._data = [0 for _ in range(t * 2 - 1)]



    def update_all(self, iterable):

        self._data[self._offset:self._offset+self._size] = [1 << (ord(c) - ord('a')) for c in iterable]

        for i in range(self._offset - 1, -1, -1):

            self._data[i] = self._data[i * 2 + 1] | self._data[i * 2 + 2]



    def update(self, index, value):

        i = self._offset + index

        self._data[i] = 1 << (ord(value) - ord('a'))

        while i >= 1:

            i = (i - 1) // 2

            self._data[i] = self._data[i * 2 + 1] | self._data[i * 2 + 2]



    def query(self, start, stop):

        result = 0

        l = start + self._offset

        r = stop + self._offset

        while l < r:

            if l & 1 == 0:

                result = result | self._data[l]

            if r & 1 == 0:

                result = result | self._data[r - 1]

            l = l // 2

            r = (r - 1) // 2

        return result





N = int(eval(input()))

S = eval(input())



st = SegmentTree(N)

st.update_all(S)



Q = int(eval(input()))

for _ in range(Q):

    q = input().split()

    if q[0] == '1':

        i, c = q[1:]

        i = int(i) - 1

        st.update(i, c)

    elif q[0] == '2':

        l, r = list(map(int, q[1:]))

        print((bin(st.query(l - 1, r)).count('1')))

# 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(eval(input()))

S = eval(input())



st = SegmentTree(N, or_)

st.build(conv(c) for c in S)



Q = int(eval(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 = list(map(int, q[1:]))

        print((bin(st.query(l - 1, r)).count('1')))

class SegmentTree:
    _data = []
    _offset = 0
    _size = 0

    def __init__(self, size):
        _size = size
        t = 1
        while t < size:
            t *= 2
        self._offset = t - 1
        self._data = [0 for _ in range(t * 2 - 1)]

    def update_all(self, iterable):
        self._data[self._offset : self._offset + self._size] = [
            1 << (ord(c) - ord("a")) for c in iterable
        ]
        for i in range(self._offset - 1, -1, -1):
            self._data[i] = self._data[i * 2 + 1] | self._data[i * 2 + 2]

    def update(self, index, value):
        i = self._offset + index
        self._data[i] = 1 << (ord(value) - ord("a"))
        while i >= 1:
            i = (i - 1) // 2
            self._data[i] = self._data[i * 2 + 1] | self._data[i * 2 + 2]

    def query(self, start, stop):
        result = 0
        l = start + self._offset
        r = stop + self._offset
        while l < r:
            if l & 1 == 0:
                result = result | self._data[l]
            if r & 1 == 0:
                result = result | self._data[r - 1]
            l = l // 2
            r = (r - 1) // 2
        return result


N = int(eval(input()))
S = eval(input())
st = SegmentTree(N)
st.update_all(S)
Q = int(eval(input()))
for _ in range(Q):
    q = input().split()
    if q[0] == "1":
        i, c = q[1:]
        i = int(i) - 1
        st.update(i, c)
    elif q[0] == "2":
        l, r = list(map(int, q[1:]))
        print((bin(st.query(l - 1, r)).count("1")))

# 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(eval(input()))
S = eval(input())
st = SegmentTree(N, or_)
st.build(conv(c) for c in S)
Q = int(eval(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 = list(map(int, q[1:]))
        print((bin(st.query(l - 1, r)).count("1")))

+# Segment tree (Bitwise Or) +from operator import or_ + + -    _data = [] -    _offset = 0 -    _size = 0 +    _f = None +    _data = None +    _offset = None +    _size = None -    def __init__(self, size): -        _size = size +    def __init__(self, size, f): +        self._f = f +        self._size = size -        self._data = [0 for _ in range(t * 2 - 1)] +        self._data = [0] * (t * 2 - 1) -    def update_all(self, iterable): -        self._data[self._offset : self._offset + self._size] = [ -            1 << (ord(c) - ord("a")) for c in iterable -        ] +    def build(self, iterable): +        f = self._f +        data = self._data +        data[self._offset : self._offset + self._size] = iterable -            self._data[i] = self._data[i * 2 + 1] | self._data[i * 2 + 2] +            data[i] = f(data[i * 2 + 1], data[i * 2 + 2]) +        f = self._f +        data = self._data -        self._data[i] = 1 << (ord(value) - ord("a")) +        data[i] = value -            self._data[i] = self._data[i * 2 + 1] | self._data[i * 2 + 2] +            data[i] = f(data[i * 2 + 1], data[i * 2 + 2]) -        result = 0 -        l = start + self._offset -        r = stop + self._offset -        while l < r: -            if l & 1 == 0: -                result = result | self._data[l] -            if r & 1 == 0: -                result = result | self._data[r - 1] -            l = l // 2 -            r = (r - 1) // 2 +        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) + + +def conv(c): +    return 1 << (ord(c) - ord("a")) -st = SegmentTree(N) -st.update_all(S) +st = SegmentTree(N, or_) +st.build(conv(c) for c in S) -        st.update(i, c) +        st.update(i, conv(c))