#include<bits/stdc++.h>
#define N 1000010
#define IT set<ODT>::iterator
using namespace std;
int read()
{
int x = 0,f = 1;
char c = getchar();
while(c<'0' || c>'9')
{
if(c=='-') f = -1;
c = getchar();
}
while(c>='0' && c<='9')
{
x = (x<<3)+(x<<1)+(c^48);
c = getchar();
}
return x*f;
}
struct ODT
{
int l,r;
mutable int v;
ODT(int L,int R=-1,int V=0): l(L),r(R),v(V) {}
bool operator <(const ODT &o) const
{
return l<o.l;
}
};
set <ODT> s;
bool prime[N];
const int M = 1e7;
void Prime()
{
memset(prime,true,sizeof(prime));
prime[0] = prime[1] = false;
for(int i=2;i<=N;i++)
{
if(prime[i])
{
for(int j=i*2;j<=N;j+=i)
prime[j]=false;
}
}
}
IT split(int x)
{
IT it = s.lower_bound(ODT(x));
if (it!=s.end() && it->l==x) return it;
--it;
int L = it->l,R = it->r,V = it->v;
s.erase(it);
s.insert(ODT(L,x-1,V));
return s.insert(ODT(x,R,V)).first;
}
void assign(int l,int r,int v)
{
IT itr = split(r+1),itl = split(l);
s.erase(itl,itr);
s.insert(ODT(l,r,v));
}
void update(int p,int v)
{
IT it = split(p);
s.erase(it);
int L = it->l,R = it->r,V = it->v;
s.insert(ODT(L,p-1,V));
s.insert(ODT(p,p,V+v));
s.insert(ODT(p+1,R,V));
}
int query(int l,int r)
{
IT itr = split(r+1),itl = split(l);
int ans = 0;
for (IT it=itl;it!=itr;it++)
if (prime[it->v] && it->v<=M) ans += (it->r-it->l+1);
return ans;
}
int main()
{
Prime();
int n=read(),q=read();
for (int i=1;i<=n;i++)
s.insert(ODT(i,i,read()));
while(q--)
{
char opt;
cin >> opt;
if (opt=='R')
{
int k=read(),l=read(),r=read();
assign(l,r,k);
}
else if (opt=='Q')
{
int l=read(),r=read();
cout << query(l,r) << endl;
}
else
{
int k=read(),x=read();
split(x+1),split(x)->v += k;
}
}
return 0;
}