#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[100010];
ll lazy[400040],sum[400040],mul[400040];
ll n,m,q;
void build(int p,int front,int end){
lazy[p]=0,mul[p]=1;
if(front==end){
sum[p]=a[front];
return ;
}
int mid=(front+end)/2;
build(2*p,front,mid);
build(2*p+1,mid+1,end);
sum[p]=sum[2*p]+sum[2*p+1],sum[p]%=q;
}
void lazy_down(int p,int front,int end){
if(lazy[p]==0&&mul[p]==1) return ;
int mid=(front+end)/2;
mul[2*p]=(mul[2*p]*mul[p])%q,mul[2*p+1]=(mul[2*p+1]*mul[p])%q,lazy[2*p]=(lazy[2*p]*mul[p]+lazy[p])%q,lazy[2*p+1]=(lazy[2*p+1]*mul[p]+lazy[p])%q,sum[2*p]=(sum[2*p]*mul[p]+(mid-front+1)*lazy[p])%q,sum[2*p+1]=(sum[2*p+1]*mul[p]+(end-mid)*lazy[p])%q,lazy[p]=0,mul[p]=1;
}
void multiply(int p,int front,int end,int x,int y,int k){
if(front>y||end<x) return ;
if(front>=x&&end<=y){
mul[p]=(mul[p]*k)%q,lazy[p]=(lazy[p]*k)%q,sum[p]=(sum[p]*k)%q;
return ;
}
lazy_down(p,front,end);
int mid=(front+end)/2;
multiply(p*2,front,mid,x,y,k);
multiply(p*2+1,mid+1,end,x,y,k);
sum[p]=(sum[p*2]+sum[p*2+1])%p;
}
void check(int p,int front,int end,int x,int y,int v){
if(front>y||end<x) return ;
if(front>=x&&end<=y) {
lazy[p]=(lazy[p]+v)%q,sum[p]=(sum[p]+v*(end-front+1))%q;
return ;
}
lazy_down(p,front,end);
int mid=(front+end)/2;
if(mid>=x) check(2*p,front,mid,x,y,v);
if(mid<y) check(2*p+1,mid+1,end,x,y,v);
sum[p]=(sum[2*p]+sum[2*p+1])%q;
}
ll find(int p,int front,int end,int x,int y){
if(x>end||y<front) return 0;
if(x<=front&&y>=end) return sum[p];
lazy_down(p,front,end);
int mid=(front+end)>>1;
return (find(2*p,front,mid,x,y)+find(2*p+1,mid+1,end,x,y))%q;
}
int main(){
int c,x,y,z;
cin>>n>>m>>q;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
for(int i=1;i<=m;i++){
cin>>c;
if(c==1){
cin>>x>>y>>z;
multiply(1,1,n,x,y,z);
}
else if(c==2){
cin>>x>>y>>z;
check(1,1,n,x,y,z);
}
else {
cin>>x>>y;
cout<<find(1,1,n,x,y)<<endl;
}
}
return 0;
}