#include<iostream>
#include<cstdio>
#define N 100010
using namespace std;
int n,m,mod,q[N];
struct Node{
int l,r;long long sum,lazy1,lazy2;
} s[N*4];
void re(int &x)
{
x=0;char i=getchar();
while(i<'0'||i>'9') i=getchar();
while(i>='0'&&i<='9') x=(x<<1)+(x<<3)+i-'0',i=getchar();
}
void build(int p,int l,int r)
{
s[p].l=l;s[p].r=r;
if(l==r) {s[p].sum=q[l]%mod;return;}
int mid=(l+r)/2;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
s[p].sum=(s[p<<1].sum+s[p<<1|1].sum)%mod;
}
void pushdown1(int p)
{
s[p<<1].lazy1=(s[p<<1].lazy1+s[p].lazy1)%mod;
s[p<<1|1].lazy1=(s[p<<1|1].lazy1+s[p].lazy1)%mod;
s[p<<1].sum=(s[p<<1].sum+s[p].lazy1*(s[p<<1].r-s[p<<1].l+1))%mod;
s[p<<1|1].sum=(s[p<<1|1].sum+s[p].lazy1*(s[p<<1|1].r-s[p<<1|1].l+1))%mod;
s[p].lazy1=0;
}
void pushdown2(int p)
{
s[p<<1].lazy2=(s[p<<1].lazy2+s[p].lazy2)%mod;
s[p<<1].lazy1=(s[p<<1].lazy1*s[p].lazy2)%mod;
s[p<<1|1].lazy2=(s[p<<1|1].lazy2+s[p].lazy2)%mod;
s[p<<1|1].lazy1=(s[p<<1|1].lazy1*s[p].lazy2)%mod;
s[p<<1].sum=(s[p<<1].sum*s[p].lazy2)%mod;
s[p<<1|1].sum=(s[p<<1|1].sum*s[p].lazy2)%mod;
s[p].lazy2=0;
}
void update(int p,int l,int r,int k,int flag)
{
if(l<=s[p].l&&r>=s[p].r)
{
if(flag==2)
{
s[p].lazy1=(s[p].lazy1+k)%mod;
s[p].sum=(s[p].sum+k*(s[p].r-s[p].l+1))%mod;
}
else
{
s[p].lazy2=(s[p].lazy2+k)%mod;
s[p].lazy1=(s[p].lazy1*k)%mod;
s[p].sum=(s[p].sum*k)%mod;
}
return;
}
if(s[p].lazy2) pushdown2(p);
if(s[p].lazy1) pushdown1(p);
int mid=(s[p].l+s[p].r)/2;
if(l<=mid) update(p<<1,l,r,k,flag);
if(r>mid) update(p<<1|1,l,r,k,flag);
s[p].sum=(s[p<<1].sum+s[p<<1|1].sum)%mod;
}
long long query(int p,int l,int r)
{
if(l<=s[p].l&&r>=s[p].r)
{return s[p].sum;}
if(s[p].lazy2) pushdown2(p);
if(s[p].lazy1) pushdown1(p);
int mid=(s[p].l+s[p].r)/2;long long ans=0;
if(l<=mid) ans+=query(p<<1,l,r);
if(r>mid) ans+=query(p<<1|1,l,r);
return ans;
}
int main()
{
re(n);re(m);re(mod);
for(int i=1;i<=n;i++) re(q[i]);
build(1,1,n);
int f,x,y,k;
for(int i=1;i<=m;i++)
{
re(f);
if(f==1)
{
re(x);re(y);re(k);
update(1,x,y,k,1);
}
if(f==2)
{
re(x);re(y);re(k);
update(1,x,y,k,2);
}
if(f==3)
{
re(x);re(y);
printf("%lld\n",query(1,x,y)%mod);
}
}
return 0;
}