#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int (i)=(l);(i)<=(r);(i)++)
#define per(i,r,l) for(int (i)=(r);(i)>=(l);(i)--)
int P;
int a[100005];
struct node{
ll l,r,sum,lazy_tag1,lazy_tag2;
}t[400005];
void pushup(int p){
t[p].sum=t[p*2].sum+t[p*2+1].sum;
t[p].sum%=P;
return;
}
void pushdown(int p){
t[p*2].sum=(t[p*2].sum*t[p].lazy_tag1+(t[p*2].r-t[p*2].l+1)*t[p].lazy_tag2)%P;
t[p*2+1].sum=(t[p*2+1].sum*t[p].lazy_tag1+(t[p*2+1].r-t[p*2+1].l+1)*t[p].lazy_tag2)%P;
t[p*2].lazy_tag1*=t[p].lazy_tag1%P;
t[p*2].lazy_tag1%=P;
t[p*2+1].lazy_tag1*=t[p].lazy_tag1%P;
t[p*2+1].lazy_tag1%=P;
t[p*2].lazy_tag2+=t[p].lazy_tag2%P;
t[p*2].lazy_tag2%=P;
t[p*2+1].lazy_tag2+=t[p].lazy_tag2%P;
t[p*2+1].lazy_tag2%=P;
t[p].lazy_tag1=1;
t[p].lazy_tag2=0;
}
void build(int p,int l,int r){
t[p].l=l;
t[p].r=r;
t[p].lazy_tag1=1;
if(l==r){
t[p].sum=a[l]%P;
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
pushup(p);
t[p].sum%=P;
return;
}
void update1(int p,int l,int r,ll k){
if(r<t[p].l||l>t[p].r){
return;
}
if(t[p].l>=l&&t[p].r<=r){
t[p].sum*=k%P;
t[p].sum%=P;
t[p].lazy_tag1*=k%P;
t[p].lazy_tag1%=P;
t[p].lazy_tag2*=k%P;
t[p].lazy_tag2%=P;
return;
}
pushdown(p);
int mid=(l+r)/2;
if(l<=t[p*2].r)update1(p*2,l,r,k);
if(r>=t[p*2+1].l)update1(p*2+1,l,r,k);
pushup(p);
return;
}
void update2(int p,int l,int r,ll k){
if(r<t[p].l||l>t[p].r){
return;
}
if(t[p].l>=l&&t[p].r<=r){
t[p].sum+=k%P;
t[p].sum%=P;
t[p].lazy_tag2*=k%P;
t[p].lazy_tag2%=P;
return;
}
pushdown(p);
int mid=(l+r)/2;
if(l<=t[p*2].r)update1(p*2,l,r,k);
if(r>=t[p*2+1].l)update1(p*2+1,l,r,k);
pushup(p);
return;
}
ll ask(int p,int l,int r){
if(r<t[p].l||l>t[p].r){
return 0;
}
if(t[p].l>=l&&t[p].r<=r){
return t[p].sum;
}
pushdown(p);
int mid=(l+r)/2;
ll sum=0;
sum+=ask(p*2,l,r);
sum+=ask(p*2+1,l,r);
sum%=P;
return sum;
}
int main(){
int n,q;
cin>>n>>q>>P;
rep(i,1,n){
cin>>a[i];
}
build(1,1,n);
rep(i,1,q){
int opt,x,y,k;
cin>>opt>>x>>y;
if(opt<3)cin>>k;
if(opt==1){
update1(1,x,y,k);
}
else if(opt==2){
update2(1,x,y,k);
}
else{
cout<<ask(1,x,y)<<endl;
}
}
return 0;
}