// Problem : D - Friend Suggestions
// Contest : AtCoder Beginner Contest 157
// URL : https://atcoder.jp/contests/abc157/tasks/abc157_d
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb emplace_back
#define int long long
#define vi vector<int>
#define pii pair<int,int>
#define m_p(x,y) make_pair(x,y)
#define vp vector<pair<int,int>>
#define setbits(x) __builtin_popcountll(x)
#define f first
#define se second
#define iniz(n) memset(n,0,sizeof(n))
#define inin(n) memset(n,-1,sizeof(n))
using namespace std;
using namespace __gnu_pbds;
template<typename T1,typename T2>istream &operator>>(istream &is, vector<pair<T1,T2>> &v) { for (pair<T1,T2> &t : v) is >> t.f>>t.se; return is; }
template<typename T>istream &operator>>(istream &is, vector<T> &v) { for (T &t : v) is >> t; return is; }
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v) { for (const T &t : v) {os << t <<" ";} os << '\n'; return os; }
double pi=acos(-1.0);
int md=1000000007;
int abst(int a)
{return a<0?-a:a;}
typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;
struct HASH{
  size_t operator()(const pii &x)const{
    return (size_t) x.first * 37U + (size_t) x.second;}};

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

int Pow(int n,int x){int ans=1;
 while(x>0)
 {if(x&1)ans=(ans*n)%md;n=(n*n)%md;x=x>>1;}
 return ans;}

 vi fact,inv;
void inverse(int n)
{inv.resize(n+1);inv[0]=1;
for(int i=1;i<=n;i++)inv[i]=Pow(fact[i],md-2);}
void factorial(int n)
{fact.resize(n+1);fact[0]=1;
for(int i=1;i<=n;i++)fact[i]=(fact[i-1]*i)%md;}

int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
void create(vector<vector<int>> &tree,int node,char aa[],int start,int end)
{
	// cerr<<node<<" "<<start<<" "<<end<<"\n";
    if(start==end){
    tree[node][aa[start]-'a']=1;}
    else
    {
        int mid=(start+end)/2;
        create(tree,2*node,aa,start,mid);
        create(tree,2*node+1,aa,mid+1,end);
        for(int i=0;i<26;i++)
        if(tree[2*node][i]==1 || tree[2*node+1][i]==1)
        tree[node][i]=1;
        else
        tree[node][i]=0;
    }
}
vi query(vector<vector<int>> &tree,int node, int start, int end, int l, int r)
{
    if(r < start or end < l)
      {
      	vi a(26);
      	return a;
      }
         if(l <= start and end <= r)
        return tree[node];
    int mid = (start + end) / 2;
    vi p1 = query(tree,2*node, start, mid, l, r);
    vi p2 = query(tree,2*node+1, mid+1, end, l, r);
    vi ans(26);
     for(int i=0;i<26;i++)
        if(p1[i]==1 || p2[i]==1)
        ans[i]=1;
    return ans;
}
void update(vector<vector<int>> &tree,int node,int start,int end,int index,char value)
{
    if(start==end){
    tree[node][value-'a']=1;
    int x=value-'a';
    for(int i=0;i<26;i++)
    if(tree[node][i]==1 && i!=x)
    tree[node][i]=0;
    }
    else
    {
        int mid=(start+end)/2;
        if(start<=index && index<=mid)
        update(tree,2*node,start,mid,index,value);
        else
        update(tree,2*node+1,mid+1,end,index,value);
        for(int i=0;i<26;i++)
        if(tree[2*node][i]==1 || tree[2*node+1][i]==1)
        tree[node][i]=1;
        else
        tree[node][i]=0;
    }
}
void solve()
{
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int n;cin>>n;
//string s;cin>>s;
char a1[n+1];
for(int i=1;i<=n;i++)
cin>>a1[i];
vector<vector<int>> tree(4*n+4,vector<int>(26));
//iniz(tree);
create(tree,1,a1,1,n);
//cerr<<n<<"\n";
int q;
cin>>q;
while(q--)
{
	
	int x;cin>>x;
	if(x==1)
	{
		int i;char c;
		cin>>i>>c;
		//cerr<<c<<"\n";
		update(tree,1,1,n,i,c);
	}
	else
	{
		int l,r;cin>>l>>r;
		vi ans=query(tree,1,1,n,l,r);
		//	cerr<<l<<" "<<r<<"\n";
		int count=0;
		for(int i=0;i<26;i++)
		if(ans[i]==1)
		count++;
		cout<<count<<"\n";
	}
}
}

int32_t main(){
ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
int t=1;
//cin>>t;
while(t--)
{
    solve();
}
}


Measured memory_bytes: 487168