#include<bits/stdc++.h>
using namespace std;
const long long INF=1e5;
long long m;
struct Tree{
long long w,mul,plu;
}tr[4*INF+5];
void Build(long long l,long long r,long long k) {
tr[k].mul=1;
tr[k].plu=0;
if(l==r) {
scanf("%lld",&tr[k].w);
return ;
}
long long mid=(l+r)>>1;
Build(l,mid,k<<1);
Build(mid+1,r,k<<1|1);
tr[k].w=(tr[k<<1].w+tr[k<<1|1].w)%m;
}
void pushdown(long long l,long long r,long long k) {
long long mid=(l+r)>>1;
tr[k<<1].w=(tr[k<<1].w*tr[k].mul+tr[k].plu*(mid-l+1))%m;
tr[k<<1|1].w=(tr[k<<1|1].w*tr[k].mul+tr[k].plu*(r-mid))%m;
tr[k<<1].mul*=tr[k].mul;
tr[k<<1|1].mul*=tr[k].mul;
tr[k<<1].plu=tr[k<<1].plu*tr[k].mul+tr[k].plu;
tr[k<<1|1].plu=tr[k<<1|1].plu*tr[k].mul+tr[k].plu;
tr[k].mul=1;
tr[k].plu=0;
}
long long query(long long ll,long long rr,long long l,long long r,long long k) {
if(l>=ll&&r<=rr) return tr[k].w;
pushdown(l,r,k);
long long mid=(l+r)>>1,sum=0;
if(ll<=mid) sum=(sum+query(ll,rr,l,mid,k<<1))%m;
if(rr>mid) sum=(sum+query(ll,rr,mid+1,r,k<<1|1))%m;
return sum%m;
}
void update_1(long long ll,long long rr,long long l,long long r,long long k,long long val) {
if(l>=ll&&r<=rr) {
tr[k].mul*=val;
tr[k].plu*=val;
tr[k].w=(tr[k].w*val)%m;
return ;
}
pushdown(l,r,k);
long long mid=(l+r)>>1;
if(ll<=mid) update_1(ll,rr,l,mid,k<<1,val);
if(rr>mid) update_1(ll,rr,mid+1,r,k<<1|1,val);
tr[k].w=(tr[k<<1].w+tr[k<<1|1].w)%m;
}
void update_2(long long ll,long long rr,long long l,long long r,long long k,long long val) {
if(l>=ll&&r<=rr) {
tr[k].plu+=val;
tr[k].w=(tr[k].w+(r-l+1)*val)%m;
return ;
}
pushdown(l,r,k);
long long mid=(l+r)>>1;
if(ll<=mid) update_2(ll,rr,l,mid,k<<1,val);
if(rr>mid) update_2(ll,rr,mid+1,r,k<<1|1,val);
tr[k].w=(tr[k<<1].w+tr[k<<1|1].w)%m;
}
int main() {
long long n,q;
scanf("%lld%lld%lld",&n,&q,&m);
Build(1,n,1);
for(long long i=1;i<=q;i++) {
long long data;
scanf("%lld",&data);
if(data==1) {//mul
long long x,y,k;
scanf("%lld%lld%lld",&x,&y,&k);
update_1(x,y,1,n,1,k);
}
else if(data==2) {//plu
long long x,y,k;
scanf("%lld%lld%lld",&x,&y,&k);
update_2(x,y,1,n,1,k);
}
else {
long long x,y;
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(x,y,1,n,1)%m);
}
}
return 0;
}