#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,p,x,y,op,k;
struct node{
int l,r,sum,t1,t2;
}t[1000000];
void up(int c){
t[c].sum=(t[c*2].sum+t[c*2+1].sum)%p;
}
void dn(int c){
t[c*2].sum=(t[c*2].sum*t[c].t2%p+t[c].t1*(t[c*2].r-t[c*2].l+1)%p)%p;
t[c*2].t2=t[c*2].t2*t[c].t2%p;
t[c*2].t1=(t[c*2].t1*t[c].t2+t[c].t1)%p;
t[c*2+1].sum=(t[c*2+1].sum*t[c].t2%p+t[c].t1*(t[c*2+1].r-t[c*2+1].l+1)%p)%p;
t[c*2+1].t2=t[c*2+1].t2*t[c].t2%p;
t[c*2+1].t1=(t[c*2+1].t1*t[c].t2+t[c].t1)%p;
t[c].t1=0,t[c].t2=1;
}
void bd(int x,int y,int c){
t[c].l=x,t[c].r=y,t[c].t1=0,t[c].t2=1;
if(x==y){
cin>>t[c].sum;
t[c].sum%=p;
return;
}
int mid=(x+y)/2;
bd(x,mid,c*2);
bd(mid+1,y,c*2+1);
up(c);
}
void ad(int x,int y,int c,int k){
if(t[c].l>y||t[c].r<x) return;
if(t[c].l>=x&&t[c].r<=y){
t[c].sum=(t[c].sum+k*(t[c].r-t[c].l+1)%p)%p;
t[c].t1=(t[c].t1+k)%p;
return;
}
dn(c);
ad(x,y,c*2,k);
ad(x,y,c*2+1,k);
up(c);
}
void ml(int x,int y,int c,int k){
if(t[c].l>y||t[c].r<x) return;
if(t[c].l>=x&&t[c].r<=y){
t[c].sum=(t[c].sum*k)%p;
t[c].t2=(t[c].t2*k)%p;
t[c].t1=(t[c].t1*k)%p;
return;
}
dn(c);
ad(x,y,c*2,k);
ad(x,y,c*2+1,k);
up(c);
}
int fd(int x,int y,int c){
if(t[c].l>y||t[c].r<x) return 0;
if(t[c].l>=x&&t[c].r<=y) return t[c].sum;
dn(c);
return (fd(x,y,c*2)+fd(x,y,c*2+1))%p;
}
signed main(){
cin>>n>>m>>p;
bd(1,n,1);
while(m--){
cin>>op;
if(op==1){
cin>>x>>y>>k;
ml(x,y,1,k);
}
else if(op==2){
cin>>x>>y>>k;
ad(x,y,1,k);
}
else{
cin>>x>>y;
cout<<fd(x,y,1)%p<<endl;
}
}
return 0;
}