/*input
10 7
3 2 4 8 8 7 8 4 8 10
1 1 7
1 1 3
1 6 10
1 5 6
2 1 2 2
1 5 6
1 5 6
*/
#include<iostream>
using namespace std;
const int N=1e7+10;
const int mod=998244353;
bool p[N];
int prime[N],s[N],cp;
long long tree[4][N];
int lowbit(int x){return x&-x;}
void add(int x,int id,int p){while(id<N) {(tree[p][id]+=x)%=mod,id+=lowbit(id);}}
long long query(int p,int id){long long ans=0;while(id) {(ans+=tree[p][id])%=mod,id-=lowbit(id);}return ans;}
int main()
{
for(int i=2;i<N;i++)
{
if(!p[i]) prime[++cp]=i,s[i]=i;
for(int j=1;j<=cp&&i*prime[j]<N;j++)
{
p[i*prime[j]]=1;
s[i*prime[j]]=prime[j];
if(i%prime[j]==0) break;
}
}
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++)
{
int x,sum=0;
scanf("%d",&x);
while(x!=1)
{
int tmp=s[x];
while(x%tmp==0) sum+=tmp,x/=tmp;
}
if(sum!=0)
{
add(1,i,2);
add(-1,i+1,2);
add(i,i,3);
add(-i-1,i+1,3);
}
add(sum,i,0);
add(-sum,i+1,0);
add(1ll*i*sum%mod,i,1);
add(-1ll*(i+1)*sum%mod,i+1,1);
}
for(int i=1;i<=q;i++)
{
int op;
scanf("%d",&op);
if(op==1)
{
int l,r;
scanf("%d%d",&l,&r);
long long ans=1ll*(r+1)*query(0,r)%mod-query(1,r)-(1ll*l*query(0,l-1)%mod-query(1,l-1));
if((1ll*(r+1)*query(2,r)%mod-query(3,r)-(1ll*l*query(2,l-1)%mod-query(3,l-1)))==0) ans=1;
ans=(ans%mod+mod)%mod;
printf("%lld\n",ans);
}
else
{
int l,r,x,sum=0;
scanf("%d%d%d",&l,&r,&x);
while(x!=1)
{
int tmp=s[x];
while(x%tmp==0) sum+=tmp,x/=tmp;
}
if(sum!=0)
{
add(1,l,2);
add(-1,r+1,2);
add(l,l,3);
add(-r-1,r+1,3);
}
add(sum,l,0);
add(-sum,r+1,0);
add(1ll*l*sum%mod,l,1);
add(-1ll*(r+1)*sum%mod,r+1,1);
}
}
}
06-17
176