#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
const int md=1e7;
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int a[N];
bool notisprime[md+10];
int prime[N];
int prcnt;
inline void init(){
notisprime[1]=1;
for(int i=2;i<=md;++i){
if(!notisprime[i]){
prime[++prcnt]=i;
}
for(int j=1;j<=prcnt && prime[j]*i<N;++j){
notisprime[prime[j]*i]=1;
}
}
}
//b数组维护素数个数,tag数组存覆盖的值
struct fyn{
int b[N<<2],ls[N<<2],rs[N<<2];
int tag[N<<2];
int cnt;
inline void clear(){cnt=0;return;}
inline int newnode(){++cnt;b[cnt]=ls[cnt]=rs[cnt]=0;tag[cnt]=-1;return cnt;}
inline void pushup(int now){
b[now]=b[ls[now]]+b[rs[now]];
return;
}
inline void pushdown(int l,int r,int now){
int mid(((r-l)>>1)+l);
if(tag[now]==-1)return;
bool flag;
if(tag[now]>md){
flag=0;
}else flag=!notisprime[tag[now]];
b[ls[now]]=(mid-l+1)*flag;
b[rs[now]]=(r-mid)*flag;
tag[ls[now]]=tag[rs[now]]=tag[now];
tag[now]=-1;
return;
}
inline void build(int l,int r,int now){
if(l==r){
if(a[l]>md) b[now]=0;
else
b[now]=!notisprime[a[l]];
return;
}
int mid(((r-l)>>1)+l);
build(l,mid,ls[now]=newnode());
build(mid+1,r,rs[now]=newnode());
pushup(now);
return;
}
inline void add(int l,int nl,int nr,int now,int w){
if(nl==nr){
a[nl]+=w;
if(a[nl]>md) b[now]=0;
else
b[now]=!notisprime[a[nl]];
return;
}
int mid(((nr-nl)>>1)+nl);
pushdown(nl,nr,now);
if(l<=mid) add(l,nl,mid,ls[now],w);
else add(l,mid+1,nr,rs[now],w);
pushup(now);
return;
}
inline void update(int l,int r,int nl,int nr,int now,int w){
if(l<=nl && nr<=r){
if(w>md)
b[now]=0;
else
b[now]=(!notisprime[w])*(nr-nl+1);
tag[now]=w;
return;
}
pushdown(nl,nr,now);
int mid(((nr-nl)>>1)+nl);
if(l<=mid) update(l,r,nl,mid,ls[now],w);
if(mid<r) update(l,r,mid+1,nr,rs[now],w);
pushup(now);
return;
}
inline int query(int l,int r,int nl,int nr,int now){
if(l<=nl && nr<=r){
return b[now];
}
pushdown(nl,nr,now);
int mid(((nr-nl)>>1)+nl);
int ans=0;
if(l<=mid) ans+=query(l,r,nl,mid,ls[now]);
if(mid<r) ans+=query(l,r,mid+1,nr,rs[now]);
pushup(now);
return ans;
}
}tre;
int T;
signed main(){
init();
int n,q;
int rt;
n=read(),q=read();
for(int i=1;i<=n;++i){
a[i]=read();
}
tre.build(1,n,rt=tre.newnode());
for(int i=1;i<=q;++i){
char op;
cin>>op;
int x,y,v;
if(op=='A'){
cin>>x>>y;
tre.add(y,1,n,rt,x);
}
if(op=='R'){
cin>>v>>x>>y;
tre.update(x,y,1,n,rt,v);
}
if(op=='Q'){
cin>>x>>y;
cout<<tre.query(x,y,1,n,rt)<<endl;
}
}
return(0-0);
}