#include<bits/stdc++.h>
#define maxn 100010
using namespace std;
int a[maxn],p;
struct T
{
long long mul,add,sum;
int l,r;
}s[maxn*4];
void gx(int rt)
{
s[rt].sum=(s[rt<<1].sum+s[rt<<1|1].sum)%p;
return;
}
void xtbj(int rt)
{
s[rt<<1].sum=(s[rt<<1].sum*s[rt].mul+s[rt].add*(s[rt<<1].r-s[rt<<1].l+1))%p;
s[rt<<1|1].sum=(s[rt<<1|1].sum*s[rt].mul+s[rt].add*(s[rt<<1|1].r-s[rt<<1|1].l+1))%p;
s[rt<<1].mul=(s[rt<<1].mul*s[rt].mul)%p;
s[rt<<1|1].mul=(s[rt<<1|1].mul*s[rt].mul)%p;
s[rt<<1].add=(s[rt<<1].add*s[rt].mul+s[rt].add)%p;
s[rt<<1|1].add=(s[rt<<1|1].add*s[rt].mul+s[rt].add)%p;
s[rt].add=0;
s[rt].mul=1;
return;
}
void jl(int rt,int l,int r)
{
s[rt].mul=1;
s[rt].l=l;
s[rt].r=r;
if(l==r)
{
s[rt].sum=a[l]%p;
return;
}
int m=(l+r)>>1;
jl(rt<<1,l,m);
jl(rt<<1|1,m+1,r);
gx(rt);
return;
}
void qjxg1(int rt,int L,int R,int c)
{
if(L<=s[rt].l&&s[rt].r<=R)
{
s[rt].sum=(s[rt].sum*c)%p;
s[rt].add=(s[rt].add*c)%p;
s[rt].mul=(s[rt].mul*c)%p;
return;
}
xtbj(rt);
long long m=(s[rt].l+s[rt].r)>>1;
if(L<=m)qjxg1(rt<<1,L,R,c);
if(R>m)qjxg1(rt<<1|1,L,R,c);
gx(rt);
return;
}
void qjxg2(int rt,int L,int R,int c)
{
if(L<=s[rt].l&&s[rt].r<=R)
{
s[rt].sum=(s[rt].sum+c*(s[rt].r-s[rt].l+1))%p;
s[rt].add=(s[rt].add+c)%p;
return;
}
xtbj(rt);
int m=(s[rt].l+s[rt].r)>>1;
if(L<=m)qjxg2(rt<<1,L,R,c);
if(R>m)qjxg2(rt<<1|1,L,R,c);
gx(rt);
return;
}
long long qjqh(int rt,int L,int R)
{
if(L<=s[rt].l&&s[rt].r<=R)
{
return s[rt].sum;
}
xtbj(rt);
long long ans=0;
int m=(s[rt].l+s[rt].r)>>1;
if(L<=m)ans=(ans+qjqh(L,R,rt<<1))%p;
if(R>m)ans=(ans+qjqh(L,R,rt<<1|1))%p;
return ans;
}
int n,m;
int main()
{
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
jl(1,1,n);
for(int i=1;i<=m;i++)
{
int c,x,k,y;
scanf("%d%d%d",&c,&x,&y);
if(c==1)
{
scanf("%d",&k);
qjxg1(1,x,y,k);
}
if(c==2)
{
scanf("%d",&k);
qjxg2(1,x,y,k);
}
if(c==3)
{
printf("%lld\n",qjqh(1,x,y));
}
}
return 0;
}