#include<bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007;
#define fil(x) memset(x, 0, sizeof(x))
#define fillb(x) memset(x,false,sizeof(x))
#define fillm(x) memset(x, -1, sizeof(x))
#define mp make_pair
#define pll pair<int, int>
#define pf printf
#define sf scanf
#define all(x) x.begin(),x.end()
#define pb push_back
#define IOS ios::sync_with_stdio(false); cin.tie(0);
#define np std::string::npos
#define fo(i,n) for(int i=0;i<n;i++)
#define of(i,n) for(int i=n-1;i>=0;i--)
#define highest(x) numeric_limits<x>::max()
#define lowest(x) numeric_limits<x>::min()
#define Inf INFINITY
#define minv(v) *min_element(v.begin(),v.end())
#define maxv(v) *max_element(v.begin(),v.end())
#define cases(cs,t) for(int cs=1;cs<=t;cs++)
#define PI acos(-1)
#define nl endl

typedef unsigned long long lll;
typedef long long ll;
int knigtx8[] = {2, 2, -2, -2, 1, 1, -1, -1}; ///knight move in chess
int knigty8[] = {1, -1, 1, -1, 2, -2, 2, -2}; ///knight move in chess
int dx8[] = {0, 0, 1, 1, 1, -1, -1, -1}; ///for 8 directions
int dy8[] = {1,-1, 1, -1, 0, 0, -1, 1}; ///for 8 directions
int dx4[] = {0, 0, 1, -1}; ///for 4 directions
int dy4[] = {1, -1, 0, 0}; ///for 4 directions
const int maxx=100005;

//this fuction sorts vector pair according to first element in descending order.
bool sortinrev(const pair<int,int> &a,const pair<int,int> &b)
{
    return a.first>b.first;
}

int atoz(){
    int frnt,bck,nibo,present,i;string s;
        frnt = abs(s[i]-present);
        bck = 26-frnt;
        nibo = min(frnt,bck);
}

template<typename T>inline T Bigmod(T base, T power, T MOD){
    T ret=1;
    while(power)
    {
        if(power & 1)ret=(ret*base)%MOD;
        base=(base*base)%MOD;
        power>>=1;
    }
    return ret;
}

const int N = 10000005;
int tree[N][30];
set<char>st;
string s;
int n;
void build(int b, int e, int node)
{
    if(b==e){
        tree[node][s[b]-'a'] = 1;
    }
    else
    {
        int mid = (b+e)/2;
        int left = 2*node+1;
        int right = 2*node +2;
        build(b,mid,left);
        build(mid+1,e,right);
        fo(i,26)
        {
            tree[node][i] = (tree[left][i]) | (tree[right][i]);
        }
    }
}

void update(int b, int e, int node, int in, char ch)
{
    if(b==e and in==e)
    {
        tree[node][s[in]-'a'] = 0;
        tree[node][ch-'a'] = 1;
        s[in] = ch;
    }
    else
    {
        int mid = (b+e)/2;
        int left = 2*node+1;
        int right = 2*node +2;
        if(b<=in and in<=mid)
        {
            update( b, mid, left, in, ch);
        }
        else{
            update( mid+1, e, right, in, ch);
        }
        fo(i,26){
            tree[node][i] = tree[left][i]|tree[right][i];
        }
    }

}

void query(int l, int r, int b, int e, int node)
{
    if(b>e) return;
    if(l<=b and e<=r)
    {
        fo(i,26)
        {
            if(tree[node][i]) st.insert((char)(i+'a'));
        }
        return;
    }
    if(l>e or r<b) return;
    int mid = (b+e)/2;
    int left = 2*node+1;
    int right = 2*node +2;
    query(l,r,b,mid,left);
    query(l,r,mid+1,e,right);
}

int main()
{
    IOS;
    cin>>n;
    cin>>s;
    build(0,n-1,0);
    int t;
    cin>>t;
    while(t--)
    {
        int x;
        cin>>x;
        if(x==1){
            int in;
            char c;
            cin>>in>>c;
            in--;
            update(0,n-1,0,in,c);
        }
        else if(x==2)
        {
            int l,r;
            cin>>l>>r;
            l--; r--;
            query(l,r,0,n-1,0);
            cout<<(int)st.size()<<endl;
            st.clear();
        }

    }
    return 0;
}


Measured memory_bytes: 125852