import sys
from io import StringIO
import unittest
import os


class SegTree:
    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


# 再帰処理上限(dfs作成時に設定するのが面倒なので限度近い値を組み込む)
sys.setrecursionlimit(999999999)


# 実装を行う関数
def resolve(test_def_name=""):
    def segfunc(x, y):
        return x + y

    n = int(input())
    s = input()
    q = int(input())
    query_s = [list(input().split()) for i in range(q)]

    alpha2int = lambda c: ord(c) - 97

    sumcun = [[0 for a in range(n)] for i in range(26)]
    # 数え上げ実施
    for cnt, char in enumerate(list(s)):
        sumcun[alpha2int(char)][cnt] = 1

    # 各アルファベットが区間内で何回利用されているか、を保持するセグメントツリーを作成
    seg_s = [SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) for i in range(26)]

    s_list = list(s)
    for query in query_s:
        if query[0] == "1":
            # 文字を変換
            target = int(query[1]) - 1  # 変換される文字の添え字
            # まず、変換される文字の利用回数。元々の値から-1減算
            target_tree = alpha2int(s_list[target])  # 操作するツリー
            seg_s[target_tree].update(target, 0)
            # 次に、変換後の文字の利用回数。元々の値に1を加算。
            target_tree = alpha2int(query[2])
            seg_s[target_tree].update(target, 1)
            # 文字列リストを置換しておく。(同じ位置の文字を再度書き換えるとき、s_list[添え字]で対象の文字を取得するため)
            s_list[target] = query[2]
        else:
            # 文字の種類を出力
            ans = 0
            # 各アルファベットに対して、以下の処理を実施。
            for i in range(26):
                # 先頭～対象範囲(from)の直前までに、文字が何個使用されているか取得。
                from_int = int(query[1])
                remove_cnt = 0
                if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                to_int = int(query[2])
                all_cnt = seg_s[i].query(0, to_int)
                if all_cnt - remove_cnt > 0:
                    ans += 1
            print(ans)


# テストクラス
class TestClass(unittest.TestCase):
    def assertIO(self, assert_input, output):
        stdout, sat_in = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(assert_input)
        resolve(sys._getframe().f_back.f_code.co_name)
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, sat_in
        self.assertEqual(out, output)

    def test_input_1(self):
        test_input = """7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7"""
        output = """3
1
5"""
        self.assertIO(test_input, output)

    def test_input_2(self):
        test_input = """4
abcd
4
2 1 4
2 1 1
1 1 b
2 1 2
"""
        output = """4
1
1"""
        self.assertIO(test_input, output)

    def test_input_3(self):
        test_input = """4
abab
10
2 1 1
2 1 2
2 1 3
2 1 4
2 2 2
2 2 3
2 2 4
2 3 3
2 3 4
2 4 4
"""
        output = """1
2
2
2
1
2
2
1
2
1"""
        self.assertIO(test_input, output)

    def test_input_5(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
16
1 25 e
1 32 m
1 36 f
1 38 r
1 40 w
1 40 e
1 46 o
1 49 l
1 53 e
1 57 t
1 58 j
1 64 z
1 70 a
1 73 t
1 74 j
2 27 78
"""
        output = """20"""
        self.assertIO(test_input, output)

    def test_input_6(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
21
1 73 t
1 53 e
1 7 t
1 70 a
1 38 r
1 15 p
1 57 t
1 58 j
1 74 j
1 8 x
1 46 o
1 25 e
1 40 w
1 49 l
1 36 f
1 15 w
1 32 m
1 1 k
1 40 e
1 64 z
2 9 19
"""
        output = """10"""
        self.assertIO(test_input, output)

    # 自作テストパターンのひな形(利用時は「tes_t」のアンダーバーを削除すること
    def tes_t_1original_1(self):
        test_input = """データ"""
        output = """データ"""
        self.assertIO(test_input, output)


# 実装orテストの呼び出し
if __name__ == "__main__":

    if os.environ.get("USERNAME") is None:
        # AtCoder提出時の場合
        resolve()

    else:
        # 自PCの場合
        unittest.main() import sys sys from io import StringIO import unittest unittest import os os class SegTree:
    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


# 再帰処理上限(dfs作成時に設定するのが面倒なので限度近い値を組み込む) SegTree def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

     __init__ n = len(init_val) n len(init_val) len init_val self.segfunc = segfunc self.segfunc self segfunc segfunc self.ide_ele = ide_ele self.ide_ele self ide_ele ide_ele self.num = 1 << (n - 1).bit_length() self.num self num 1 << (n - 1).bit_length() 1 (n - 1).bit_length() n - 1).bit_length n - 1 n 1 bit_length self.tree = [ide_ele] * 2 * self.num self.tree self tree [ide_ele] * 2 * self.num [ide_ele] * 2 [ide_ele] ide_ele 2 self.num self num for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
         i range(n) range n self.tree[self.num + i] = init_val[i] self.tree[self.num + i] self.tree self tree self.num + i self.num self num i init_val[i] init_val i for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

     i range(self.num - 1, 0, -1) range self.num - 1 self.num self num 1 0 -1 self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1]) self.tree[i] self.tree self tree i self.segfunc(self.tree[2 * i], self.tree[2 * i + 1]) self.segfunc self segfunc self.tree[2 * i] self.tree self tree 2 * i 2 i self.tree[2 * i + 1] self.tree self tree 2 * i + 1 2 * i 2 i 1 self self init_val init_val segfunc segfunc ide_ele ide_ele def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

     update """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """ k += self.num k self.num self num self.tree[k] = x self.tree[k] self.tree self tree k x while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

     k > 1 k 1 self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1]) self.tree[k >> 1] self.tree self tree k >> 1 k 1 self.segfunc(self.tree[k], self.tree[k ^ 1]) self.segfunc self segfunc self.tree[k] self.tree self tree k self.tree[k ^ 1] self.tree self tree k ^ 1 k 1 k >>= 1 k 1 self self k k x x def query(self, l, r):
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


# 再帰処理上限(dfs作成時に設定するのが面倒なので限度近い値を組み込む) query res = self.ide_ele res self.ide_ele self ide_ele l += self.num l self.num self num r += self.num r self.num self num while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
         l < r l r if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
             l & 1 l 1 res = self.segfunc(res, self.tree[l]) res self.segfunc(res, self.tree[l]) self.segfunc self segfunc res self.tree[l] self.tree self tree l l += 1 l 1 if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
             r & 1 r 1 res = self.segfunc(res, self.tree[r - 1]) res self.segfunc(res, self.tree[r - 1]) self.segfunc self segfunc res self.tree[r - 1] self.tree self tree r - 1 r 1 l >>= 1 l 1 r >>= 1 r 1 return res res self self l l r r sys.setrecursionlimit(999999999) sys.setrecursionlimit sys setrecursionlimit 999999999 def resolve(test_def_name=""):
    def segfunc(x, y):
        return x + y

    n = int(input())
    s = input()
    q = int(input())
    query_s = [list(input().split()) for i in range(q)]

    alpha2int = lambda c: ord(c) - 97

    sumcun = [[0 for a in range(n)] for i in range(26)]
    # 数え上げ実施
    for cnt, char in enumerate(list(s)):
        sumcun[alpha2int(char)][cnt] = 1

    # 各アルファベットが区間内で何回利用されているか、を保持するセグメントツリーを作成
    seg_s = [SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) for i in range(26)]

    s_list = list(s)
    for query in query_s:
        if query[0] == "1":
            # 文字を変換
            target = int(query[1]) - 1  # 変換される文字の添え字
            # まず、変換される文字の利用回数。元々の値から-1減算
            target_tree = alpha2int(s_list[target])  # 操作するツリー
            seg_s[target_tree].update(target, 0)
            # 次に、変換後の文字の利用回数。元々の値に1を加算。
            target_tree = alpha2int(query[2])
            seg_s[target_tree].update(target, 1)
            # 文字列リストを置換しておく。(同じ位置の文字を再度書き換えるとき、s_list[添え字]で対象の文字を取得するため)
            s_list[target] = query[2]
        else:
            # 文字の種類を出力
            ans = 0
            # 各アルファベットに対して、以下の処理を実施。
            for i in range(26):
                # 先頭～対象範囲(from)の直前までに、文字が何個使用されているか取得。
                from_int = int(query[1])
                remove_cnt = 0
                if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                to_int = int(query[2])
                all_cnt = seg_s[i].query(0, to_int)
                if all_cnt - remove_cnt > 0:
                    ans += 1
            print(ans)


# テストクラス resolve def segfunc(x, y):
        return x + y

     segfunc return x + y x + y x y x x y y n = int(input()) n int(input()) int input() input s = input() s input() input q = int(input()) q int(input()) int input() input list(input().split()) for i in range(q) for i in range(q) i range(q) range q for i in range(q) list(input().split()) list input().split() ().split () input split query_s = [list(input().split()) for i in range(q)] query_s [list(input().split()) for i in range(q)] alpha2int = lambda c: ord(c) - 97 alpha2int lambda c: ord(c) - 97 ord(c) - 97 ord(c) ord c 97 c [0 for a in range(n)] for i in range(26) for i in range(26) i range(26) range 26 for i in range(26) [0 for a in range(n)] sumcun = [[0 for a in range(n)] for i in range(26)] sumcun [[0 for a in range(n)] for i in range(26)] for cnt, char in enumerate(list(s)):
        sumcun[alpha2int(char)][cnt] = 1

    # 各アルファベットが区間内で何回利用されているか、を保持するセグメントツリーを作成
     cnt char enumerate(list(s)) enumerate list(s) list s sumcun[alpha2int(char)][cnt] = 1 sumcun[alpha2int(char)][cnt] [alpha2int(char)] sumcun alpha2int(char) alpha2int char cnt 1 SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) for i in range(26) for i in range(26) i range(26) range 26 for i in range(26) SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) SegTree sumcun[i] sumcun i segfunc=segfunc segfunc segfunc ide_ele=0 ide_ele 0 seg_s = [SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) for i in range(26)] seg_s [SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) for i in range(26)] s_list = list(s) s_list list(s) list s for query in query_s:
        if query[0] == "1":
            # 文字を変換
            target = int(query[1]) - 1  # 変換される文字の添え字
            # まず、変換される文字の利用回数。元々の値から-1減算
            target_tree = alpha2int(s_list[target])  # 操作するツリー
            seg_s[target_tree].update(target, 0)
            # 次に、変換後の文字の利用回数。元々の値に1を加算。
            target_tree = alpha2int(query[2])
            seg_s[target_tree].update(target, 1)
            # 文字列リストを置換しておく。(同じ位置の文字を再度書き換えるとき、s_list[添え字]で対象の文字を取得するため)
            s_list[target] = query[2]
        else:
            # 文字の種類を出力
            ans = 0
            # 各アルファベットに対して、以下の処理を実施。
            for i in range(26):
                # 先頭～対象範囲(from)の直前までに、文字が何個使用されているか取得。
                from_int = int(query[1])
                remove_cnt = 0
                if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                to_int = int(query[2])
                all_cnt = seg_s[i].query(0, to_int)
                if all_cnt - remove_cnt > 0:
                    ans += 1
            print(ans)


# テストクラス query query_s if query[0] == "1":
            # 文字を変換
            target = int(query[1]) - 1  # 変換される文字の添え字
            # まず、変換される文字の利用回数。元々の値から-1減算
            target_tree = alpha2int(s_list[target])  # 操作するツリー
            seg_s[target_tree].update(target, 0)
            # 次に、変換後の文字の利用回数。元々の値に1を加算。
            target_tree = alpha2int(query[2])
            seg_s[target_tree].update(target, 1)
            # 文字列リストを置換しておく。(同じ位置の文字を再度書き換えるとき、s_list[添え字]で対象の文字を取得するため)
            s_list[target] = query[2]
        else:
            # 文字の種類を出力
            ans = 0
            # 各アルファベットに対して、以下の処理を実施。
            for i in range(26):
                # 先頭～対象範囲(from)の直前までに、文字が何個使用されているか取得。
                from_int = int(query[1])
                remove_cnt = 0
                if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                to_int = int(query[2])
                all_cnt = seg_s[i].query(0, to_int)
                if all_cnt - remove_cnt > 0:
                    ans += 1
            print(ans)


# テストクラス query[0] == "1" query[0] query 0 "1" target = int(query[1]) - 1 target int(query[1]) - 1 int(query[1]) int query[1] query 1 1 target_tree = alpha2int(s_list[target]) target_tree alpha2int(s_list[target]) alpha2int s_list[target] s_list target seg_s[target_tree].update(target, 0) [target_tree].update [target_tree] seg_s target_tree update target 0 target_tree = alpha2int(query[2]) target_tree alpha2int(query[2]) alpha2int query[2] query 2 seg_s[target_tree].update(target, 1) [target_tree].update [target_tree] seg_s target_tree update target 1 s_list[target] = query[2] s_list[target] s_list target query[2] query 2 ans = 0 ans 0 for i in range(26):
                # 先頭～対象範囲(from)の直前までに、文字が何個使用されているか取得。
                from_int = int(query[1])
                remove_cnt = 0
                if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                to_int = int(query[2])
                all_cnt = seg_s[i].query(0, to_int)
                if all_cnt - remove_cnt > 0:
                    ans += 1
             i range(26) range 26 from_int = int(query[1]) from_int int(query[1]) int query[1] query 1 remove_cnt = 0 remove_cnt 0 if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                 from_int > 1 from_int 1 remove_cnt = seg_s[i].query(0, from_int - 1) remove_cnt seg_s[i].query(0, from_int - 1) [i].query [i] seg_s i query 0 from_int - 1 from_int 1 to_int = int(query[2]) to_int int(query[2]) int query[2] query 2 all_cnt = seg_s[i].query(0, to_int) all_cnt seg_s[i].query(0, to_int) [i].query [i] seg_s i query 0 to_int if all_cnt - remove_cnt > 0:
                    ans += 1
             all_cnt - remove_cnt > 0 all_cnt - remove_cnt all_cnt remove_cnt 0 ans += 1 ans 1 print(ans) print ans test_def_name="" test_def_name "" class TestClass(unittest.TestCase):
    def assertIO(self, assert_input, output):
        stdout, sat_in = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(assert_input)
        resolve(sys._getframe().f_back.f_code.co_name)
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, sat_in
        self.assertEqual(out, output)

    def test_input_1(self):
        test_input = """7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7"""
        output = """3
1
5"""
        self.assertIO(test_input, output)

    def test_input_2(self):
        test_input = """4
abcd
4
2 1 4
2 1 1
1 1 b
2 1 2
"""
        output = """4
1
1"""
        self.assertIO(test_input, output)

    def test_input_3(self):
        test_input = """4
abab
10
2 1 1
2 1 2
2 1 3
2 1 4
2 2 2
2 2 3
2 2 4
2 3 3
2 3 4
2 4 4
"""
        output = """1
2
2
2
1
2
2
1
2
1"""
        self.assertIO(test_input, output)

    def test_input_5(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
16
1 25 e
1 32 m
1 36 f
1 38 r
1 40 w
1 40 e
1 46 o
1 49 l
1 53 e
1 57 t
1 58 j
1 64 z
1 70 a
1 73 t
1 74 j
2 27 78
"""
        output = """20"""
        self.assertIO(test_input, output)

    def test_input_6(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
21
1 73 t
1 53 e
1 7 t
1 70 a
1 38 r
1 15 p
1 57 t
1 58 j
1 74 j
1 8 x
1 46 o
1 25 e
1 40 w
1 49 l
1 36 f
1 15 w
1 32 m
1 1 k
1 40 e
1 64 z
2 9 19
"""
        output = """10"""
        self.assertIO(test_input, output)

    # 自作テストパターンのひな形(利用時は「tes_t」のアンダーバーを削除すること
    def tes_t_1original_1(self):
        test_input = """データ"""
        output = """データ"""
        self.assertIO(test_input, output)


# 実装orテストの呼び出し TestClass def assertIO(self, assert_input, output):
        stdout, sat_in = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(assert_input)
        resolve(sys._getframe().f_back.f_code.co_name)
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, sat_in
        self.assertEqual(out, output)

     assertIO stdout, sat_in = sys.stdout, sys.stdin stdout sys.stdout sys stdout sat_in sys.stdin sys stdin sys.stdout, sys.stdin = StringIO(), StringIO(assert_input) sys.stdout sys stdout StringIO() StringIO sys.stdin sys stdin StringIO(assert_input) StringIO assert_input resolve(sys._getframe().f_back.f_code.co_name) resolve sys._getframe().f_back.f_code.co_name sys._getframe().f_back.f_code sys._getframe().f_back sys._getframe() sys._getframe sys _getframe f_back f_code co_name sys.stdout.seek(0) sys.stdout.seek sys.stdout sys stdout seek 0 out = sys.stdout.read()[:-1] out sys.stdout.read()[:-1] sys.stdout.read() sys.stdout.read sys.stdout sys stdout read :-1 -1 sys.stdout, sys.stdin = stdout, sat_in sys.stdout sys stdout stdout sys.stdin sys stdin sat_in self.assertEqual(out, output) self.assertEqual self assertEqual out output self self assert_input assert_input output output def test_input_1(self):
        test_input = """7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7"""
        output = """3
1
5"""
        self.assertIO(test_input, output)

     test_input_1 test_input = """7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7""" test_input """7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7""" output = """3
1
5""" output """3
1
5""" self.assertIO(test_input, output) self.assertIO self assertIO test_input output self self def test_input_2(self):
        test_input = """4
abcd
4
2 1 4
2 1 1
1 1 b
2 1 2
"""
        output = """4
1
1"""
        self.assertIO(test_input, output)

     test_input_2 test_input = """4
abcd
4
2 1 4
2 1 1
1 1 b
2 1 2
""" test_input """4
abcd
4
2 1 4
2 1 1
1 1 b
2 1 2
""" output = """4
1
1""" output """4
1
1""" self.assertIO(test_input, output) self.assertIO self assertIO test_input output self self def test_input_3(self):
        test_input = """4
abab
10
2 1 1
2 1 2
2 1 3
2 1 4
2 2 2
2 2 3
2 2 4
2 3 3
2 3 4
2 4 4
"""
        output = """1
2
2
2
1
2
2
1
2
1"""
        self.assertIO(test_input, output)

     test_input_3 test_input = """4
abab
10
2 1 1
2 1 2
2 1 3
2 1 4
2 2 2
2 2 3
2 2 4
2 3 3
2 3 4
2 4 4
""" test_input """4
abab
10
2 1 1
2 1 2
2 1 3
2 1 4
2 2 2
2 2 3
2 2 4
2 3 3
2 3 4
2 4 4
""" output = """1
2
2
2
1
2
2
1
2
1""" output """1
2
2
2
1
2
2
1
2
1""" self.assertIO(test_input, output) self.assertIO self assertIO test_input output self self def test_input_5(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
16
1 25 e
1 32 m
1 36 f
1 38 r
1 40 w
1 40 e
1 46 o
1 49 l
1 53 e
1 57 t
1 58 j
1 64 z
1 70 a
1 73 t
1 74 j
2 27 78
"""
        output = """20"""
        self.assertIO(test_input, output)

     test_input_5 test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
16
1 25 e
1 32 m
1 36 f
1 38 r
1 40 w
1 40 e
1 46 o
1 49 l
1 53 e
1 57 t
1 58 j
1 64 z
1 70 a
1 73 t
1 74 j
2 27 78
""" test_input """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
16
1 25 e
1 32 m
1 36 f
1 38 r
1 40 w
1 40 e
1 46 o
1 49 l
1 53 e
1 57 t
1 58 j
1 64 z
1 70 a
1 73 t
1 74 j
2 27 78
""" output = """20""" output """20""" self.assertIO(test_input, output) self.assertIO self assertIO test_input output self self def test_input_6(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
21
1 73 t
1 53 e
1 7 t
1 70 a
1 38 r
1 15 p
1 57 t
1 58 j
1 74 j
1 8 x
1 46 o
1 25 e
1 40 w
1 49 l
1 36 f
1 15 w
1 32 m
1 1 k
1 40 e
1 64 z
2 9 19
"""
        output = """10"""
        self.assertIO(test_input, output)

    # 自作テストパターンのひな形(利用時は「tes_t」のアンダーバーを削除すること
     test_input_6 test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
21
1 73 t
1 53 e
1 7 t
1 70 a
1 38 r
1 15 p
1 57 t
1 58 j
1 74 j
1 8 x
1 46 o
1 25 e
1 40 w
1 49 l
1 36 f
1 15 w
1 32 m
1 1 k
1 40 e
1 64 z
2 9 19
""" test_input """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
21
1 73 t
1 53 e
1 7 t
1 70 a
1 38 r
1 15 p
1 57 t
1 58 j
1 74 j
1 8 x
1 46 o
1 25 e
1 40 w
1 49 l
1 36 f
1 15 w
1 32 m
1 1 k
1 40 e
1 64 z
2 9 19
""" output = """10""" output """10""" self.assertIO(test_input, output) self.assertIO self assertIO test_input output self self def tes_t_1original_1(self):
        test_input = """データ"""
        output = """データ"""
        self.assertIO(test_input, output)


# 実装orテストの呼び出し tes_t_1original_1 test_input = """データ""" test_input """データ""" output = """データ""" output """データ""" self.assertIO(test_input, output) self.assertIO self assertIO test_input output self self unittest.TestCase unittest TestCase if __name__ == "__main__":

    if os.environ.get("USERNAME") is None:
        # AtCoder提出時の場合
        resolve()

    else:
        # 自PCの場合
        unittest.main() __name__ == "__main__" __name__ "__main__" if os.environ.get("USERNAME") is None:
        # AtCoder提出時の場合
        resolve()

    else:
        # 自PCの場合
        unittest.main() os.environ.get("USERNAME") is None os.environ.get("USERNAME") os.environ.get os.environ os environ get "USERNAME" None resolve() resolve unittest.main() unittest.main unittest main def resolve(test_def_name=""):
    def segfunc(x, y):
        return x + y

    n = int(input())
    s = input()
    q = int(input())
    query_s = [list(input().split()) for i in range(q)]

    alpha2int = lambda c: ord(c) - 97

    sumcun = [[0 for a in range(n)] for i in range(26)]
    # 数え上げ実施
    for cnt, char in enumerate(list(s)):
        sumcun[alpha2int(char)][cnt] = 1

    # 各アルファベットが区間内で何回利用されているか、を保持するセグメントツリーを作成
    seg_s = [SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) for i in range(26)]

    s_list = list(s)
    for query in query_s:
        if query[0] == "1":
            # 文字を変換
            target = int(query[1]) - 1  # 変換される文字の添え字
            # まず、変換される文字の利用回数。元々の値から-1減算
            target_tree = alpha2int(s_list[target])  # 操作するツリー
            seg_s[target_tree].update(target, 0)
            # 次に、変換後の文字の利用回数。元々の値に1を加算。
            target_tree = alpha2int(query[2])
            seg_s[target_tree].update(target, 1)
            # 文字列リストを置換しておく。(同じ位置の文字を再度書き換えるとき、s_list[添え字]で対象の文字を取得するため)
            s_list[target] = query[2]
        else:
            # 文字の種類を出力
            ans = 0
            # 各アルファベットに対して、以下の処理を実施。
            for i in range(26):
                # 先頭～対象範囲(from)の直前までに、文字が何個使用されているか取得。
                from_int = int(query[1])
                remove_cnt = 0
                if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                to_int = int(query[2])
                all_cnt = seg_s[i].query(0, to_int)
                if all_cnt - remove_cnt > 0:
                    ans += 1
            print(ans)


# テストクラス def resolve(test_def_name=""):
    def segfunc(x, y):
        return x + y

    n = int(input())
    s = input()
    q = int(input())
    query_s = [list(input().split()) for i in range(q)]

    alpha2int = lambda c: ord(c) - 97

    sumcun = [[0 for a in range(n)] for i in range(26)]
    # 数え上げ実施
    for cnt, char in enumerate(list(s)):
        sumcun[alpha2int(char)][cnt] = 1

    # 各アルファベットが区間内で何回利用されているか、を保持するセグメントツリーを作成
    seg_s = [SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) for i in range(26)]

    s_list = list(s)
    for query in query_s:
        if query[0] == "1":
            # 文字を変換
            target = int(query[1]) - 1  # 変換される文字の添え字
            # まず、変換される文字の利用回数。元々の値から-1減算
            target_tree = alpha2int(s_list[target])  # 操作するツリー
            seg_s[target_tree].update(target, 0)
            # 次に、変換後の文字の利用回数。元々の値に1を加算。
            target_tree = alpha2int(query[2])
            seg_s[target_tree].update(target, 1)
            # 文字列リストを置換しておく。(同じ位置の文字を再度書き換えるとき、s_list[添え字]で対象の文字を取得するため)
            s_list[target] = query[2]
        else:
            # 文字の種類を出力
            ans = 0
            # 各アルファベットに対して、以下の処理を実施。
            for i in range(26):
                # 先頭～対象範囲(from)の直前までに、文字が何個使用されているか取得。
                from_int = int(query[1])
                remove_cnt = 0
                if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                to_int = int(query[2])
                all_cnt = seg_s[i].query(0, to_int)
                if all_cnt - remove_cnt > 0:
                    ans += 1
            print(ans)


# テストクラス resolve class TestClass(unittest.TestCase):
    def assertIO(self, assert_input, output):
        stdout, sat_in = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(assert_input)
        resolve(sys._getframe().f_back.f_code.co_name)
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, sat_in
        self.assertEqual(out, output)

    def test_input_1(self):
        test_input = """7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7"""
        output = """3
1
5"""
        self.assertIO(test_input, output)

    def test_input_2(self):
        test_input = """4
abcd
4
2 1 4
2 1 1
1 1 b
2 1 2
"""
        output = """4
1
1"""
        self.assertIO(test_input, output)

    def test_input_3(self):
        test_input = """4
abab
10
2 1 1
2 1 2
2 1 3
2 1 4
2 2 2
2 2 3
2 2 4
2 3 3
2 3 4
2 4 4
"""
        output = """1
2
2
2
1
2
2
1
2
1"""
        self.assertIO(test_input, output)

    def test_input_5(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
16
1 25 e
1 32 m
1 36 f
1 38 r
1 40 w
1 40 e
1 46 o
1 49 l
1 53 e
1 57 t
1 58 j
1 64 z
1 70 a
1 73 t
1 74 j
2 27 78
"""
        output = """20"""
        self.assertIO(test_input, output)

    def test_input_6(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
21
1 73 t
1 53 e
1 7 t
1 70 a
1 38 r
1 15 p
1 57 t
1 58 j
1 74 j
1 8 x
1 46 o
1 25 e
1 40 w
1 49 l
1 36 f
1 15 w
1 32 m
1 1 k
1 40 e
1 64 z
2 9 19
"""
        output = """10"""
        self.assertIO(test_input, output)

    # 自作テストパターンのひな形(利用時は「tes_t」のアンダーバーを削除すること
    def tes_t_1original_1(self):
        test_input = """データ"""
        output = """データ"""
        self.assertIO(test_input, output)


# 実装orテストの呼び出し class TestClass(unittest.TestCase):
    def assertIO(self, assert_input, output):
        stdout, sat_in = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(assert_input)
        resolve(sys._getframe().f_back.f_code.co_name)
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, sat_in
        self.assertEqual(out, output)

    def test_input_1(self):
        test_input = """7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7"""
        output = """3
1
5"""
        self.assertIO(test_input, output)

    def test_input_2(self):
        test_input = """4
abcd
4
2 1 4
2 1 1
1 1 b
2 1 2
"""
        output = """4
1
1"""
        self.assertIO(test_input, output)

    def test_input_3(self):
        test_input = """4
abab
10
2 1 1
2 1 2
2 1 3
2 1 4
2 2 2
2 2 3
2 2 4
2 3 3
2 3 4
2 4 4
"""
        output = """1
2
2
2
1
2
2
1
2
1"""
        self.assertIO(test_input, output)

    def test_input_5(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
16
1 25 e
1 32 m
1 36 f
1 38 r
1 40 w
1 40 e
1 46 o
1 49 l
1 53 e
1 57 t
1 58 j
1 64 z
1 70 a
1 73 t
1 74 j
2 27 78
"""
        output = """20"""
        self.assertIO(test_input, output)

    def test_input_6(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
21
1 73 t
1 53 e
1 7 t
1 70 a
1 38 r
1 15 p
1 57 t
1 58 j
1 74 j
1 8 x
1 46 o
1 25 e
1 40 w
1 49 l
1 36 f
1 15 w
1 32 m
1 1 k
1 40 e
1 64 z
2 9 19
"""
        output = """10"""
        self.assertIO(test_input, output)

    # 自作テストパターンのひな形(利用時は「tes_t」のアンダーバーを削除すること
    def tes_t_1original_1(self):
        test_input = """データ"""
        output = """データ"""
        self.assertIO(test_input, output)


# 実装orテストの呼び出し TestClass class SegTree:
    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


# 再帰処理上限(dfs作成時に設定するのが面倒なので限度近い値を組み込む) class SegTree:
    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


# 再帰処理上限(dfs作成時に設定するのが面倒なので限度近い値を組み込む) SegTree
import sys
from io import StringIO
import unittest
import os


class SegTree:
    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


# 再帰処理上限(dfs作成時に設定するのが面倒なので限度近い値を組み込む)
sys.setrecursionlimit(999999999)


# 実装を行う関数
def resolve(test_def_name=""):
    def segfunc(x, y):
        return x + y

    n = int(input())
    s = input()
    q = int(input())
    query_s = [list(input().split()) for i in range(q)]

    alpha2int = lambda c: ord(c) - 97

    sumcun = [[0 for a in range(n)] for i in range(26)]
    # 数え上げ実施
    for cnt, char in enumerate(list(s)):
        sumcun[alpha2int(char)][cnt] = 1

    # 各アルファベットが区間内で何回利用されているか、を保持するセグメントツリーを作成
    seg_s = [SegTree(sumcun[i], segfunc=segfunc, ide_ele=0) for i in range(26)]

    s_list = list(s)
    for query in query_s:
        if query[0] == "1":
            # 文字を変換
            target = int(query[1]) - 1  # 変換される文字の添え字
            # まず、変換される文字の利用回数。元々の値から-1減算
            target_tree = alpha2int(s_list[target])  # 操作するツリー
            seg_s[target_tree].update(target, 0)
            # 次に、変換後の文字の利用回数。元々の値に1を加算。
            target_tree = alpha2int(query[2])
            seg_s[target_tree].update(target, 1)
            # 文字列リストを置換しておく。(同じ位置の文字を再度書き換えるとき、s_list[添え字]で対象の文字を取得するため)
            s_list[target] = query[2]
        else:
            # 文字の種類を出力
            ans = 0
            # 各アルファベットに対して、以下の処理を実施。
            for i in range(26):
                # 先頭～対象範囲(from)の直前までに、文字が何個使用されているか取得。
                from_int = int(query[1])
                remove_cnt = 0
                if from_int > 1:
                    remove_cnt = seg_s[i].query(0, from_int - 1)
                # 先頭～対象範囲(to)のまでに、文字が何個使用されているか取得。
                to_int = int(query[2])
                all_cnt = seg_s[i].query(0, to_int)
                if all_cnt - remove_cnt > 0:
                    ans += 1
            print(ans)


# テストクラス
class TestClass(unittest.TestCase):
    def assertIO(self, assert_input, output):
        stdout, sat_in = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(assert_input)
        resolve(sys._getframe().f_back.f_code.co_name)
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, sat_in
        self.assertEqual(out, output)

    def test_input_1(self):
        test_input = """7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7"""
        output = """3
1
5"""
        self.assertIO(test_input, output)

    def test_input_2(self):
        test_input = """4
abcd
4
2 1 4
2 1 1
1 1 b
2 1 2
"""
        output = """4
1
1"""
        self.assertIO(test_input, output)

    def test_input_3(self):
        test_input = """4
abab
10
2 1 1
2 1 2
2 1 3
2 1 4
2 2 2
2 2 3
2 2 4
2 3 3
2 3 4
2 4 4
"""
        output = """1
2
2
2
1
2
2
1
2
1"""
        self.assertIO(test_input, output)

    def test_input_5(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
16
1 25 e
1 32 m
1 36 f
1 38 r
1 40 w
1 40 e
1 46 o
1 49 l
1 53 e
1 57 t
1 58 j
1 64 z
1 70 a
1 73 t
1 74 j
2 27 78
"""
        output = """20"""
        self.assertIO(test_input, output)

    def test_input_6(self):
        test_input = """78
xcajtlueygwtjfreordfpsmyvirremdzhsfisulnbmmkxkdrrkwtjhsfmltkoieuxtwnvvozgcoabm
21
1 73 t
1 53 e
1 7 t
1 70 a
1 38 r
1 15 p
1 57 t
1 58 j
1 74 j
1 8 x
1 46 o
1 25 e
1 40 w
1 49 l
1 36 f
1 15 w
1 32 m
1 1 k
1 40 e
1 64 z
2 9 19
"""
        output = """10"""
        self.assertIO(test_input, output)

    # 自作テストパターンのひな形(利用時は「tes_t」のアンダーバーを削除すること
    def tes_t_1original_1(self):
        test_input = """データ"""
        output = """データ"""
        self.assertIO(test_input, output)


# 実装orテストの呼び出し
if __name__ == "__main__":

    if os.environ.get("USERNAME") is None:
        # AtCoder提出時の場合
        resolve()

    else:
        # 自PCの場合
        unittest.main()
