Problem:
Score : 500 points

Problem Statement

You are given a string S of length N consisting of lowercase English letters.

Process Q queries of the following two types:

Type 1: change the i_q-th character of S to c_q. (Do nothing if the i_q-th character is already c_q.)

Type 2: answer the number of different characters occurring in the substring of S between the l_q-th and r_q-th characters (inclusive).

Constraints

N, Q, i_q, l_q, and r_q are integers.

S is a string consisting of lowercase English letters.

c_q is a lowercase English letter.

1 \leq N \leq 500000

1 \leq Q \leq 20000

|S| = N

1 \leq i_q \leq N

1 \leq l_q \leq r_q \leq N

There is at least one query of type 2 in each testcase.

Input

Input is given from Standard Input in the following format:

N
S
Q
Query_1
\vdots
Query_Q

Here, Query_i in the 4-th through (Q+3)-th lines is one of the following:

1 i_q c_q

2 l_q r_q

Output

For each query of type 2, print a line containing the answer.

Sample Input 1

7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7

Sample Output 1

3
1
5

In the first query, cdbb contains three kinds of letters: b , c , and d, so we print 3.

In the second query, S is modified to abcdzbd.

In the third query, a contains one kind of letter: a, so we print 1.

In the fourth query, S is modified to abcazbd.

In the fifth query, S does not change and is still abcazbd.

In the sixth query, abcazbd contains five kinds of letters: a, b, c, d, and z, so we print 5.

Solution in Python (3.8.2) (judge verdict: Time Limit Exceeded)

class SegTree:

    def __init__(self, N):
        self.N = N
        self.data = [0 for _ in range(2 * N)]

    def update(self, i, x):
        index = self.N + i - 1
        self.data[index] = x
        while index > 0:
            index = (index - 1) // 2  # parent
            self.data[index] = max(self.data[2 * index + 1], self.data[2 * index + 2])

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return 0
        if a <= l and r <= b:
            return self.data[k]
        else:
            vl = self.query(a, b, 2 * k + 1, l, (l + r) // 2)
            vr = self.query(a, b, 2 * k + 2, (l + r) // 2, r)
            return max(vl, vr)


def main():
    N = int(input())
    pw2 = 1
    while pw2 < N:
        pw2 *= 2
    S = input()
    Q = int(input())
    query_list = [input().split(' ') for _ in range(Q)]
    trees = [None for _ in range(26)]
    for cn in range(26):
        trees[cn] = SegTree(pw2)
    for i, c in enumerate(S):
        cn = ord(c) - ord('a')
        trees[cn].update(i, 1)
    for query in query_list:
        if query[0] == '1':
            # type 1 query
            i = int(query[1]) - 1
            new_cn = ord(query[2]) - ord('a')
            for cn in range(26):
                x = (1 if cn == new_cn else 0)
                trees[cn].update(i, x)
        else:
            # type 2 query
            left = int(query[1]) - 1
            right = int(query[2]) - 1
            kinds = sum([trees[cn].query(left, right + 1, 0, 0, pw2) for cn in range(26)])
            print(kinds)


if __name__ == '__main__':
    main()