#include <bits/stdc++.h>
        using namespace std;
        #define rep(i,a,b) for(ll i =a; i<b;++i)
        #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        #define endl "\n"
        #define pb push_back
        #define F first
        #define S second
        #define print(a)       for(auto x : a) cout << x << " "; cout << endl
        #define print1(a)      for(auto x : a) cout << x.F << " " << x.S << endl
        #define print2(a,x,y)  for(int i = x; i < y; i++) cout<< a[i]<< " "; cout << endl
        #define mk(x,y)  make_pair(x,y)
        typedef  long long  int ll;
        const int N = ( 1e6 + 5 );
        const int mod = 1e9+7;
        ll n,m;
        string s;
ll pow_mod_m(ll a , ll n)
{
    if(!n)
        return 1;
    ll pt =  pow_mod_m(a,n/2);
    pt *= pt ; pt %= mod;
    if(n&1)
        pt *= a , pt %= mod;
    return pt;
}

struct LCA
{
    vector <int> height , euler , first , segtree;
    vector <bool > visited;
    int n;
    LCA(vector <vector<int>> &adj , int root  = 0)
    {
        n = adj.size();
        height.resize(n);
        first.resize(n);
        euler.reserve(2*n);
        visited.assign(n,false);
        dfs(adj,root);
        int m = euler.size();
        segtree.resize(4*m);
        build(1 , 0 , m-1);
    }
    void dfs(vector < vector <int>> &adj , int node , int h = 0)
    {
        visited[node]  = 1;
        height[node]  =h;
        first[node] = euler.size();
        euler.pb(node);
        for(auto to : adj[node])
        {
            if(!visited[to]){
                 dfs(adj ,to , h+1);
                 euler.pb(node);
            }
        }
    }
    void build(int node ,int b ,int e)
    {
        if(b == e)
            segtree[node]  = euler[b];
        else
        {
            int m = (b+e)>>1;
            build(node <<1 ,b ,m);
            build(node <<1 | 1 , m+1 , e);
            int l  =segtree[node <<1] ,r = segtree[node <<1 | 1 ] ;
            segtree[node] = ( height[l] < height[r] ) ? l  : r;
        }
    }

int query(int node , int b , int e,int L ,int R)
{
    if( b > R  || e<L)
        return -1;
    if( b >= L and e <= R )
        return segtree[node];
    int mid = ( b + e ) >> 1;
    int left  = query(node <<1 , b , mid , L ,R);
    int right = query(node <<1 |1 , mid+1,e, L,R);
    if(left == -1) return right;
    if(right == -1) return left;
    return (height[left] < height[right]) ? left : right ;
}

int lca(int u,int v)
{
    int left = first[u] , right = first[v];
    if(left > right) swap(left,right);
    return query( 1 , 0 , euler.size() -1 ,left ,right) ;
}
};

ll f[4*N][26];

void add(ll pos, ll val, ll num)
{
    for ( ; pos < s.size() ; pos = (pos | (pos+1)))
    {
        f[pos][num] += val;
    }
}

ll query(ll pos,ll num)
{
    ll res = 0;
    for ( ; pos >=0 ; pos = (pos & (pos+1)) -1 )
    {
        res += f[pos][num];
    }
    return res;
}
ll distinct(ll l,ll r, ll num)
{
    return (query(r,num) - query(l-1, num));
}

int main()
{
     IOS;
 //    freopen("a_example (2).txt","r",stdin);
 //   freopen("c.txt","w",stdout);
    int ts =1;
  //  cin>>ts;
	while( ts-- )
    {
        cin>>n;
        cin>>s;
        cin>>m;
        rep( i , 0 , s.size() ) add(i , 1, s[i]-'a');
        rep(i,0,m)
        {
            ll x,l,r;
            char c;
            cin>>x;
            if(x == 1)
            {
                cin>> l >> c;
                l--;
                add(l , -1 , s[l] -'a');
                add(l ,1, c -'a');
                s[l] = c;
            }
            else
            {
                ll ans = 0 ;
                cin >> l>> r;l--,r--;
                rep(i,0,26){
                    if(distinct(l,r,i) >  0 )
                    {
                        ans ++;
                    }
                }
                cout << ans << endl;
            }
        }
    }
	return 0;
}


Measured memory_bytes: 103324