#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node
{int su,mu,ad,dx;}a[400010];
int n,m,mod;
int read()
{
char c=getchar();int x=0;
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
void build(int u,int l,int r)
{
a[u].dx=r-l+1;
if(l==r){a[u].su=read()%mod,a[u].mu=1;return;}
int mid=(l+r)>>1,lu=u*2,ru=u*2+1;
build(lu,l,mid);
build(ru,mid+1,r);
a[u].su=(a[lu].su+a[ru].su)%mod;
a[u].mu=1;
}
void pushdown(int u,int l,int r)
{
int lu=u*2,ru=u*2+1;
if(l==r) return ;
a[lu].su=a[lu].su*a[u].mu+a[u].ad*a[lu].dx;
a[ru].su=a[ru].su*a[u].mu+a[u].ad*a[ru].dx;
a[lu].su%=mod,a[ru].su%=mod;
a[lu].ad=a[lu].ad*a[u].mu+a[u].ad;
a[ru].ad=a[ru].ad*a[u].mu+a[u].ad;
a[lu].ad%=mod,a[ru].ad%=mod;
a[lu].mu=a[lu].mu*a[u].mu;
a[ru].mu=a[ru].mu*a[u].mu;
a[lu].mu%=mod,a[ru].mu%=mod;
a[u].mu=1,a[u].ad=0;
}
void add(int l,int r,int s,int e,int u,int x)
{
pushdown(u,s,e);
if(s>=l&&e<=r)
{
a[u].su=(a[u].su+x*a[u].dx)%mod;
a[u].ad=(a[u].ad+x)%mod;
return;
}
int mid=(s+e)>>1,lu=u*2,ru=u*2+1;
if(l<=mid) add(l,r,s,mid,lu,x);
if(r>=mid+1) add(l,r,mid+1,e,ru,x);
a[u].su=(a[lu].su+a[ru].su)%mod;
}
void mul(int l,int r,int s,int e,int u,int x)
{
pushdown(u,s,e);
if(s>=l&&e<=r)
{
a[u].su=(a[u].su*x)%mod;
a[u].mu=(a[u].mu*x)%mod;
a[u].ad=(a[u].ad*x)%mod;
return;
}
int mid=(s+e)>>1,lu=u*2,ru=u*2+1;
if(l<=mid) mul(l,r,s,mid,lu,x);
if(r>=mid+1) mul(l,r,mid+1,e,ru,x);
a[u].su=(a[lu].su+a[ru].su)%mod;
}
int query(int l,int r,int s,int e,int u)
{
pushdown(u,s,e);
if(s>=l&&e<=r) return a[u].su;
int mid=(s+e)>>1,lu=u*2,ru=u*2+1,sum=0;
if(l<=mid) sum=(sum+query(l,r,s,mid,lu))%mod;
if(r>=mid+1) sum=(sum+query(l,r,mid+1,r,ru))%mod;
return sum;
}
signed main()
{
n=read(),m=read(),mod=read();
build(1,1,n);
for(int i=1,op,x,y,k;i<=m;i++)
{
op=read(),x=read(),y=read();
if(op==1) k=read(),mul(x,y,1,n,1,k);
else if(op==2) k=read(),add(x,y,1,n,1,k);
else printf("%lld\n",query(x,y,1,n,1));
}
return 0;
}