#include <bits/stdc++.h>
#define N 500005
#define lll long long
#define mid ((ll+rr)/2)
#define for1(i,n) for(int i=1;i<=n;i++)
using namespace std;
int n,m,mod,ndnum;
lll a[N],sum[2*N],lc[2*N],rc[2*N],sz[2*N],lazyAdd[2*N],lazyMul[2*N];
void update(int s){
sum[s]=(sum[lc[s]]%mod+sum[rc[s]]%mod)%mod;
}
void build(int s,int ll,int rr){
lazyMul[s]=1;
sz[s]=rr-ll+1;
if(sz[s]==1){
sum[s]=a[ll];
return;
}
lc[s]=++ndnum;
build(lc[s],ll,mid);
rc[s]=++ndnum;
build(rc[s],mid+1,rr);
update(s);
}
void tagMul(int s,lll k){
lazyMul[s]=lazyMul[s]*k%mod;
sum[s]=(sum[s]%mod)*(lazyMul[s]%mod)%mod;
}
void tagAdd(int s,lll k){
lazyAdd[s]=(lazyAdd[s]+k)%mod;
sum[s]=(sum[s]+k*sz[s]%mod)%mod;
}
void pushdown(int s){
if(lazyMul[s]>1 && lc[s]){
tagMul(lc[s],lazyMul[s]);
tagMul(rc[s],lazyMul[s]);
lazyMul[s]=1;
}
if(lazyAdd[s] && lc[s]){
tagAdd(lc[s],lazyAdd[s]);
tagAdd(rc[s],lazyAdd[s]);
lazyAdd[s]=0;
}
}
void add(int s,int ll,int rr,int L,int R,lll k){
if(ll>R||L>rr) return;
else if(ll>=L&&rr<=R){
tagAdd(s,k);
return;
}
else{
pushdown(s);
add(lc[s],ll,mid,L,R,k);
add(rc[s],mid+1,rr,L,R,k);
update(s);
}
}
void mul(int s,int ll,int rr,int L,int R,lll k){
if(ll>R||L>rr) return;
else if(ll>=L&&rr<=R){
tagMul(s,k);
return;
}
else{
pushdown(s);
mul(lc[s],ll,mid,L,R,k);
mul(rc[s],mid+1,rr,L,R,k);
update(s);
}
}
lll query(int s,int ll,int rr,int L,int R){
if(ll>R||L>rr) return 0;
else if(ll>=L&&rr<=R){
return sum[s]%mod;
}
else{
pushdown(s);
return (query(lc[s],ll,mid,L,R)%mod+query(rc[s],mid+1,rr,L,R)%mod)%mod;
}
}
int main(){
scanf("%d%d%d",&n,&m,&mod);
for1(i,n) scanf("%lld",&a[i]);
build(++ndnum,1,n);
for1(i,m){
int op,x,y;
scanf("%d",&op);
if(op==1){
lll k;
scanf("%d%d%lld",&x,&y,&k);
mul(1,1,n,x,y,k);
}
else if(op==2){
lll k;
scanf("%d%d%lld",&x,&y,&k);
add(1,1,n,x,y,k);
}
else{
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
}
return 0;
}