import bisect



N = int(eval(input()))

S = eval(input())

Q = int(eval(input()))

alphabet_dic = {}

alphabet_array = []

for i,s in enumerate(S):

    alphabet_array.append(s)

    if s in alphabet_dic:

        alphabet_dic[s].append(i)

    else:

        alphabet_dic[s] = [i]

# print(alphabet_dic)



for _ in range(Q):

    a, b, c = list(map(str,input().split()))

    if int(a) == 1:

        b = int(b)

        now_str = alphabet_array[b-1]

        if now_str != c:

            alphabet_array[b-1] = c

            alphabet_dic[now_str].remove(b-1)

            if c in alphabet_dic:

                bisect.insort_left(alphabet_dic[c],b-1)

            else:

                alphabet_dic[c] = [b-1]

    else:

        ans = 0

        b = int(b)

        c = int(c)

        for index_array in list(alphabet_dic.values()):

            if not len(index_array) or index_array[-1] < b-1:

                continue

            i = bisect.bisect_left(index_array,b-1)

            if index_array[i] <= c-1:

                ans += 1

        print(ans)

class SegmentTree(object):  # 1-indexed

    def __init__(self, size, S):

        self.len = 1 << size.bit_length()



        self.array = [0] * (2 * self.len)

        for i, s in enumerate(S):

            self.array[i + self.len] = 1 << (ord(s) - ord('a'))

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

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



    def query1(self, i, x):

        i += self.len

        self.array[i] = 1 << (ord(x) - ord('a'))

        i >>= 1

        while i > 0:

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

            i >>= 1



    def get(self, i):

        return self.array[i + self.len]



    def query(self, l, r, i, a, b):

        if l == a and r == b:

            return self.array[i]

        center = (a + b) // 2

        if center >= r:

            return self.query(l, r, i * 2, a, center)

        elif center <= l:

            return self.query(l, r, i * 2 + 1, center, b)

        else:

            return self.query(l, center, i * 2, a, center) | self.query(center, r, i * 2 + 1, center, b)



    def query2(self, l, r):

        ans = self.query(l - 1, r, 1, 0, self.len)

        print((bin(ans).count('1')))





N = int(eval(input()))

S = eval(input())

tree = SegmentTree(N, S)

Q = int(eval(input()))



for _ in range(Q):

    a, b, c = list(map(str, input().split()))

    if a == "1":

        b = int(b)

        tree.query1(b-1, c)

    else:

        b = int(b)

        c = int(c)

        tree.query2(b, c)

import bisect

N = int(eval(input()))
S = eval(input())
Q = int(eval(input()))
alphabet_dic = {}
alphabet_array = []
for i, s in enumerate(S):
    alphabet_array.append(s)
    if s in alphabet_dic:
        alphabet_dic[s].append(i)
    else:
        alphabet_dic[s] = [i]
# print(alphabet_dic)
for _ in range(Q):
    a, b, c = list(map(str, input().split()))
    if int(a) == 1:
        b = int(b)
        now_str = alphabet_array[b - 1]
        if now_str != c:
            alphabet_array[b - 1] = c
            alphabet_dic[now_str].remove(b - 1)
            if c in alphabet_dic:
                bisect.insort_left(alphabet_dic[c], b - 1)
            else:
                alphabet_dic[c] = [b - 1]
    else:
        ans = 0
        b = int(b)
        c = int(c)
        for index_array in list(alphabet_dic.values()):
            if not len(index_array) or index_array[-1] < b - 1:
                continue
            i = bisect.bisect_left(index_array, b - 1)
            if index_array[i] <= c - 1:
                ans += 1
        print(ans)

class SegmentTree(object):  # 1-indexed
    def __init__(self, size, S):
        self.len = 1 << size.bit_length()
        self.array = [0] * (2 * self.len)
        for i, s in enumerate(S):
            self.array[i + self.len] = 1 << (ord(s) - ord("a"))
        for i in range(self.len - 1, 0, -1):
            self.array[i] = self.array[i * 2] | self.array[i * 2 + 1]

    def query1(self, i, x):
        i += self.len
        self.array[i] = 1 << (ord(x) - ord("a"))
        i >>= 1
        while i > 0:
            self.array[i] = self.array[i * 2] | self.array[i * 2 + 1]
            i >>= 1

    def get(self, i):
        return self.array[i + self.len]

    def query(self, l, r, i, a, b):
        if l == a and r == b:
            return self.array[i]
        center = (a + b) // 2
        if center >= r:
            return self.query(l, r, i * 2, a, center)
        elif center <= l:
            return self.query(l, r, i * 2 + 1, center, b)
        else:
            return self.query(l, center, i * 2, a, center) | self.query(
                center, r, i * 2 + 1, center, b
            )

    def query2(self, l, r):
        ans = self.query(l - 1, r, 1, 0, self.len)
        print((bin(ans).count("1")))


N = int(eval(input()))
S = eval(input())
tree = SegmentTree(N, S)
Q = int(eval(input()))
for _ in range(Q):
    a, b, c = list(map(str, input().split()))
    if a == "1":
        b = int(b)
        tree.query1(b - 1, c)
    else:
        b = int(b)
        c = int(c)
        tree.query2(b, c)

-import bisect +class SegmentTree(object):  # 1-indexed +    def __init__(self, size, S): +        self.len = 1 << size.bit_length() +        self.array = [0] * (2 * self.len) +        for i, s in enumerate(S): +            self.array[i + self.len] = 1 << (ord(s) - ord("a")) +        for i in range(self.len - 1, 0, -1): +            self.array[i] = self.array[i * 2] | self.array[i * 2 + 1] + +    def query1(self, i, x): +        i += self.len +        self.array[i] = 1 << (ord(x) - ord("a")) +        i >>= 1 +        while i > 0: +            self.array[i] = self.array[i * 2] | self.array[i * 2 + 1] +            i >>= 1 + +    def get(self, i): +        return self.array[i + self.len] + +    def query(self, l, r, i, a, b): +        if l == a and r == b: +            return self.array[i] +        center = (a + b) // 2 +        if center >= r: +            return self.query(l, r, i * 2, a, center) +        elif center <= l: +            return self.query(l, r, i * 2 + 1, center, b) +        else: +            return self.query(l, center, i * 2, a, center) | self.query( +                center, r, i * 2 + 1, center, b +            ) + +    def query2(self, l, r): +        ans = self.query(l - 1, r, 1, 0, self.len) +        print((bin(ans).count("1"))) + +tree = SegmentTree(N, S) -alphabet_dic = {} -alphabet_array = [] -for i, s in enumerate(S): -    alphabet_array.append(s) -    if s in alphabet_dic: -        alphabet_dic[s].append(i) -    else: -        alphabet_dic[s] = [i] -# print(alphabet_dic) -    if int(a) == 1: +    if a == "1": -        now_str = alphabet_array[b - 1] -        if now_str != c: -            alphabet_array[b - 1] = c -            alphabet_dic[now_str].remove(b - 1) -            if c in alphabet_dic: -                bisect.insort_left(alphabet_dic[c], b - 1) -            else: -                alphabet_dic[c] = [b - 1] +        tree.query1(b - 1, c) -        ans = 0 -        for index_array in list(alphabet_dic.values()): -            if not len(index_array) or index_array[-1] < b - 1: -                continue -            i = bisect.bisect_left(index_array, b - 1) -            if index_array[i] <= c - 1: -                ans += 1 -        print(ans) +        tree.query2(b, c)