#include<bits/stdc++.h>
using namespace std;
const long long INF=0x3f3f3f3f3f3f3f3f;
const int MAXN=5e5+8;
const int MAXLYR=60;
struct SegTreeNode
{
int sum,lazy_update;
SegTreeNode operator+(const SegTreeNode& rhs) const {
return {sum+rhs.sum,-1};
}
};
struct SegmentTree
{
int sz=1,lb[MAXN<<1],rb[MAXN<<1],lc[MAXN<<1],rc[MAXN<<1];
SegTreeNode tr[MAXN<<1][MAXLYR];
inline void push_up(int u,int lyr) { tr[u][lyr]=tr[lc[u]][lyr]+tr[rc[u]][lyr]; }
inline void push_down(int u,int lyr)
{
if(tr[u][lyr].lazy_update==-1) return ;
int mid=(lb[u]+rb[u])>>1;
tr[lc[u]][lyr].sum=(mid-lb[u]+1)*tr[u][lyr].lazy_update;
tr[rc[u]][lyr].sum=(rb[u]-mid)*tr[u][lyr].lazy_update;
tr[lc[u]][lyr].lazy_update=tr[u][lyr].lazy_update;
tr[rc[u]][lyr].lazy_update=tr[u][lyr].lazy_update;
tr[u][lyr].lazy_update=-1;
}
void build(int u,int l,int r,long long vals[][MAXLYR])
{
lb[u]=l,rb[u]=r;
if(l==r)
{
for(int lyr=0;lyr<MAXLYR;lyr++) tr[u][lyr].sum=vals[l][lyr];
return ;
}
int mid=(l+r)>>1;
build(lc[u]=++sz,l,mid,vals),build(rc[u]=++sz,mid+1,r,vals);
for(int lyr=0;lyr<MAXLYR;lyr++) push_up(u,lyr);
}
void update(int u,int lyr,int l,int r,int val)
{
if(l>r||l>rb[u]||r<lb[u]) return ;
if(lb[u]>=l&&rb[u]<=r)
{
tr[u][lyr].sum=(rb[u]-lb[u]+1)*val;
tr[u][lyr].lazy_update=val;
return ;
}
push_down(u,lyr);
update(lc[u],lyr,l,r,val),update(rc[u],lyr,l,r,val);
push_up(u,lyr);
}
SegTreeNode query(int u,int lyr,int l,int r)
{
if(l>r||l>rb[u]||r<lb[u]) return {0,-1};
if(l<=lb[u]&&rb[u]<=r) return tr[u][lyr];
push_down(u,lyr);
return query(lc[u],lyr,l,r)+query(rc[u],lyr,l,r);
}
} segtr;
int n,m;
long long pos[MAXN][MAXLYR],cnt[MAXN];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
char ch;
for(int i=1;i<=n;i++) cin>>ch,pos[i][(ch>='A'&&ch<='Z' ? ch-'A'+1:ch-'a'+27)]=1;
segtr.build(1,1,n,pos);
while(m--)
{
int op,l,r;
cin>>op>>l>>r;
if(op==1) cin>>ch,cout<<segtr.query(1,(ch>='A'&&ch<='Z' ? ch-'A'+1:ch-'a'+27),l,r).sum<<"\n";
else if(op==2)
{
cin>>ch;
for(int i=1;i<=52;i++) segtr.update(1,i,l,r,0);
segtr.update(1,(ch>='A'&&ch<='Z' ? ch-'A'+1:ch-'a'+27),l,r,1);
}
else
{
for(int i=1;i<=52;i++)
{
cnt[i]=segtr.query(1,i,l,r).sum;
if(cnt[i]>0) segtr.update(1,i,l,r,0);
}
for(int i=1,pre=l;i<=52;i++)
{
if(cnt[i]>0) segtr.update(1,i,pre,pre+cnt[i]-1,1);
pre+=cnt[i];
}
}
}
return 0;
}