rt,
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
int mod;
int a[1000005];
int l1[1000005];
int r1[1000005];
int ans[1000005];
int t1[1000005];
int t[1000005];
int lefc(int x){
return x<<1;
}
int rigc(int x){
return x<<1|1;
}
void pu(int x){
ans[x]=(ans[lefc(x)]+ans[rigc(x)])%mod;
}
void build(int x,int l,int r){
l1[x]=l;
r1[x]=r;
t1[x]=1;
t[x]=0;
if(l==r) {
ans[x]=a[l]%mod;
return;
}
int mid=(l+r)/2;
build(lefc(x),l,mid);
build(rigc(x),mid+1,r);
ans[x]=ans[lefc(x)]+ans[rigc(x)];
ans[x]%=mod;
//pu(x);
}
void pd(int x){
ans[lefc(x)]=ans[lefc(x)]*t1[x]+((r1[lefc(x)]-l1[lefc(x)]+1)*t[x]%mod)%mod;
ans[rigc(x)]=ans[rigc(x)]*t1[x]+((r1[rigc(x)]-l1[rigc(x)]+1)*t[x]%mod)%mod;
t1[lefc(x)]=(t1[lefc(x)]*t1[x])%mod;
t1[rigc(x)]=(t1[rigc(x)]*t1[x])%mod;
t[lefc(x)]=(t[lefc(x)]*t1[x]+t[x])%mod;
t[rigc(x)]=(t[rigc(x)]*t1[x]+t[x])%mod;
t1[x]=1;
t[x]=0;
}
void udt(int l,int r,int x,int k){
int lu,ru;
lu=l1[x];
ru=r1[x];
if(l<=lu&&ru<=r){
t[x]+=k;
t[x]%=mod;
ans[x]+=(r1[x]-l1[x]+1)*k;
ans[x]%=mod;
return;
}
pd(x);
ans[x]=(ans[lefc(x)]+ans[rigc(x)])%mod;
int mid=(lu+ru)/2;
if(l<=mid) udt(l,r,lefc(x),k);
if(mid<r) udt(l,r,rigc(x),k);
pu(x);
}
void udtx(int l,int r,int x,int k){
int lx=l1[x];
int rx=r1[x];
if(l<=lx&&rx<=r){
t[x]=(t[x]*k)%mod;
t1[x]=(t1[x]*k)%mod;
ans[x]=(ans[x]*k)%mod;
return;
}
pd(x);
ans[x]=(ans[lefc(x)]+ans[rigc(x)]);
int mid=(lx+rx)/2;
if(l<=mid) udtx(l,r,lefc(x),k);
if(mid<r) udtx(l,r,rigc(x),k);
pu(x);
}
int quy(int l,int r,int x){
int lq=l1[x];
int rq=r1[x];
if(l<=lq&&rq<=r){
return ans[x];
}
pd(x);
int val=0;
int mid=(l+r)/2;
if(l<=mid) val=(val+quy(l,r,lefc(x)));
if(mid<r) val=(val+quy(l,r,rigc(x)));
return val;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>mod;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
while(m--){
int op;
cin>>op;
if(op==1){
int x,y,k;
cin>>x>>y>>k;
udtx(x,y,1,k);
}
if(op==2){
int x,y,k;
cin>>x>>y>>k;
udt(x,y,1,k);
}
if(op==3){
int x,y;
cin>>x>>y;
cout<<quy(x,y,1)<<'\n';
}
}
return 0;
}