#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=100001;
ll sum[N<<2],lazy1[N<<2],lazy2[N<<2];
ll a[N];
ll n,m,p;
inline ll read()
{
ll ans=0;
char last=' ',ch=getchar();
while(ch<'0'||ch>'9') last=ch,ch=getchar();
while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
if(last=='-') ans=-ans;
return ans;
}
void build(ll cnt,ll l,ll r)
{
if(l==r)
{
sum[cnt]=a[l]%p;
return;
}
else
{
ll mid=(l+r)>>1;
build(cnt<<1,l,mid);
build((cnt<<1)|1,mid+1,r);
sum[cnt]=(sum[cnt<<1]+sum[(cnt<<1)|1])%p;
}
}
inline bool cover(ll nl,ll nr,ll l,ll r)
{
return l<=nl&&r>=nr;
}
inline bool intersection(ll nl,ll nr,ll l,ll r)
{
return l<=nr&&r>=nl;
}
void pushdown(ll cnt,ll l,ll r)
{
ll mid=(l+r)>>1;
lazy1[cnt<<1]=(lazy1[cnt<<1]*lazy2[cnt]+lazy1[cnt])%p;
lazy1[(cnt<<1)|1]=(lazy1[(cnt<<1)|1]*lazy2[cnt]+lazy1[cnt])%p;
lazy2[cnt<<1]=(lazy2[cnt<<1]*lazy2[cnt]%p)%p;
lazy2[(cnt<<1)|1]=(lazy2[(cnt<<1)|1]*lazy2[cnt]%p)%p;
sum[cnt<<1]=((lazy1[cnt]*(mid-l+1)%p)+(sum[cnt<<1]*lazy2[cnt]%p))%p;
sum[cnt<<1|1]=((lazy1[cnt]*(r-mid)%p)+(sum[cnt<<1|1]*lazy2[cnt]%p))%p;
lazy2[cnt]=1;
lazy1[cnt]=0;
}
void add1(ll cnt,ll nl,ll nr,ll l,ll r,ll a)
{
if(cover(nl,nr,l,r))
{
sum[cnt]=(sum[cnt]+(nr-nl+1)*a%p)%p;
lazy1[cnt]=(lazy1[cnt]+a%p)%p;
return ;
}
pushdown(cnt,nl,nr);
ll mid=(nl+nr)>>1;
if(intersection(nl,mid,l,r)) add1(cnt<<1,nl,mid,l,r,a);
if(intersection(mid+1,nr,l,r)) add1(cnt<<1|1,mid+1,nr,l,r,a);
sum[cnt]=(sum[cnt<<1]+sum[cnt<<1|1])%p;
}
void add2(ll cnt,ll nl,ll nr,ll l,ll r,ll a)
{
if(cover(nl,nr,l,r))
{
sum[cnt]=(sum[cnt]*a)%p;
lazy1[cnt]=(lazy1[cnt]*a)%p;
lazy2[cnt]=(lazy2[cnt]*a)%p;
return ;
}
pushdown(cnt,nl,nr);
ll mid=(nl+nr)>>1;
if(intersection(nl,mid,l,r)) add2(cnt<<1,nl,mid,l,r,a);
if(intersection(mid+1,nr,l,r)) add2(cnt<<1|1,mid+1,nr,l,r,a);
sum[cnt]=(sum[cnt<<1]+sum[cnt<<1|1])%p;
}
ll query(ll cnt,ll nl,ll nr,ll l,ll r)
{
if(cover(nl,nr,l,r))
{
return sum[cnt]%p;
}
pushdown(cnt,nl,nr);
ll mid=(nl+nr)>>1;
ll ans=0;
if(intersection(nl,mid,l,r)) ans+=query(cnt<<1,nl,mid,l,r)%p;
if(intersection(mid+1,nr,l,r)) ans+=query(cnt<<1|1,mid+1,nr,l,r)%p;
return ans;
}
int main()
{
n=read(),m=read(),p=read();
for(ll i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<=N<<2;i++) lazy2[i]=1;
build(1,1,n);
while(m--)
{
ll k;
k=read();
if(k==1)
{
ll l=read(),r=read(),t=read();
add2(1,1,n,l,r,t);
}
if(k==2)
{
ll l=read(),r=read(),t=read();
add1(1,1,n,l,r,t);
}
if(k==3)
{
ll l=read(),r=read();
printf("%lld\n",query(1,1,n,l,r)%p);
}
}
}