#include <bits/stdc++.h>
#define MAXN 100005
#define mod 1000000007
#define inf LLONG_MAX/3
using namespace std;

typedef long long ll; 
typedef pair<ll,ll> pll;

ll power(ll x,ll y,ll m=mod)
{
  ll ans = 1;
  while(y>0)
  {
    if(y&1)
    {
      ans = (ans*x)%m;
    }
    x = (x*x)%m;  
    y /= 2;
  }
  return ans%m;
}

ll modInverse(ll a, ll m=mod) 
{ 
    ll m0 = m; 
    ll y = 0, x = 1; 
  
    if (m == 1) 
      return 0; 
  
    while (a > 1) 
    { 
        // q is quotient 
        ll q = a / m; 
        ll t = m; 
  
        // m is remainder now, process same as 
        // Euclid's algo 
        m = a % m, a = t; 
        t = y; 
  
        // Update y and x 
        y = x - q * y; 
        x = t; 
    } 
  
    // Make x positive 
    if (x < 0) 
       x += m0; 
  
    return x; 
}

ll getMid(ll s, ll e)  
{ 
    return s + (e - s) / 2; 
} 

ll Util(ll* st, ll ss, ll se, ll l,  
            ll r, ll node) 
{ 
    if (l <= ss && r >= se) 
        return st[node]; 
  
    if (se < l || ss > r) 
        return 0; 
  
    ll mid = getMid(ss, se); 
      
    return (Util(st, ss, mid, l, r,  
                       2 * node + 1)+ 
               Util(st, mid + 1, se, l,  
                       r, 2 * node + 2)); 
} 
  
void updateValue(ll arr[], ll* st, ll ss, ll se,  
                 ll index, ll value, ll node) 
{ 
    if (index < ss || index > se)  
    { 
        return; 
    } 
      
    if (ss == se)  
    {    
        arr[index] = value; 
        st[node] = value; 
    } 
    else { 
            ll mid = getMid(ss, se); 
              
            if (index >= ss && index <= mid) 
                updateValue(arr, st, ss, mid, index,  
                            value, 2 * node + 1); 
            else
                updateValue(arr, st, mid + 1, se,  
                            index, value, 2 * node + 2); 
              
            st[node] = (st[2 * node + 1]+  
                       st[2 * node + 2]); 
    } 
    return; 
} 
  
ll get(ll* st, ll n, ll l, ll r) 
{ 
    if (l < 0 || r > n - 1 || l > r)  
    { 
        return 0; 
    } 
  
    return Util(st, 0, n - 1, l, r, 0); 
} 
  
ll constructSTUtil(ll arr[], ll ss, ll se,  
                    ll* st, ll si) 
{ 
    if (ss == se)  
    { 
        st[si] = arr[ss]; 
        return arr[ss]; 
    } 
  
    ll mid = getMid(ss, se); 
      
    st[si] = (constructSTUtil(arr, ss, mid, st,  
                                 si * 2 + 1)+ 
                 constructSTUtil(arr, mid + 1, se,  
                                 st, si * 2 + 2)); 
      
    return st[si]; 
} 
  
ll* constructST(ll arr[], ll n) 
{ 
    // Height of segment tree 
    ll x = (ll)(ceil(log2(n))); 
  
    // Maximum size of segment tree 
    ll max_size = 2 * (ll)pow(2, x) - 1; 
  
    // Allocate memory 
    ll* st = new ll[max_size]; 
  
    // Fill the allocated memory st 
    constructSTUtil(arr, 0, n - 1, st, 0); 
  
    // Return the constructed segment tree 
    return st; 
}

int main()
{
  /*#ifndef ONLINE_JUDGE 
  freopen("input.txt", "r", stdin); 
  #endif*/
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  ll t=1;
  // cin>>t;
  while(t--)
  {
    ll n,m,q,i,j,ans=0;
    string s;
    cin>>n>>s>>q;
    ll freq[26][n];
    memset(freq,0,sizeof(freq));
    for(i=0;i<n;i++)
    {
      freq[s[i]-'a'][i]=1;
    }
    ll *st[26];
    for(i=0;i<26;i++)
    {
      st[i] = constructST(freq[i],n);
    }
    while(q--)
    {
      ll ty;
      cin>>ty;
      if(ty == 1)
      {
        char c;
        cin>>i>>c;
        for(j=0;j<26;j++)
        {
          if(j==c-'a')
          {
            updateValue(freq[j],st[j],0,n-1,i-1,1,0);
          }
          else
          {
            updateValue(freq[j],st[j],0,n-1,i-1,0,0); 
          }
        }
      }
      else
      {
        ll c;
        cin>>i>>c;
        ans = 0;
        for(j=0;j<26;j++)
        {
          if(get(st[j],n,i-1,c-1))
            ans++;
        }
        cout<<ans<<"\n";
      }
    }
  }
  return 0;
}


Measured memory_bytes: 315548