#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define mn 100010
#define ll long long
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while('0'>ch || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while('0'<=ch && ch<='9'){x=x*10+(ch-'0');ch=getchar();}
return x*f;
};
int n,q;
ll m;
ll st[mn];
struct name{
int l,r;
ll ans;
ll cf,jf;
}a[mn*4];
void build(int x,int y,int b){
a[b].l=x;a[b].r=y;
if(x==y) {a[b].ans=st[x]%m;return;}
int mid=(x+y)>>1;
build(x,mid,b<<1);build(mid+1,y,b<<1|1);
a[b].ans=(a[b<<1].ans+a[b<<1|1].ans)%m;
};
void spread(int b){
if(a[b].cf){
a[b<<1].jf=(a[b<<1].jf*a[b].cf)%m;
a[b<<1|1].jf=(a[b<<1|1].jf*a[b].cf)%m;
a[b<<1].cf=max((a[b<<1].cf*a[b].cf),a[b].cf)%m;
a[b<<1|1].cf=max((a[b<<1|1].cf*a[b].cf),a[b].cf)%m;
a[b<<1].ans=(a[b<<1].ans*a[b].cf)%m;
a[b<<1|1].ans=(a[b<<1|1].ans*a[b].cf)%m;
a[b].cf=0;
}
if(a[b].jf){
a[b<<1].ans=(a[b<<1].ans+a[b].jf*(a[b<<1].r-a[b<<1].l+1))%m;
a[b<<1].jf=(a[b<<1].jf+a[b].jf)%m;
a[b<<1|1].ans=(a[b<<1|1].ans+a[b].jf*(a[b<<1|1].r-a[b<<1|1].l+1))%m;
a[b<<1|1].jf=(a[b<<1|1].jf+a[b].jf)%m;
a[b].jf=0;
}
};
void addj(int x,int y,int b,ll z){
if(a[b].l>=x && a[b].r<=y){
a[b].ans=(a[b].ans+z*(a[b].r-a[b].l+1))%m;
a[b].jf=(a[b].jf+z)%m;
return;
}
spread(b);
int mid=(a[b].l+a[b].r)>>1;
if(x<=mid) addj(x,y,b<<1,z);
if(mid+1<=y) addj(x,y,b<<1|1,z);
a[b].ans=(a[b<<1].ans+a[b<<1|1].ans)%m;
};
void addc(int x,int y,int b,ll z){
if(a[b].l>=x && a[b].r<=y){
a[b].ans=(a[b].ans*z)%m;a[b].cf=max((a[b].cf*z),z)%m;
a[b].jf=(a[b].jf*z)%m;
return;
}
spread(b);
int mid=(a[b].l+a[b].r)>>1;
if(x<=mid) addc(x,y,b<<1,z);
if(mid+1<=y) addc(x,y,b<<1|1,z);
a[b].ans=(a[b<<1].ans+a[b<<1|1].ans)%m;
};
ll find(int x,int y,int b){
if(a[b].l>=x && a[b].r<=y) return a[b].ans;
spread(b);
int mid=(a[b].l+a[b].r)>>1;
ll ansl=0;
if(x<=mid) ansl=ansl+find(x,y,b<<1);
if(mid+1<=y) ansl=ansl+find(x,y,b<<1|1);
return ansl%m;
};
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
n=read();q=read();m=read();
for(int i=1;i<=n;i++) st[i]=read();
build(1,n,1);
for(int i=1;i<=q;i++){
int opt=read();
int x=read(),y=read();
ll k;
if(opt==1){
k=read();
addc(x,y,1,k);
}
if(opt==2){
k=read();
addj(x,y,1,k);
}
if(opt==3){
printf("%lld\n",find(x,y,1));
}
}
return 0;
}