/*
    Author:zeke
    
    pass System Test!
    GET AC!!
*/
#include <iostream>
#include <queue>
#include <vector>
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <algorithm>
#include <functional>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <map>
#include <iomanip>
#include <utility>
#include <stack>
#include <bitset>
using ll = long long;
using ld = long double;
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
#define rep3(var, min, max) for (ll(var) = (min); (var) < (max); ++(var))
#define repi3(var, min, max) for (ll(var) = (max)-1; (var) + 1 > (min); --(var))
#define Mp(a, b) make_pair((a), (b))
#define F first
#define S second
#define int ll
#define Icin(s) \
    ll(s);      \
    cin >> (s);
#define Scin(s) \
    ll(s);      \
    cin >> (s);
template <class T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b)
{
    if (b < a)
    {
        a = b;
        return 1;
    }
    return 0;
}
typedef pair<ll, ll> P;
typedef vector<ll> V;
typedef vector<V> VV;
typedef vector<P> VP;
//ll mod = 1e9+7;
//ll MOD = 1e9 + 7;
ll INF = 1e18;
VV value; // ノードの値を持つ配列
ll Size;             // 葉の数

void update(ll moji,ll i,ll dis)
{
    // i 番目の葉の値を x に変える
    i += Size - 1; // i 番目の葉のノード番号
    value[moji][i]+=dis;
    while (i > 0)
    {
        i = (i - 1) / 2; // ノード i の親ノードの番号に変える
        value[moji][i] += dis;
    }
}

int query(ll moji,int a, int b, int k, int l, int r)
{
    // [a, b) の区間に対するクエリについて
    // ノード k （区間 [l, r) 担当）が答える
    if (r <= a || b <= l)
        return 0; // 区間が被らない場合は INF を返す
    if (a <= l && r <= b)
        return value[moji][k]; // ノード k の担当範囲がクエリ区間 [a, b)
                         // に完全に含まれる
    else
    {
        int c1 = query(moji,a, b, 2 * k + 1, l, (l + r) / 2); // 左の子に値を聞く
        int c2 = query(moji,a, b, 2 * k + 2, (l + r) / 2, r); // 右の子に値を聞く
        return c1+c2;                              // 左右の子の値の min を取る
    }
}
int n, q;
void test(){
    rep(i,n){
        rep(j,26){
            if(query(j,i,i+1,0,0,Size)){
                cout<<(char)(j+'a');
            }
            
        }
        //cout<<endl;
    }
    cout<<endl;
}
signed main(void)
{
    
    cin >> n;
    string s;
    cin>>s;
    Size = 1;
    while (Size < n){
        Size *= 2; // 葉の数を計算（n以上の最小の2冪数）
    }
    VV temp(26,V(Size*2-1,0));
    value=temp;
    rep(i,n){
        char c=s[i];
        ll moji=c-'a';
        update(moji,i,1);
    }
    
    cin>>q;
    rep(i,q){
        int type;
        cin>>type;
        if(type==1){
            ll x;
            char c;
            cin>>x;
            cin>>c;
            x--;
          //  char changec=;
            ll moji=c-'a';
            ll cmoji;
            rep(j,26){
                if(query(j,x,x+1,0,0,Size)){
                    cmoji=j;
                }
            }
            update(moji,x,1);
            update(cmoji,x,-1);
        }else{
          //  test();
            ll x,y;
            cin>>x>>y;
            x--;y--;
            ll sum=0;
            rep(i,26){
                if(query(i,x,y+1,0,0,Size)){
                    sum++;
                }
            }
            cout<<sum<<endl;
        }
    }
}


Measured memory_bytes: 427008