#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+7;
int n,m,mod,a[maxn];
struct tree{
int x,ldj,ldc;
}t[maxn<<2];
void up(int rt){
t[rt].x=(t[rt<<1].x+t[rt<<1|1].x)%mod;
}
void upl(int rt,int ln,int rn){
if(t[rt].ldj){
t[rt<<1].ldj=(t[rt<<1].ldj+t[rt].ldj)%mod;
t[rt<<1|1].ldj=(t[rt<<1|1].ldj+t[rt].ldj)%mod;
t[rt<<1].x+=t[rt].ldj*ln%mod;
t[rt<<1].x%=mod;
t[rt<<1|1].x+=t[rt].ldj*rn%mod;
t[rt<<1|1].x%=mod;
t[rt].ldj=0;
}
if(t[rt].ldc){
t[rt<<1].ldc=(t[rt<<1].ldc*t[rt].ldc)%mod;
t[rt<<1|1].ldc=(t[rt<<1|1].ldc*t[rt].ldc)%mod;
t[rt<<1].x=(t[rt<<1].x*((t[rt].ldc*ln)%mod))%mod;
t[rt<<1|1].x=(t[rt<<1|1].x*((t[rt].ldc*rn)%mod))%mod;
t[rt].ldc=0;
}
}
void gz(int l,int r,int rt){
t[rt].ldj=t[rt].ldc=0;
if(l==r){
t[rt].x=a[l]%mod;
return;
}
int mid=(l+r)/2;
gz(l,mid,rt<<1);
gz(mid+1,r,rt<<1|1);
up(rt);
}
void xgj(int L,int R,int C,int l,int r,int rt){
if(L<=l&&r<=R){
t[rt].x+=C*(r-l+1)%mod;
t[rt].x%=mod;
t[rt].ldj+=C%mod;
t[rt].ldj%=mod;
return;
}
int mid=(l+r)/2;
upl(rt,mid-l+1,r-mid);
if(L<=mid)xgj(L,R,C,l,mid,rt<<1);
if(R>mid)xgj(L,R,C,mid+1,r,rt<<1|1);
up(rt);
}
void xgc(int L,int R,int C,int l,int r,int rt){
if(L<=l&&r<=R){
t[rt].x=(t[rt].x*(C*(r-l+1)%mod))%mod;
t[rt].ldc=t[rt].ldc*C%mod;
return;
}
int mid=(l+r)/2;
upl(rt,mid-l+1,r-mid);
if(L<=mid)xgc(L,R,C,l,mid,rt<<1);
if(R>mid)xgc(L,R,C,mid+1,r,rt<<1|1);
up(rt);
}
int qh(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return t[rt].x%mod;
}
if(L>r||R<l)return 0;
int m=(l+r)/2;
upl(rt,m-l+1,r-m);
return (qh(L,R,l,m,rt<<1)+qh(L,R,m+1,r,rt<<1|1))%mod;
}
signed main(){
scanf("%lld%lld%lld",&n,&m,&mod);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
a[i]%=mod;
}
gz(1,n,1);
while(m--){
int op,l,r,k;
scanf("%lld%lld%lld",&op,&l,&r);
if(op==3){
printf("%lld\n",qh(l,r,1,n,1)%mod);
}else{
scanf("%lld",&k);
if(op==2){
xgj(l,r,k,1,n,1);
}else{
xgc(l,r,k,1,n,1);
}
}
}
}
悬一关