#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,q,x,y,k,op,mod,a[N];
struct SGT {
int ans[N<<2],tag1[N<<2],tag2[N<<2];
inline int ls(int p) {return p<<1;}
inline int rs(int p) {return p<<1|1;}
inline void psup(int p) {ans[p]=ans[ls(p)]+ans[rs(p)],ans[p]%=mod;}
inline void build(int p=1,int L=1,int R=n) {
tag2[p]=1;
if(L==R) {
ans[p]=a[L];
return;
}
int mid=(L+R)>>1;
build(ls(p),L,mid),build(rs(p),mid+1,R),psup(p);
}
inline void work1(int p,int L,int R,int k) {tag1[p]+=k,ans[p]+=(R-L+1)*k,tag1[p]%=mod,ans[p]%=mod;}
inline void work2(int p,int L,int R,int k) {tag1[p]*=k,tag2[p]*=k,ans[p]*=k,tag1[p]%=mod,tag2[p]%=mod,ans[p]%=mod;}
inline void psd(int p,int L,int R) {
int mid=(L+R)>>1;
if(tag2[p]!=1) work2(ls(p),L,mid,tag2[p]),work2(rs(p),mid+1,R,tag2[p]),tag2[p]=1;
if(tag1[p]) work1(ls(p),L,mid,tag1[p]),work1(rs(p),mid+1,R,tag1[p]),tag1[p]=0;
}
inline void add1(int l,int r,int k,int p=1,int L=1,int R=n) {
if(l<=L&&R<=r) {
work1(p,L,R,k);
return;
}
psd(p,L,R);
int mid=(L+R)>>1;
if(l<=mid) add1(l,r,k,ls(p),L,mid);
if(r>mid) add1(l,r,k,rs(p),mid+1,R);
psup(p);
}
inline void add2(int l,int r,int k,int p=1,int L=1,int R=n) {
if(l<=L&&R<=r) {
work2(p,L,R,k);
return;
}
psd(p,L,R);
int mid=(L+R)>>1;
if(l<=mid) add2(l,r,k,ls(p),L,mid);
if(r>mid) add2(l,r,k,rs(p),mid+1,R);
psup(p);
}
inline int gts(int l,int r,int p=1,int L=1,int R=n) {
int res=0;
if(l<=L&&R<=r) return ans[p];
psd(p,L,R);
int mid=(L+R)>>1;
if(l<=mid) res+=gts(l,r,ls(p),L,mid);
if(r>mid) res+=gts(l,r,rs(p),mid+1,R);
return res;
}
} t;
signed main() {
ios_base::sync_with_stdio(NULL);
cin.tie(nullptr);
cout.tie(nullptr);
cin>>n>>q>>mod;
for(int i=1;i<=n;i++)
cin>>a[i];
t.build();
while(q--) {
cin>>op>>x>>y;
if(op==1) cin>>k,t.add1(x,y,k);
else if(op==2) cin>>k,t.add2(x,y,k);
else cout<<t.gts(x,y)<<'\n';
}
return 0;
}