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)

/*
 
@author
_      _          _                 _      _
\\    // /\    | | \  |     |    /\ \\    //     
 \\  // /__\   | |_/  |_____|   /__\ \\  //
  \\// /    \  | | \  |     |  /    \ \\//
   \/ /      \ | |_/  |     | /      \ \/
@ Indian Institute of Technology Bhilai
*/
 
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
#define fr(i,start,end, inc) for(ll i=(start); i<(end); i+=inc)
#define rf(i,end,start, inc) for(ll i=(start-1); i>=(end); i-=inc)
#define rep(i,n) for(ll i=0; i<n; i++)
#define rep1(i,n) for(ll i=1; i<=n; i++)
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define mp make_pair
#define pl pair<ll, ll>
#define pi pair<int,int>
#define fi first
#define se second
#define all(v) v.begin(), v.end()
#define alla(arr,n) arr, arr+n
#define fsync ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
const ll maxx =  1e9+7;

bool compare(const pl &a, const pl &b){
    return a.fi<b.fi || (a.fi==b.fi && a.se<b.se);
}
ll inline power(ll a, ll b, ll p){
    a %= p;
    ll ans = 1;
    while(b>0){
        if(b & 1)
            ans = (ans*a)%p;
        a = (a*a)%p;
        b >>= 1;
    }
    return ans;
}

ll inv(ll n, ll p){
    return power(n,p-2, p);
}
inline vector<ll> allinv(ll n, ll p){
    vector<ll> arr(n);
    arr[1]=1;
    fr(i,2,n,1){
        arr[i] = (p - (p/i)*arr[p%i]%p)%p;
    }
    return arr;
}
vector<ll> inline allncr(ll n, ll p){
    vector<ll> nci(n+1);
    nci[0]=1;
    nci[n]=1;
    vector<ll> v = allinv(n,p);
    fr(i,1,n,1){
        nci[i]=(nci[i-1]*(n-i-1))%p;
    }
    return nci;
}
ll max3(ll a, ll b, ll c){
    return max(max(a,b),c);
}

bool inline isPrime(ll n) { 
    if (n <= 1)  return false; 
    if (n <= 3)  return true; 
    if (n%2 == 0 || n%3 == 0) return false; 
    for (ll i=5; i*i<=n; i=i+6) 
        if (n%i == 0 || n%(i+2) == 0) 
           return false; 
    return true; 
}

void prt(int i){   
    i ? cout << "YES\n" : cout << "NO\n" ;
}

template<class T>
void printv(T &v){
    ll n = v.size();
    rep(i,n)
        cout << v[i] << " ";
    cout << "\n";
}
const ll maxn = 500002;
ll f[26][maxn];

//------------dsu-------------
// ll find_parent(ll u){
//     if(parent[u]==-1)
//         return u;
//     return parent[u] = find_parent(parent[u]);
// }

// void merge(ll u, ll v){
//     u = find_parent(u);
//     v = find_parent(v);
//     if(v==u)
//         return;
//     parent[v]=u;
//     tot[u]+=tot[v];
// }

void fenwick_update(ll idx, ll val, ll ch){
    while(idx <= maxn){
        f[ch][idx]+=val;
        idx += (idx & -idx);
    }
}
ll read_fenwick(ll idx, ll ch){
    ll sum = 0;
    while(idx > 0){
        sum += f[ch][idx];
        idx -= (idx & -idx);
    }
    return sum;
}

int main(){
    fsync
    ll test=1;
    // cin >> test;
    while(test--){
        rep(i,26){
            rep(j,maxn)
                f[i][j]=0;
        }
        ll n,q,a,b,d,ans=0;
        char c;
        cin >> n;
        string s;
        cin >> s;
        cin >> q;
        rep(i,n)
            fenwick_update(i+1, 1, s[i]-'a');
        rep(i,q){
            cin >> a >> b;
            if(a==1){
                cin >> c;
                if(s[b-1] == c)
                    continue;
                fenwick_update(b,-1,s[b-1]-'a');
                s[b-1]=c;
                fenwick_update(b,1,c-'a');
                continue;
            }
            cin >> d;
            ans=0;
            rep(e,26){
                if(read_fenwick(d,e)-read_fenwick(b-1, e))
                    ans++;
            }
            cout << ans << "\n";
        }
    }

}