#include <iostream>
#include <cmath>
#include <cstdio>
#define int long long
using namespace std;
struct node{
int n,l,r;
int lt1=1,lt2;
}f[400005];
int a[100005];
int n,m,p;
void down2(int);
void down1(int z)
{
if(f[z].lt1!=1)
{
down2(z);
f[z*2].n=f[z*2].n*f[z].lt1%p;
if(f[z*2].lt1==true)
f[z*2].lt1=f[z*2].lt1*f[z].lt1%p;
else f[z*2].lt1=f[z].lt1%p;
f[z*2+1].n=f[z*2+1].n*f[z].lt1%p;
if(f[z*2+1].lt1==true)
f[z*2+1].lt1=f[1+z*2].lt1*f[z].lt1%p;
else f[z*2+1].lt1=f[z].lt1%p;
f[z].lt1=0;
return ;
}
}
void down2(int z)
{
if(f[z].lt2==true)
{
down1(z);
f[z*2].n=f[z*2].n+f[z].lt2*(f[z*2].r-f[z*2].l)%p;
f[z*2+1].n=f[z*2+1].n+f[z].lt2*(f[z*2+1].r-f[z*2+1].l)%p;
f[z*2].lt2+=f[z].lt2;;;
f[z*2+1].lt2+=f[z].lt2;
f[z].lt2=0;
return ;
}
}
void build(int z,int l,int r)
{
f[z].l=l;
f[z].r=r;
if(l==r)
{
f[z].n=a[l];
return ;
}
int mid=l+r>>1;
build(z*2,l,mid);
build(z*2+1,mid+1,r);
f[z].n=f[z*2].n+f[z*2+1].n;
return ;
}
void cheng(int z,int l,int r,int v)
{
down2(z);
if(l<=f[z].l&&r>=f[z].r)
{
f[z].lt1*=v;
return ;
}
down1(z);
int mid=(f[z].l+f[z].r)/2;
if(l<=mid)cheng(z*2,l,r,v);
if(r>mid)cheng(z*2+1,l,r,v);
f[z].n=(f[z*2].n+f[z*2+1].n)%p;
return ;
}
void jia(int z,int l,int r,int v)
{
down1(z);
if(l<=f[z].l&&r>=f[z].r)
{
f[z].lt2+=v;
return ;
}
down2(z);
int mid=(f[z].l+f[z].r)/2;
if(l<=mid)jia(z*2,l,r,v);
if(r>mid)jia(z*2+1,l,r,v);
f[z].n=(f[z*2].n+f[z*2+1].n)%p;
return ;
}
int ask(int z,int l,int r)
{
down1(z);down2(z);
if(l<=f[z].l&&r>=f[z].r)
return f[z].n;
int mid=(f[z].l+f[z].r)/2;
long long ans=0;
if(l<=mid)ans+=ask(z*2,l,r);
if(r>mid)ans+=ask(z*2+1,l,r);
return ans%p;
}
signed main()
{
cin>>n>>m>>p;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1,1,n);
while(m--)
{
int pos;
cin>>pos;
if(pos==1)
{
int a,b,c;
cin>>a>>b>>c;
cheng(1,a,b,c);
}
if(pos==2)
{
int a,b,c;
cin>>a>>b>>c;
jia(1,a,b,c);
}
if(pos==3)
{
int a,b;
cin>>a>>b;
cout<<ask(1,a,b)<<endl;
}
}
return 0;
}