#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
inline void write(int x){
if(x==0){putchar('0');return;}
int len=0,k1=x,c[10005];
if(k1<0)k1=-k1,putchar('-');
while(k1)c[len++]=k1%10+'0',k1/=10;
while(len--)putchar(c[len]);
}
const int N=1e5+10;
int a[N],mod;
struct SGT{
int tr[N<<2],add[N<<2],mul[N<<2];
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
void push_up(int p){tr[p]=(tr[ls(p)]+tr[rs(p)])%mod;}
void build(int p,int pl,int pr){
add[p]=0,mul[p]=1;
if(pl==pr){
tr[p]=a[pl];
return ;
}
int mid=(pl+pr)>>1;
build(ls(p),pl,mid);
build(rs(p),mid+1,pr);
push_up(p);
}
void mul_tag(int p,int pl,int pr,int d){
mul[p]=(mul[p]+d)%mod;
add[p]=(add[p]*d)%mod;
tr[p]=(tr[p]*d)%mod;
}
void add_tag(int p,int pl,int pr,int d){
add[p]=(add[p]+d)%mod;
tr[p]=(tr[p]+d*(pr-pl+1))%mod;
}
void push_down(int p,int pl,int pr){
if(mul[p]!=1){
int mid=(pl+pr)>>1;
mul_tag(ls(p),pl,mid,mul[p]);
mul_tag(rs(p),mid+1,pr,mul[p]);
mul[p]=1;
}
if(add[p]){
int mid=(pl+pr)>>1;
add_tag(ls(p),pl,mid,add[p]);
add_tag(rs(p),mid+1,pr,add[p]);
add[p]=0;
}
}
void upd1(int l,int r,int p,int pl,int pr,int d){
if(l<=pl&&pr<=r){
mul_tag(p,pl,pr,d);
return ;
}
push_down(p,pl,pr);
int mid=(pl+pr)>>1;
if(l<=mid)upd1(l,r,ls(p),pl,mid,d);
if(r>mid)upd1(l,r,rs(p),mid+1,pr,d);
push_up(p);
}
void upd2(int l,int r,int p,int pl,int pr,int d){
if(l<=pl&&pr<=r){
add_tag(p,pl,pr,d);
return ;
}
push_down(p,pl,pr);
int mid=(pl+pr)>>1;
if(l<=mid)upd2(l,r,ls(p),pl,mid,d);
if(r>mid)upd2(l,r,rs(p),mid+1,pr,d);
push_up(p);
}
int query(int l,int r,int p,int pl,int pr){
if(pl>=l&&pr<=r)return tr[p];
push_down(p,pl,pr);
int res=0,mid=(pl+pr)>>1;
if(l<=mid)res=(res+query(l,r,ls(p),pl,mid))%mod;
if(r>mid)res=(res+query(l,r,rs(p),mid+1,pr))%mod;
return res;
}
}sgt;
signed main(){
int n=read(),m=read();mod=read();
for(int i=1;i<=n;i++)a[i]=read();
sgt.build(1,1,n);
while(m--){
int op=read(),l=read(),r=read();
if(op==1){
int d=read();
sgt.upd1(l,r,1,1,n,d);
}
else if(op==2){
int d=read();
sgt.upd2(l,r,1,1,n,d);
}
else write((sgt.query(l,r,1,1,n))%mod),puts("");
}
return 0;
}