#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<int, int> pi;
tree<int,int,greater<int>,rb_tree_tag,tree_order_statistics_node_update> map_t;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for(int i = 0; i < (a); ++i)
#define pb push_back
#define sz(x) (int)x.size()
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
#define REV(x) reverse(x.begin(),x.end())
int dx[]={-1,0,1,0};
int dy[]={0,-1,0,1};

class SegTree
{
    private:
        vector<vector<int>> t;
    public:
        void build(vector<int> &arr,int v,int tl,int tr)
        {
            t.assign(4*sz(arr)+1,vector<int>(26,0));
            build_helper(arr,v,tl,tr);
        }
        vector<int> plus(vector<int> first,vector<int> second)
        {
            vector<int> res(26);
            F0R(i,26)
                res[i]=first[i]+second[i];
            return res;
        }
        void build_helper(vector<int> &arr,int v,int tl,int tr)
        {
            if(tl==tr)
                t[v][arr[tl]]++;
            else
            {
                int mid=tl+(tr-tl)/2;
                build_helper(arr,2*v,tl,mid);
                build_helper(arr,2*v+1,mid+1,tr);
                t[v]=plus(t[2*v],t[2*v+1]);
            } 
        }
        vector<int> query(int v,int tl,int tr,int l,int r)
        {
            if(r<l)
            {
                vector<int> newV(26,0);
                return newV;
            }
            if(tl==l && tr==r)
                return t[v];
            int mid=tl+(tr-tl)/2;
            return plus(query(2*v,tl,mid,l,min(r,mid)),query(2*v+1,mid+1,tr,max(mid+1,l),r));
        }
        void update(int v,int tl,int tr,int pos,int new_val)
        {
            if(tl==tr)
            {
                t[v].clear();
                t[v].assign(26,0);
                t[v][new_val]++;
            }
            else
            {
                int mid=tl+(tr-tl)/2;
                if(pos<=mid)
                    update(2*v,tl,mid,pos,new_val);
                else
                    update(2*v+1,mid+1,tr,pos,new_val);
                t[v]=plus(t[2*v],t[2*v+1]);
            }
        }
};

int main()
{
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    int n,q;
    string s;
    cin >> n >> s >> q;
    vector<int> arr(n);
    F0R(i,n)
        arr[i]=s[i]-'a';
    SegTree inst;
    inst.build(arr,1,0,n-1);
    while(q--)
    {
        int a;
        cin >> a;
        if(a==1)
        {
            int b;
            char c;
            cin >> b >> c;
            b--;
            inst.update(1,0,n-1,b,c-'a');
        }
        else
        {
            int b,c;
            cin >> b >> c;
            b--; c--;
            vector<int> res=inst.query(1,0,n-1,b,c);
            int cnt=0;
            F0R(i,26)
            {
                if(res[i]>0)
                    cnt++;
            }
            cout << cnt << "\n";
        }
    }

    return 0;
}


Measured memory_bytes: 268444