#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1000010;
int p[N],n,m,mod;
struct node
{
int l,r,sum,lazyadd,lazymul;
}a[N];
void update(int k)
{
if(a[k].l==a[k].r)return;
a[k].sum=(a[k*2].sum+a[k*2+1].sum)%mod;
return;
}
void build(int k,int l,int r)
{
a[k].l=l;a[k].r=r;a[k].lazymul=1;a[k].lazyadd=0;
if(l==r)
{
a[k].sum=p[l]%mod;
return;
}
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
update(k);
}
void down(int k)
{
if(a[k].l==a[k].r)return;
a[k*2].sum=(a[k].lazymul*a[k*2].sum+(a[k].lazyadd*(a[k*2].r-a[k*2].l+1))%mod)%mod;
a[k*2+1].sum=(a[k].lazymul*a[k*2+1].sum+(a[k].lazyadd*(a[k*2+1].r-a[k*2+1].l+1))%mod)%mod;
a[k*2].lazymul*=a[k].lazymul;a[k*2].lazymul%=mod;
a[k*2+1].lazymul*=a[k].lazymul;a[k*2+1].lazymul%=mod;
a[k*2].lazyadd*=a[k].lazymul;a[k*2].lazyadd+=a[k].lazyadd;a[k*2].lazymul%=mod;
a[k*2+1].lazyadd*=a[k].lazymul;a[k*2+1].lazyadd+=a[k].lazyadd;a[k*2+1].lazymul%=mod;
a[k].lazymul=1;
a[k].lazyadd=0;
update(k);
}
void add(int k,int l,int r,int x)
{
if(l>r)return;
if(a[k].l>=l&&a[k].r<=r)
{
a[k].sum+=(a[k].r-a[k].l+1)*x;a[k].sum%=mod;
a[k].lazyadd+=x;a[k].lazyadd%=mod;
return;
}
down(k);
int mid=(a[k].l+a[k].r)/2;
if(r>mid) add(k*2+1,l,r,x);
if(l<=mid) add(k*2,l,r,x);
update(k);
}
void mul(int k,int l,int r,int x)
{
if(l>r)return;
if(a[k].l>=l&&a[k].r<=r)
{
a[k].sum*=x;a[k].sum%=mod;
a[k].lazymul*=x;a[k].lazymul%=mod;
a[k].lazyadd*=x;a[k].lazyadd%=mod;
return;
}
down(k);
int mid=(a[k].l+a[k].r)/2;
if(r>mid) mul(k*2+1,l,r,x);
if(l<=mid) mul(k*2,l,r,x);
update(k);
}
int query(int k,int l,int r)
{
if(a[k].l>=l&&a[k].r<=r)return a[k].sum;
down(k);
int mid=(a[k].l+a[k].r)/2,ret=0;
if(l<=mid){ret+=query(k*2,l,r);ret%=mod;}
if(r>mid){ret+=query(k*2+1,l,r);ret%=mod;}
return ret;
}
signed main()
{
scanf("%lld%lld%lld",&n,&m,&mod);
for(int i=1;i<=n;i++)
{
scanf("%lld",&p[i]);
p[i]%=mod;
}
build(1,1,n);
while(m--)
{
int opt,x,y,k;
scanf("%lld",&opt);
if(opt==1)
{
scanf("%lld%lld%lld",&x,&y,&k);
mul(1,x,y,k);
}
if(opt==2)
{
scanf("%lld%lld%lld",&x,&y,&k);
add(1,x,y,k);
}
if(opt==3)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,x,y));
}
}
return 0;
}