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 C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <iostream>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
#include <string.h>

using namespace std;

// #define for(i,a,b) for (int i=(a);i<(b);++i)
typedef long long ll;
typedef pair<ll,ll> P;
#define REP(i,n) for(long long i = 0; i < (long long)(n); i++)
#define pb push_back // vectorに要素追加
#define INF (ll)1e18

ll mod = 1e9+7;
string alphabet = "abcdefghijklmnopqrstuwvyz";
ll get_alphabet_index(char c){
	ll ans = -1;
	REP(i,alphabet.size()){
		if (c==alphabet[i]){
			ans = i;
			break;
		}
	}
	return ans;
}

// 検索タグ
int main() {
	// 入力
	ll N;cin>>N;
	string S;cin>>S;
	ll S_list[N];
	// set: 重複なしの集合
	set<ll> S_set[alphabet.size()]; // アルファベットごとにsetを用意
	REP(i,N){
		ll index = get_alphabet_index(S[i]);
		S_list[i] = index;
		S_set[index].insert(i); // O(logN)
	}


	ll Q;cin>>Q;
	// printf("%s\n", S.c_str()); // stringをprint
	// REP(i,N)printf("%lld ", S_list[i]);
	// printf("\n");

	// 解法
	REP(i,Q){
		ll type;cin>>type;
		if (type==1){ // 入れ替え処理
			ll i_tmp;cin>>i_tmp;i_tmp--; // 差し替えるのが何文字目か
			char c_tmp;cin>>c_tmp;
			ll index_before = S_list[i_tmp]; // 差し替え前の文字のアルファベット番号
			ll index_after = get_alphabet_index(c_tmp); // 差し替え後の文字のアルファベット番号
			S_list[i_tmp] = index_after;
			// S_set[index_before].erase(i_tmp); //  O(logN)
			// S_set[index_after].insert(i_tmp); //  O(logN)
			// REP(j,abc.size()){
			// 	if (S_tmp.substr(i_tmp,1)==abc.substr(j,1)){
			// 		S[i] = j;
			// 		S_set[j].insert(i);
			// 	}
			// printf("type: 1, ");
			// REP(j,N)printf("%lld ", S_list[j]);
			// printf("\n");

		}
		if (type==2){ // 入れ替え処理
			ll l_tmp, r_tmp;cin>>l_tmp>>r_tmp;l_tmp--;r_tmp--;
			// printf("type: 2, substr: ");
			// REP(j,r_tmp-l_tmp+1){
			// 	printf("%c", alphabet[S_list[l_tmp+j]]);
			// }
			// printf("\n");
			ll ans = 0;
			REP(j, alphabet.size()){
				// lower_bount(x): x以上の要素のうち最も小さい要素のイテレータを返す。
				// 存在しない場合最後のイテレータを返す
				// if (S_set[j].size()==0)continue; // 一文字もないアルファベットはパス
				// auto itr_lower = S_set[j].lower_bound(l_tmp); // lから左にある最初index
				// printf("%s, %lld<=%lld- %lld<=%lld\n", alphabet.substr(j,1).c_str(), l_tmp, *itr_lower, *itr_upper, r_tmp);
				// if (*itr_lower==S_set[j].size()-1 & *itr_lower<l_tmp)continue;
				// if (*itr_lower<=r_tmp) ans++;
				
				// cout<<S_set[j].lower_bound(1)<<endl;
			}
			printf("%lld\n", ans);
		// 	REP(j,abc.size()){
		// 		if (S_tmp.substr(i_tmp,1)==abc.substr(j,1)){
		// 			S[i] = j;
		// 			S_set[j].insert(i);
		// 		}

		}
	}

	//出力
}