#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100005
#define LL long long
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
LL n,m,p,opt,x,y,k,a[N];
template<typename _type>
class SegmentTree
{
private:
struct node
{
int l,r;
int add,mul,sum;
#define l(u) t[u].l
#define r(u) t[u].r
#define add(u) t[u].add
#define mul(u) t[u].mul
#define sum(u) t[u].sum
#define siz(u) (r(u)-l(u)+1)
}t[N*4];
void PushUp(int u)
{
sum(u)=(sum(u*2)+sum(u*2+1))%p;
}
void PushDown(int u)
{
int v;
v=u*2;
sum(v)=(sum(v)*mul(u)%p+add(u)*siz(v)%p)%p;
mul(v)=mul(v)*mul(u)%p;
add(v)=(add(v)*mul(u)%p+add(u))%p;
v=u*2+1;
sum(v)=(sum(v)*mul(u)%p+add(u)*siz(v)%p)%p;
mul(v)=mul(v)*mul(u)%p;
add(v)=(add(v)*mul(u)%p+add(u))%p;
add(u)=0;
mul(u)=1;
}
public:
void Build(int u,int l,int r,_type a[])
{
l(u)=l;
r(u)=r;
mul(u)=1;
if(l==r)
{
sum(u)=a[l];
return;
}
int mid=(l+r)>>1;
Build(u*2,l,mid,a);
Build(u*2+1,mid+1,r,a);
PushUp(u);
}
void UpDataAdd(int u,int l,int r,_type val)
{
if(l(u)>r||r(u)<l)
{
return;
}
if(l(u)>=l&&r(u)<=r)
{
sum(u)=(sum(u)+val*siz(u)%p)%p;
add(u)=(add(u)+val)%p;
return;
}
PushDown(u);
UpDataAdd(u*2,l,r,val);
UpDataAdd(u*2+1,l,r,val);
PushUp(u);
}
void UpDataMul(int u,int l,int r,_type val)
{
if(l(u)>r||r(u)<l)
{
return;
}
if(l(u)>=l&&r(u)<=r)
{
sum(u)=sum(u)*val%p;
mul(u)=mul(u)*val%p;
add(u)=add(u)*val%p;
return;
}
PushDown(u);
UpDataMul(u*2,l,r,val);
UpDataMul(u*2+1,l,r,val);
PushUp(u);
}
_type AskSum(int u,int l,int r)
{
if(l(u)>r||r(u)<l)
{
return 0;
}
if(l(u)>=l&&r(u)<=r)
{
return sum(u);
}
PushDown(u);
return (AskSum(u*2,l,r)%p+AskSum(u*2+1,l,r)%p)%p;
}
};
SegmentTree<LL> T;
int main()
{
scanf("%lld%lld%lld",&n,&m,&p);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
T.Build(1,1,n,a);
while(m--)
{
scanf("%lld",&opt);
if(opt==1)
{
scanf("%lld%lld%lld",&x,&y,&k);
T.UpDataAdd(1,x,y,k);
}
else if(opt==2)
{
scanf("%lld%lld%lld",&x,&y,&k);
T.UpDataMul(1,x,y,k);
}
else
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",T.AskSum(1,x,y)%p);
}
}
return 0;
}