#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
struct tree
{
int l,r,sum,a,c,tag;
}t[maxn*4];
int n,q,md;
int num[maxn];
void lazylag(int p,int k,int book)//k为参数 p为点的标号
{
if(book==1)
{
if(t[p].c ==1)
{
t[p].a+=k;
t[p].tag=9;
}else
{
if(t[p].tag==4)t[p].a=(t[p].r-t[p].l+1)*(k+t[p].a);
if(t[p].tag==9)t[p].a=t[p].c*(t[p].r-t[p].l+1)*(k+t[p].a);
}
}
if(book==2)
{
if(t[p].a==0)
{
t[p].c*=k;
t[p].tag=4;
}else
{
if(t[p].tag==4)
{
t[p].c*=k;
t[p].a=k*(t[p].r-t[p].l+1)*t[p].a;
}
if(t[p].tag==9)
{
t[p].c*=k;
t[p].a=t[p].c*(t[p].r-t[p].l+1)*t[p].a;
}
}
}
//cout<<t[p].sum<<'\n'<<t[p].c<<'\n'<<t[p].a<<'\n'<<t[p].r-t[p].l<<'\n';
return ;
}
void pushdown(int p)
{
for(int i=0;i<=1;i++)
{
if(t[p*2+i].tag==0)
{
t[p*2+i].tag=t[p].tag;
t[p*2+i].a=t[p].a;
t[p*2+i].c=t[p].c;
}else
{
if(t[p*2+i].tag==4)
{
lazylag(p*2+i,t[p*2+i].c,2);
lazylag(p*2+i,t[p*2+i].a,1);
}
if(t[p*2+i].tag==9)
{
lazylag(p*2+i,t[p*2+i].c,2);
lazylag(p*2+i,t[p*2+i].a,1);
}
}
t[p*2+i].sum=t[p*2+i].sum*t[p*2+i].c+t[p*2+i].a*(t[p*2+i].r-t[p*2+i].l+1);
}
t[p].a=0;t[p].c=1;t[p].tag=0;
}
void build(int p,int left,int right)
{
t[p].l=left;t[p].r=right;
t[p].a =0;t[p].c=1;t[p].tag=0;
if(left==right)
{
t[p].sum=num[left];
return;
}
int mid=(left+right)/2;
build(p*2,left,mid);
build(p*2+1,mid+1,right);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
void mul(int p,int i,int j,int x,int y,int k)
{
if(x<=i&&y>=j)lazylag(p,k,2);
else
{
if(t[p].a!=0||t[p].c!=1)pushdown(p);
int mid=(i+j)/2;
if(x<=mid)mul(p*2,x,mid,x,y,k);
if(y>mid)mul(p*2+1,mid+1,j,x,y,k);
t[p].sum=t[p*2].sum*t[p*2].c+t[p*2].a*(t[p*2].r-t[p*2].l+1)+t[p*2+1].sum*t[p*2+1].c+t[p*2+1].a*(t[p*2+1].r-t[p*2+1].l+1);
}
}
void plu(int p,int i,int j,int x,int y,int k)
{
if(x<=i&&y>=j)
{
lazylag(p,k,1);
}
else
{
if(t[p].a!=0||t[p].c!=1)pushdown(p);
int mid=(i+j)/2;
if(x<=mid)plu(p*2,x,mid,x,y,k);
if(y>mid)plu(p*2+1,mid+1,j,x,y,k);
t[p].sum=t[p*2].sum*t[p*2].c+t[p*2].a*(t[p*2].r-t[p*2].l+1)+t[p*2+1].sum*t[p*2+1].c+t[p*2+1].a*(t[p*2+1].r-t[p*2+1].l+1);
}
}
int query(int p,int x,int y)
{
if(t[p].l==x&&t[p].r==y)return t[p].sum*t[p].c+t[p].a*(t[p].r-t[p].l+1);
else
{
if(t[p].a!=0||t[p].c!=1)pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(x>mid)return query(p*2+1,mid+1,y);
else if(y<=mid)return query(p*2,x,mid);
else return query(p*2,x,mid)+query(p*2+1,mid+1,y);
}
}
int main()
{
cin>>n>>q>>md;
for(int i=1;i<=n;i++)cin>>num[i];
build(1,1,n);
for(int i=1;i<=q;i++)
{
int temp,x,y,k;
cin>>temp;
if(temp==1)
{
cin>>x>>y>>k;
mul(1,1,n,x,y,k);
}
if(temp==2)
{
cin>>x>>y>>k;
plu(1,1,n,x,y,k);
}
if(temp==3)
{
cin>>x>>y;
cout<<(query(1,x,y))%md<<'\n';
}
}
}