#include<bits/stdc++.h>
using namespace std;
#define LL long long
int n,m;
LL p,a[100001],sum[400001],lz_add[400001],lz_mul[400001];
void add(int k,int l,int r,LL v_add,LL v_mul)
{
lz_add[k]=(lz_add[k]*v_mul%p+v_add)%p;
lz_mul[k]=lz_mul[k]*v_mul%p;
sum[k]=(sum[k]*v_mul%p+v_add*(r-l+1))%p;
}
void pushdown(int k,int l,int r)
{
if(lz_add[k]||lz_mul[k]>1)
{
int mid=l+r>>1;
add(k<<1,l,mid,lz_add[k],lz_mul[k]);
add(k<<1|1,mid+1,r,lz_add[k],lz_mul[k]);
lz_add[k]=0;
lz_mul[k]=1;
}
}
void pushup(int k)
{
sum[k]=(sum[k<<1]+sum[k<<1|1])%p;
}
void build(int k,int l,int r)
{
lz_mul[k]=1;
if(l==r)
{
sum[k]=a[l];
return;
}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}
void update(int k,int l,int r,int x,int y,LL v_add,LL v_mul)
{
if(x<=l&&r<=y)
{
add(k,l,r,v_add,v_mul);
return;
}
pushdown(k,l,r);
int mid=l+r>>1;
if(x<=mid)
update(k<<1,l,mid,x,y,v_add,v_mul);
if(y>mid)
update(k<<1|1,mid+1,r,x,y,v_add,v_mul);
pushup(k);
}
LL query(int k,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
return sum[k];
pushdown(k,l,r);
int mid=l+r>>1;
LL res=0;
if(x<=mid)
res=(res+query(k<<1,l,mid,x,y))%p;
if(y>mid)
res=(res+query(k<<1|1,mid+1,r,x,y))%p;
return res;
}
int main()
{
cin>>n>>m>>p;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i]%=p;
}
build(1,1,n);
while(m--)
{
int op;
cin>>op;
if(op==1)
{
int l,r;
LL v;
cin>>l>>r>>v;
update(1,1,n,l,r,0,v);
}
else if(op==2)
{
int l,r;
LL v;
cin>>l>>r>>v;
update(1,1,n,l,r,v,1);
}
else
{
int l,r;
cin>>l>>r;
cout<<query(1,1,n,l,r)<<'\n';
}
}
return 0;
}
thx