#include <bits/stdc++.h>
#define int long long
#define MAXN 100005
using namespace std;
struct SegmentTree{
int l,r,sum,add,mul,len;
}t[MAXN*4];
int a[MAXN],n,m,p;
void pushup(int x){
t[x].sum=(t[x*2].sum+t[x*2+1].sum)%p;
}
void build(int x,int l,int r){
t[x].l=l;
t[x].r=r;
t[x].len=r-l+1;
t[x].mul=1;
//cout<<"x="<<x<<" l="<<l<<" r="<<r<<endl;
if(l==r){
t[x].sum=a[l]%p;
return ;
}
int mid=(l+r)>>1;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
pushup(x);
}
void pushdown(int x){
t[x*2].sum=(t[x].mul*t[x*2].sum+(t[x*2].len*t[x].add)%p)%p;
t[x*2+1].sum=(t[x].mul*t[x*2+1].sum+(t[x*2+1].len*t[x].add)%p)%p;
t[x*2].mul=(t[x*2].mul*t[x].mul)%p;
t[x*2+1].mul=(t[x*2+1].mul*t[x].mul)%p;
t[x*2].add=(t[x*2].add*t[x].mul+t[x].add)%p;
t[x*2+1].add=(t[x*2+1].add*t[x].mul+t[x].add)%p;
//cout<<t[x*2].add<<' '<<t[x*2].mul<<"\n"<<t[x*2+1].add<<' '<<t[x*2+1].mul<<"\n";
t[x].add=0;
t[x].mul=1;
}
int query(int x,int l,int r){
//cout<<"x="<<x<<" l="<<l<<" r="<<r<<endl;
int L=t[x].l,R=t[x].r;
if(l<=L&&r>=R)return t[x].sum;
int mid=(L+R)>>1,val=0;
pushdown(x);
if(l<=mid)val=(val+query(x*2,l,r))%p;
if(r>mid)val=(val+query(x*2+1,l,r))%p;
return val;
}
void changeadd(int x,int l,int r,int k){
int L=t[x].l,R=t[x].r;
if(l<=L&&R<=r){
t[x].sum=(t[x].sum+k*t[x].len)%p;
t[x].add=(k+t[x].add)%p;
return ;
}
pushdown(x);
int mid=(L+R)>>1;
if(l<=mid)changeadd(x*2,l,r,k);
if(r>mid)changeadd(x*2+1,l,r,k);
pushup(x);
//cout<<"x="<<x<<" sum="<<t[x].sum<<"\n";
}
void changemul(int x,int l,int r,int k){
int L=t[x].l,R=t[x].r;
if(l<=L&&R<=r){
t[x].add=(t[x].add*k)%p;
t[x].mul=(t[x].mul*k)%p;
t[x].sum=(t[x].sum*k)%p;
return ;
}
pushdown(x);
int mid=(L+R)>>1;
if(l<=mid)changeadd(x*2,l,r,k);
if(r>mid)changeadd(x*2+1,l,r,k);
pushup(x);
//cout<<"x="<<x<<" sum="<<t[x].sum<<"\n";
}
signed main(){
scanf("%lld%lld%lld",&n,&m,&p);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
build(1,1,n);
while(m--){
int opr;
scanf("%lld",&opr);
if(opr==1){
int x,y,k;
scanf("%lld%lld%lld",&x,&y,&k);
changemul(1,x,y,k);
}
if(opr==2){
int x,y,k;
scanf("%lld%lld%lld",&x,&y,&k);
changeadd(1,x,y,k);
}
if(opr==3){
int x,y;
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,x,y));
}
}
return 0;
}
谢谢!