#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5;
ll n,m,a,x,y,k,ans[N],mod;
struct edge{
ll l,r;
ll sum;
ll lz;
ll add;
}e[N<<2];
inline ll ls(ll x){
return x<<1;
}
inline ll rs(ll x){
return x<<1|1;
}
void build(ll k,ll l,ll r){
e[k].add=1;
e[k].l=l;
e[k].r=r;
if(l==r){
e[k].sum=ans[l];
return;
}
ll mid=(l+r)/2;
build(ls(k),l,mid);
build(rs(k),mid+1,r);
e[k].sum=(e[k*2].sum+e[k*2+1].sum)%mod;
}
void pushdown(ll u){
if(e[u].lz){
e[u*2].lz+=e[u].lz;
e[u*2+1].lz+=e[u].lz;
e[u*2].sum+=e[u].lz*(e[u*2].r-e[u*2].l+1);
e[u*2+1].sum+=e[u].lz*(e[u*2+1].r-e[u*2+1].l+1);
e[u].lz=0;
}
if(e[u].add!=1){
e[u*2].add=e[u].add;
e[u*2+1].add=e[u].add;
e[u*2].sum*=e[u].add;
e[u*2].sum%=mod;
e[u*2+1].sum*=e[u].add;
e[u*2+1].sum%=mod;
e[u].add=1;
}
}
void pushup(ll u){
e[u].sum=e[u*2].sum+e[u*2+1].sum;
}
void update(ll l,ll r,ll u,ll x,ll y)
{
if(e[u].r==0||e[u].l==0) return;
if(l<=e[u].l&&e[u].r<=r){
if(y==1){
e[u].add=x;
e[u].sum*=x;
e[u].sum%=mod;
}
else{
e[u].lz+=x;
e[u].sum+=x*(e[u].r-e[u].l+1);
e[u].sum%=mod;
}
return;
}
ll mid=(e[u].r+e[u].l)>>1;
pushdown(u);
if(l<=mid) update(l,r,u*2,x,y);
if(r>mid) update(l,r,u*2+1,x,y);
pushup(u);
}
ll query(ll u,ll l,ll r,ll nl,ll nr){
ll res=0;
if(e[u].l>r||e[u].r<l) return 0;
if(e[u].l>=l&&e[u].r<=r) return e[u].sum%mod;
ll mid=(nl+nr)>>1;
pushdown(u);
if(l<=mid) res+=query(ls(u),l,r,nl,mid)%mod;
if(y>mid) res+=query(rs(u),l,r,mid+1,nr)%mod;
return res%mod;
}
int main(){
scanf("%d%d%d",&n,&m,&mod);
for(ll i=1;i<=n;i++) scanf("%d",&ans[i]);
build(1,1,n);
for(ll i=1;i<=m;i++){
scanf("%d",&a);
if(a==1||a==2){
scanf("%d%d%d",&x,&y,&k);
update(x,y,1,k,a);
}
else{
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,x,y,1,n));
}
}
return 0;
}