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: Accepted)

#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;

const ll mod = 1e9 + 7;
const ll MAXN = 5e5 + 5;

vector < vector < ll > > t(4 * MAXN, vector < ll > (26, 0));
ll n;
string s;

void build(ll v, ll tl, ll tr){
  if(tl == tr){
    t[v][s[tl] - 'a']++;
  }else{
    ll tm = (tr - tl) / 2 + tl;
    build(2 * v, tl, tm);
    build(2 * v + 1, tm + 1, tr);
    for(int i = 0; i < 26; i++) t[v][i] = t[2 * v][i] + t[2 * v + 1][i];
  }
}

void update(ll v, ll tl, ll tr, ll pos, char ch){
  if(tl == tr){
    t[v][s[tl] - 'a']--;
    t[v][ch - 'a']++;
  }else{
    ll tm = (tr - tl) / 2 + tl;
    if(pos <= tm) update(2 * v, tl, tm, pos, ch);
    else update(2 * v + 1, tm + 1, tr, pos, ch);
    for(int i = 0; i < 26; i++) t[v][i] = t[2 * v][i] + t[2 * v + 1][i];
  }
}

vector < ll > query(ll v, ll tl, ll tr, ll l, ll r){
  if(l > r){
    vector < ll > tmp(26, 0);
    return tmp;
  }
  if(tl == l && tr == r){
    return t[v];
  }else{
    ll tm = (tr - tl) / 2 + tl;
    vector < ll > a = query(2 * v, tl, tm, l, min(r, tm));
    vector < ll > b = query(2 * v + 1, tm + 1, tr, max(l, tm + 1), r);
    for(int i = 0; i < 26; i++) a[i] += b[i];
    return a;
  }
}

int main(){
  ios_base::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);

  cin >> n;
  cin >> s;

  build(1, 0, n - 1);

  ll q;
  cin >> q;
  while(q--){
    int a;
    cin >> a;
    if(a == 1){
      ll pos;
      cin >> pos;
      char ch;
      cin >> ch;
      update(1, 0, n - 1, pos - 1, ch);
      s[pos - 1] = ch;
    }else{
      ll l, r;
      cin >> l >> r;
      vector < ll > ans = query(1, 0, n - 1, l - 1, r - 1);
      ll cnt = 0;
      for(int i = 0; i < 26; i++){
        if(ans[i]) cnt++;
      }
      cout << cnt << '\n';
    }
  }
}