#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+1;
int n,q,mod,op,x,y,z,a[N],t[N<<2],tag[N<<2],tag2[N<<2];
inline int ls(int p){return p<<1;}
inline int rs(int p){return p<<1|1;}
inline void addtag(int p,int x){
tag2[p]=tag2[p]*x%mod;
tag[p]=tag[p]*x%mod;
t[p]=t[p]*x%mod;
}
inline void addtag2(int p,int pl,int pr,int x){
tag[p]=(tag[p]+x)%mod;
t[p]=(t[p]+x*(pr-pl+1))%mod;
}
inline void push_up(int p){t[x]=(t[ls(x)]+t[rs(x)])%mod;}
inline void push_down(int p,int pl,int pr){
int m=(pl+pr)>>1;
addtag(ls(p),tag2[p]);
addtag(rs(p),tag2[p]);
tag2[p]=1;
addtag2(ls(p),pl,m,tag[p]);
addtag2(rs(p),m+1,pr,tag[p]);
tag[p]=0;
}
void bulid(int p,int pl,int pr){
tag2[p]=1;
if(pl==pr){t[p]=a[pl];return;}
int m=(pl+pr)>>1;
bulid(ls(p),pl,m);
bulid(rs(p),m+1,pr);
push_up(p);
}
void update(int l,int r,int p,int pl,int pr,int x){
if(l<=pl&&pr<=r){addtag(p,x);return;}
push_down(p,pl,pr);
int m=(pl+pr)>>1;
if(l<=m)update(l,r,ls(p),pl,m,x);
if(m<r)update(l,r,rs(p),m+1,pr,x);
push_up(p);
}
void update2(int l,int r,int p,int pl,int pr,int x){
if(l<=pl&&pr<=r){addtag2(p,pl,pr,x);return;}
push_down(p,pl,pr);
int m=(pl+pr)>>1;
if(l<=m)update2(l,r,ls(p),pl,m,x);
if(m<r)update2(l,r,rs(p),m+1,pr,x);
push_up(p);
}
int query(int l,int r,int p,int pl,int pr){
if(l<=pl&&pr<=r)return t[p];
push_down(p,pl,pr);
int m=(pl+pr)>>1,an=0;
if(l<=m)an+=query(l,r,ls(p),pl,m);
if(m<r)an+=query(l,r,rs(p),m+1,pr);
return an;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>q>>mod;
for(int i=1;i<=n;i++)cin>>a[i];
while(q--){
cin>>op>>x>>y;
if(op==1){
cin>>z;
update(x,y,1,1,n,z);
}else if(op==2){
cin>>z;
update2(x,y,1,1,n,z);
}else cout<<query(x,y,1,1,n)<<'\n';
}
return 0;
}