#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int n,q,m,a[N];
struct node{
int l,r;
long long val,tag;
long long mul;
}o[N*4+2];
void push_up(int u){
o[u].val=(o[u*2].val+o[u*2+1].val)%m;
return;
}
void push_down(int u){
o[u*2].val=(o[u*2].val*o[u].mul+o[u].tag*(o[u*2].r-o[u*2].l+1))%m;
o[u*2+1].val=(o[u*2+1].val*o[u].mul+o[u].tag*(o[u*2+1].r-o[u*2+1].l+1))%m;
o[u*2].mul=(o[u*2].mul*o[u].mul)%m;
o[u*2+1].mul=(o[u*2+1].mul*o[u].mul)%m;
o[u*2].tag=(o[u].tag+o[u].mul*o[u*2].tag)%m;
o[u*2+1].tag=(o[u].tag+o[u].mul*o[u*2+1].tag)%m;
o[u].tag=0;
o[u].mul=1;
return;
}
void build(int u,int l,int r){
o[u].l=l,o[u].r=r;
o[u].mul=1;
if(l==r){
o[u].val=a[u]%m;
return;
}
int mid=(l+r)>>1;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
push_up(u);
return;
}
void add_jia(int u,int l,int r,int k){
if(l<=o[u].l && o[u].r<=r){
o[u].val=(o[u].val+(o[u].r-o[u].l+1)*k)%m;
o[u].tag=(o[u].tag+k)%m;
return;
}
push_down(u);
int mid=(o[u].l+o[u].r)>>1;
if(l<=mid) add_jia(u*2,l,r,k);
if(r>mid) add_jia(u*2+1,l,r,k);
push_up(u);
return;
}
void add_che(int u,int l,int r,int k){
if(l<=o[u].l && o[u].r<=r){
o[u].val=(o[u].val*k)%m;
o[u].mul=(o[u].mul*k)%m;
o[u].tag=(o[u].tag*k)%m;
return;
}
push_down(u);
int mid=(o[u].l+o[u].r)>>1;
if(l<=mid) add_che(u*2,l,r,k);
if(mid<r) add_che(u*2+1,l,r,k);
push_up(u);
return;
}
long long query(int u,int l,int r){
if(l<=o[u].l && o[u].r<=r){
return o[u].val%m;
}
push_down(u);
long long ans=0;
int mid=(o[u].l+o[u].r)>>1;
if(l<=mid) ans+=query(u*2,l,r);
if(mid<r) ans+=query(u*2+1,l,r);
return ans%m;
}
signed main(){
cin>>n>>q>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=q;i++){
int ch,x,y;
cin>>ch>>x>>y;
if(ch==1){
int k;
cin>>k;
add_che(1,x,y,k);
}
else if(ch==2){
int k;
cin>>k;
add_jia(1,x,y,k);
}
else if(ch==3){
cout<<query(1,x,y)<<endl;
}
}
return 0;
}