#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 10;
ll a[N];
ll tree[N<<2];
ll tag_add[N<<2];
ll tag_mul[N<<2];
ll ls(ll p){ return p<<1; }
ll rs(ll p){ return p<<1|1;}
int MOD=0;
void push_up(ll p){
tree[p] = (tree[ls(p)] + tree[rs(p)])%MOD;
}
void build(ll p,ll pl,ll pr){
tag_add[p] = 0;
if(pl==pr){tree[p]=a[pl]%MOD; return;}
ll mid = (pl+pr) >> 1;
build(ls(p),pl,mid);
build(rs(p),mid+1,pr);
push_up(p);
}
void add(ll p,ll pl,ll pr,ll d){
tag_add[p] = (tag_add[p]+d%MOD)%MOD;
tree[p] = (tree[p]+(d%MOD)*(pr-pl+1))%MOD;
}
void mul(ll p,ll pl,ll pr,ll d){
if(!tag_mul[p]) tag_mul[p]=d%MOD;
else tag_mul[p] =(tag_mul[p]* d)%MOD;
tag_add[p]=(tag_add[p]*(d%MOD))%MOD;
tree[p] =(tree[p]%MOD*d%MOD)%MOD;
}
void push_down(ll p,ll pl,ll pr){
if(tag_add[p]||tag_mul[p]){
ll mid = (pl+pr)>>1;
if(tag_mul[p]){
mul(ls(p),pl,mid,tag_mul[p]);
mul(rs(p),mid+1,pr,tag_mul[p]);
tag_mul[p]=0;
}
add(ls(p),pl,mid,tag_add[p]);
add(rs(p),mid+1,pr,tag_add[p]);
tag_add[p]=0;
}
}
void update_add(ll L,ll R,ll p,ll pl,ll pr,ll d){
if(L<=pl && pr<=R){
add(p, pl, pr,d);
return;
}
push_down(p,pl,pr);
ll mid=(pl+pr)>>1;
if(L<=mid) update_add(L,R,ls(p),pl,mid,d);
if(R>mid) update_add(L,R,rs(p),mid+1,pr,d);
push_up(p);
}
void update_mul(ll L,ll R,ll p,ll pl,ll pr,ll d){
if(L<=pl && pr<=R){
mul(p, pl, pr,d);
return;
}
push_down(p,pl,pr);
ll mid=(pl+pr)>>1;
if(L<=mid) update_mul(L,R,ls(p),pl,mid,d);
if(R>mid) update_mul(L,R,rs(p),mid+1,pr,d);
push_up(p);
}
ll query(ll L,ll R,ll p,ll pl,ll pr){
if(pl>=L && R >= pr) return tree[p]%MOD;
push_down(p,pl,pr);
ll res=0;
ll 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%MOD;
}
void mdf(ll p,ll pl,ll pr){
tag_add[p]=0;
tag_mul[p]=0;
if(pl==pr) {
tree[p]=0;
return;
}
ll mid=pl+pr>>1;
mdf(ls(p),pl,mid);
mdf(rs(p),mid+1,pr);
push_up(p);
}
void change(ll L,ll R,ll p,ll pl,ll pr){
if(pl>=L && R >= pr) {
mdf(p,pl,pr);
return;
}
ll mid = (pl+pr)>>1;
if(L<=mid) change(L,R,ls(p),pl,mid);
if(R>mid) change(L,R,rs(p),mid+1,pr);
push_up(p);
}
int main(){
ll n, m; scanf("%lld%lld%lld",&n,&m,&MOD);
for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
while(m--){
ll q,L,R,d; scanf("%lld",&q);
if (q==1){
scanf("%lld%lld%lld",&L,&R,&d);
if(d==0) change(L,R,1,1,n);
else update_mul(L,R,1,1,n,d);
}else if(q==2){
scanf("%lld%lld%lld",&L,&R,&d);
update_add(L,R,1,1,n,d);
}
else {
scanf("%lld%lld",&L,&R);
printf("%lld\n",query(L,R,1,1,n));
}
}
return 0;
}