#include<bits/stdc++.h>
using namespace std;
#define N 100010
long long ans[N<<2],tag1[N<<2],tag2[N<<2],a[N];
long long n,m,mod,l,r,k;
void pushup(long long p){
ans[p]=ans[p<<1]+ans[p<<1|1];
}
void build(long long p,long long l,long long r){
if (l==r){
ans[p]=a[l];
return;
}
long long mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void pushdown(long long p,long long l,long long r){
long long mid=l+r>>1;
ans[p<<1]=(ans[p<<1]*tag1[p]+tag2[p]*(mid-l+1))%mod;
ans[p<<1|1]=(ans[p<<1|1]*tag1[p]+tag2[p]*(r-mid))%mod;
tag1[p<<1]=tag1[p<<1]*tag1[p]%mod;
tag1[p<<1|1]=tag1[p<<1|1]*tag1[p]%mod;
tag2[p<<1]=(tag2[p<<1]*tag1[p]+tag2[p])%mod;
tag2[p<<1|1]=(tag2[p<<1|1]*tag1[p]+tag2[p])%mod;
tag1[p]=1;
tag2[p]=0;
}
void up1(long long p,long long l,long long r,long long L,long long R,long long k){
if (L<=l && R>=r){
ans[p]+=(r-l+1)*k;
ans[p]%=mod;
tag2[p]=(tag2[p]+k)%mod;
return;
}
pushdown(p,l,r);
long long mid=l+r>>1;
if (mid>=L){
up1(p<<1,l,mid,L,R,k);
}
if (mid<R){
up1(p<<1|1,mid+1,r,L,R,k);
}
pushup(p);
}
void up2(long long p,long long l,long long r,long long L,long long R,long long k){
if (L<=l && R>=r){
ans[p]=ans[p]*k%mod;
tag1[p]=tag1[p]*k%mod;
tag2[p]=tag2[p]*k%mod;
return;
}
long long mid=l+r>>1;
pushdown(p,l,r);
if (mid>=L){
up2(p<<1,l,mid,L,R,k);
}
if (mid<R){
up2(p<<1|1,mid+1,r,L,R,k);
}
pushup(p);
}
long long q(long long p,long long l,long long r,long long L,long long R){
if (L<=l && R>=r){
return ans[p];
}
long long mid=l+r>>1,sum=0;
pushdown(p,l,r);
if (mid>=L){
sum+=q(p<<1,l,mid,L,R);
sum%=mod;
}
if (mid<R){
sum+=q(p<<1|1,mid+1,r,L,R);
sum%=mod;
}
return sum%mod;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> mod;
for (long long i=1;i<=n;i++){
cin >> a[i];
}
build(1,1,n);
while (m--){
long long op;
cin >> op;
if (op==1){
cin >> l >> r >> k;
up1(1,1,n,l,r,k);
}
else if(op==2){
cin >> l >> r >> k;
up2(1,1,n,l,r,k);
}
else{
cin >> l >> r;
cout << q(1,1,n,l,r)%mod << endl;
}
}
return 0;
}