#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll N=100001; ll sum[N<<2],lazy1[N<<2],lazy2[N<<2]; ll a[N]; ll n,m,p; inline ll read() { ll ans=0; char last=' ',ch=getchar(); while(ch<'0'||ch>'9') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } void build(ll cnt,ll l,ll r) { if(l==r) { sum[cnt]=a[l]%p; return; } else { ll mid=(l+r)>>1; build(cnt<<1,l,mid); build((cnt<<1)|1,mid+1,r); sum[cnt]=(sum[cnt<<1]+sum[(cnt<<1)|1])%p; } } inline bool cover(ll nl,ll nr,ll l,ll r) { return l<=nl&&r>=nr; } inline bool intersection(ll nl,ll nr,ll l,ll r) { return l<=nr&&r>=nl; } void pushdown(ll cnt,ll l,ll r) { ll mid=(l+r)>>1; lazy1[cnt<<1]=(lazy1[cnt<<1]*lazy2[cnt]+lazy1[cnt])%p; lazy1[(cnt<<1)|1]=(lazy1[(cnt<<1)|1]*lazy2[cnt]+lazy1[cnt])%p; lazy2[cnt<<1]=(lazy2[cnt<<1]*lazy2[cnt]%p)%p; lazy2[(cnt<<1)|1]=(lazy2[(cnt<<1)|1]*lazy2[cnt]%p)%p; sum[cnt<<1]=((lazy1[cnt]*(mid-l+1)%p)+(sum[cnt<<1]*lazy2[cnt]%p))%p; sum[cnt<<1|1]=((lazy1[cnt]*(r-mid)%p)+(sum[cnt<<1|1]*lazy2[cnt]%p))%p; lazy2[cnt]=1; lazy1[cnt]=0; } void add1(ll cnt,ll nl,ll nr,ll l,ll r,ll a) { if(cover(nl,nr,l,r)) { sum[cnt]=(sum[cnt]+(nr-nl+1)*a%p)%p; lazy1[cnt]=(lazy1[cnt]+a%p)%p; return ; } pushdown(cnt,nl,nr); ll mid=(nl+nr)>>1; if(intersection(nl,mid,l,r)) add1(cnt<<1,nl,mid,l,r,a); if(intersection(mid+1,nr,l,r)) add1(cnt<<1|1,mid+1,nr,l,r,a); sum[cnt]=(sum[cnt<<1]+sum[cnt<<1|1])%p; } void add2(ll cnt,ll nl,ll nr,ll l,ll r,ll a) { if(cover(nl,nr,l,r)) { sum[cnt]=(sum[cnt]*a)%p; lazy1[cnt]=(lazy1[cnt]*a)%p; lazy2[cnt]=(lazy2[cnt]*a)%p; return ; } pushdown(cnt,nl,nr); ll mid=(nl+nr)>>1; if(intersection(nl,mid,l,r)) add2(cnt<<1,nl,mid,l,r,a); if(intersection(mid+1,nr,l,r)) add2(cnt<<1|1,mid+1,nr,l,r,a); sum[cnt]=(sum[cnt<<1]+sum[cnt<<1|1])%p; } ll query(ll cnt,ll nl,ll nr,ll l,ll r) { if(cover(nl,nr,l,r)) { return sum[cnt]%p; } pushdown(cnt,nl,nr); ll mid=(nl+nr)>>1; ll ans=0; if(intersection(nl,mid,l,r)) ans+=query(cnt<<1,nl,mid,l,r)%p; if(intersection(mid+1,nr,l,r)) ans+=query(cnt<<1|1,mid+1,nr,l,r)%p; return ans; } int main() { n=read(),m=read(),p=read(); for(ll i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=N<<2;i++) lazy2[i]=1; build(1,1,n); while(m--) { ll k; k=read(); if(k==1) { ll l=read(),r=read(),t=read(); add2(1,1,n,l,r,t); } if(k==2) { ll l=read(),r=read(),t=read(); add1(1,1,n,l,r,t); } if(k==3) { ll l=read(),r=read(); printf("%lld ",query(1,1,n,l,r)%p); } } }