#include<iostream>
#include<cstdio>
using namespace std;
const int M=100005,L=0,R=1;
int n,m,p;
int q,x,y,k;
int v[M];
int rt,cnt;
struct xds
{
long long int sum,addt,mult;
int son[2];
}a[M*2];
void build(int &rt,int l,int r)
{
rt=++cnt;
if(l==r)
{
a[rt].sum=v[l]%p;
a[rt].mult=1,a[rt].addt=0;
}
else
{
int mid=(l+r)>>1;
build(a[rt].son[L],l,mid);
build(a[rt].son[R],mid+1,r);
a[rt].sum=(a[a[rt].son[L]].sum%p+a[a[rt].son[R]].sum%p)%p;
a[rt].mult=1,a[rt].addt=0;
}
}
void tag(int rt,int l,int r,int mu,int ad)
{
a[rt].sum=(a[rt].sum*mu%p+(r-l+1)*ad%p)%p;
a[rt].addt=(a[rt].addt*mu%p+ad%p)%p;
a[rt].mult=a[rt].mult*mu%p;
}
void modify1(int rt,int l,int r,int ql,int qr,int k)
{
if(l==ql&&r==qr)
tag(rt,l,r,k,0);
else
{
int mid=(l+r)>>1;
tag(a[rt].son[L],l,mid,a[rt].mult,a[rt].addt);
tag(a[rt].son[R],mid+1,r,a[rt].mult,a[rt].addt);
a[rt].mult=1; a[rt].addt=0;
if(qr<=mid)modify1(a[rt].son[L],l,mid,ql,qr,k);
else if(ql>mid)modify1(a[rt].son[R],mid+1,r,ql,qr,k);
else modify1(a[rt].son[L],l,mid,ql,mid,k),modify1(a[rt].son[R],mid+1,r,mid+1,qr,k);
a[rt].sum=(a[a[rt].son[L]].sum%p+a[a[rt].son[R]].sum%p)%p;
}
}
void modify2(int rt,int l,int r,int ql,int qr,int k)
{
if(l==ql&&r==qr)
tag(rt,l,r,1,k);
else
{
int mid=(l+r)>>1;
tag(a[rt].son[L],l,mid,a[rt].mult,a[rt].addt);
tag(a[rt].son[R],mid+1,r,a[rt].mult,a[rt].addt);
a[rt].mult=1; a[rt].addt=0;
if(qr<=mid)modify2(a[rt].son[L],l,mid,ql,qr,k);
else if(ql>mid)modify2(a[rt].son[R],mid+1,r,ql,qr,k);
else modify2(a[rt].son[L],l,mid,ql,mid,k),modify2(a[rt].son[R],mid+1,r,mid+1,qr,k);
a[rt].sum=(a[a[rt].son[L]].sum%p+a[a[rt].son[R]].sum%p)%p;
}
}
long long int query(int rt,int l,int r,int ql,int qr)
{
if(l==ql&&r==qr)
return a[rt].sum%p;
else
{
int mid=(l+r)>>1;
tag(a[rt].son[L],l,mid,a[rt].mult,a[rt].addt);
tag(a[rt].son[R],mid+1,r,a[rt].mult,a[rt].addt);
a[rt].mult=1; a[rt].addt=0;
int ret=0;
if(qr<=mid)ret=query(a[rt].son[L],l,mid,ql,qr)%p;
else if(ql>mid)ret=query(a[rt].son[R],mid+1,r,ql,qr)%p;
else ret=query(a[rt].son[L],l,mid,ql,mid)%p+query(a[rt].son[R],mid+1,r,mid+1,qr)%p;
a[rt].sum=(a[a[rt].son[L]].sum%p+a[a[rt].son[R]].sum%p)%p;
return ret%p;
}
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++)
scanf("%d",&v[i]);
build(rt,1,n);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&q,&x,&y);
if(q==1)
{
scanf("%d",&k);
modify1(rt,1,n,x,y,k);
}
if(q==2)
{
scanf("%d",&k);
modify2(rt,1,n,x,y,k);
}
if(q==3)
printf("%d\n",query(rt,1,n,x,y));
}
return 0;
}