祝大佬rp++
#include<cstdio>
#define ll long long
const int maxn=1e5+1;
int n,q,mod,op,x,y,k;
struct Node{
int l,r,len;
ll sum,t1=1,t2;//tm,ta
Node *ls,*rs;
bool IN(int L,int R){return L<=l&&r<=R;}
bool OUT(int L,int R){return R<l||r<L;}
void mg1(int x){sum=sum*x%mod,t1=t1*x%mod,t2=t2*x%mod;}
void mg2(int x){sum=(sum+x*len)%mod,t2=(t2+x)%mod;}
void pushup(){sum=(ls->sum+rs->sum)%mod;}
void pushdown(){
ls->mg1(t1),rs->mg1(t1);
ls->mg2(t2),rs->mg2(t2);
t1=1,t2=0;
}
void upd(int L,int R){
if(IN(L,R)){
if(op&1)mg1(k);
else mg2(k);
}
else if(!OUT(L,R)){
pushdown();
ls->upd(L,R),rs->upd(L,R);
pushup();
}
}
int qry(int L,int R){
if(IN(L,R))return sum;
if(!OUT(L,R)){
pushdown();
return (ls->qry(L,R)+rs->qry(L,R))%mod;
}
return 0;
}
}mem[maxn<<1],*pool=mem;
Node* New(int L,int R){
auto x=pool++;
x->l=L,x->r=R,x->len=R-L+1;
if(L^R){
int M=L+R>>1;
x->ls=New(L,M),x->rs=New(M+1,R);
x->pushup();
}
else scanf("%lld",&(x->sum)),x->sum%=mod;
return x;
}
main(){
scanf("%d%d%d",&n,&q,&mod);
auto rot=New(1,n);
while(q--){
scanf("%d%d%d",&op,&x,&y);
if(op^3)scanf("%d",&k),rot->upd(x,y);
else printf("%lld\n",rot->qry(x,y));
//test();
}
}