#include<bits/stdc++.h>
#define ll long long
#define maxn 100005
#define ls (now<<1)
#define rs ((now<<1)|1)
#define mid ((l+r)>>1)
using namespace std;
ll sum[maxn<<2],lazy1[maxn<<2],lazy2[maxn<<2];
ll modd;
void pd(int now,ll l,ll r)
{
sum[ls]=(((sum[ls]*lazy2[now])%modd)+lazy1[now]*(l-r+1))%modd;
sum[rs]=(((sum[rs]*lazy2[now])%modd)+lazy1[now]*(r-mid))%modd;
lazy1[ls]=(lazy1[ls]*lazy2[now]+lazy1[now]); lazy2[ls]*=lazy2[now];
lazy1[rs]=(lazy1[rs]*lazy2[now]+lazy1[now]); lazy2[rs]*=lazy2[now];
lazy1[now]=0; lazy2[now]=1;
}
void up(int now) {sum[now]=sum[ls]+sum[rs];sum[now]%=modd;}
void modify(int now,ll l,ll r,ll L,ll R,ll k,ll v)
{
if(L<=l&&r<=R) {sum[now]=(((sum[now]*v)%modd)+k*(r-l+1))%modd; lazy1[now]=((lazy1[now]*v)+k)%modd; lazy2[now]=(lazy2[now]*v)%modd; return;}
//if(lazy1[now]||lazy2[now]>1)
pd(now,l,r);
if(L<=mid) modify(ls,l,mid,L,R,k,v);
if(mid+1<=R) modify(rs,mid+1,r,L,R,k,v);
up(now);
return;
}
ll query(int now,int l,int r,int L,int R)
{
if(L<=l&&r<=R) return sum[now];
//if(lazy1[now]||lazy2[now]>1)
pd(now,l,r);
ll ret=0;
if(L<=mid) ret=(ret+query(ls,l,mid,L,R))%modd;
if(mid+1<=R) ret=(ret+query(rs,mid+1,r,L,R))%modd;
return ret;
}
void build(int now,ll l,ll r)
{
lazy2[now]=1;
if(l==r) {cin>>sum[now]; return;}
build(ls,l,mid); build(rs,mid+1,r);
up(now);
}
int n,m;
int main()
{
cin>>n>>m>>modd;
build(1,1,n);
while(m--)
{
int op;
cin>>op;
if(op==1)
{
int x,y,k;
cin>>x>>y>>k;
modify(1,1,n,x,y,0,k);
}
else if(op==2)
{
int x,y,k;
cin>>x>>y>>k;
modify(1,1,n,x,y,k,1);
}
else if(op==3)
{
int x,y;
cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
}
//cout<<query(1,1,n,1,n)<<endl;
}
return 0;
}