#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,q,m,a[N],f[N*4],v1[N*4],v2[N*4],op,x,y,k;
inline void push_down(int k,int l,int r){
int mid=(l+r)>>1;
f[k*2]=(v2[k]*f[k*2]+v1[k]*(mid-l+1))%m;
f[k*2+1]=(v2[k]*f[k*2+1]+v1[k]*(r-mid))%m;
v2[k*2]=(v2[k*2]*v2[k])%m;
v2[k*2+1]=(v2[k*2+1]*v2[k])%m;
v1[k*2]=(v1[k*2]+v1[k])%m;
v1[k*2+1]=(v1[k*2+1]+v1[k])%m;
v2[k]=1;
v1[k]=0;
}
inline void buildtree(int k,int l,int r){
v1[k]=0,v2[k]=1;
if(l==r){
f[k]=a[l];
return ;
}
int mid=(l+r)>>1;
buildtree(k*2,l,mid),buildtree(k*2+1,mid+1,r);
f[k]=(f[k*2]+f[k*2+1])%m;
}
inline void add(int k,int l,int r,int x,int y,int z){
if(l==x&&r==y){
v1[k]=(v1[k]+z)%m;
f[k]=(f[k]+(r-l+1)*z)%m;
return ;
}
push_down(k,l,r);
int mid=(l+r)>>1;
if(y<=mid) add(k*2,l,mid,x,y,z);
else if(x>mid) add(k*2+1,mid+1,r,x,y,z);
else add(k*2,l,mid,x,mid,z),add(k*2+1,mid+1,r,mid+1,y,z);
f[k]=(f[k*2]+f[k*2+1])%m;
}
inline void insert(int k,int l,int r,int x,int y,int z){
if(l==x&&r==y){
v2[k]=(v2[k]*z)%m;
v1[k]=(v1[k]*z)%m;
f[k]=(f[k]*z)%m;
return ;
}
push_down(k,l,r);
int mid=(l+r)>>1;
if(y<=mid) insert(k*2,l,mid,x,y,z);
else if(x>mid) insert(k*2+1,mid+1,r,x,y,z);
else insert(k*2,l,mid,x,mid,z),insert(k*2+1,mid+1,r,mid+1,y,z);
f[k]=(f[k*2]+f[k*2+1])%m;
}
int calc(int k,int l,int r,int x,int y){
if(l==x&&r==y) return f[k];
push_down(k,l,r);
int mid=(l+r)>>1;
if(y<=mid) return calc(k*2,l,mid,x,y);
else if(x>mid) return calc(k*2+1,mid+1,r,x,y);
else return (calc(k*2,l,mid,x,mid)+calc(k*2+1,mid+1,r,mid+1,y))%m;
}
signed main(){
cin>>n>>q>>m;
for(int i=1;i<=n;i++) cin>>a[i];
buildtree(1,1,n);
while(q--){
cin>>op;
if(op==1){
cin>>x>>y>>k;
insert(1,1,n,x,y,k);
}
if(op==2){
cin>>x>>y>>k;
add(1,1,n,x,y,k);
}
if(op==3){
cin>>x>>y;
cout<<calc(1,1,n,x,y)<<endl;
}
}
return 0;
}