#include<bits/stdc++.h>
#define ll long long
const int N=1e5+10;
using namespace std;
int n,m,p;
int a[N];
struct node{
int l,r;
ll lazy,sum,mul;
}tr[N<<2];
void pushup(int u){
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}//维护树中的sum值
void build(int u,int aa,int bb){
tr[u].l=aa;
tr[u].r=bb;
if(aa==bb) {
tr[u].sum=a[aa];
return;
}
tr[u].lazy=0;
tr[u].mul=1;
int mid=(aa+bb)>>1;
build(u<<1,aa,mid);
build(u<<1|1,mid+1,bb);
pushup(u);//计算u为根的树的sum值
return;
}
void pushdown(int u){//懒标记传下去
tr[u<<1].sum=(tr[u<<1].sum*tr[u].mul+(tr[u<<1].r-tr[u<<1].l+1)*tr[u].lazy)%p;//因为只有含在目标区间内的区间才会被标记
tr[u<<1|1].sum=(tr[u<<1|1].sum*tr[u].mul+(tr[u<<1|1].r -tr[u<<1|1].l+1)*tr[u].lazy)%p;
tr[u<<1].lazy=(tr[u<<1].lazy+tr[u].lazy)%p;
tr[u<<1|1].lazy=(tr[u<<1|1].lazy+tr[u].lazy)%p;
tr[u<<1].mul =(tr[u<<1].mul*tr[u].mul )%p;
tr[u<<1|1].mul =(tr[u<<1|1].mul*tr[u].mul )%p;
tr[u].lazy=0;
tr[u].mul=1;
return;
}
void multiply(int u,int aa,int bb,ll k){
if(aa<=tr[u].l&&bb>=tr[u].r) {
tr[u].sum=(tr[u].sum*k)%p;
tr[u].lazy=(tr[u].lazy*k)%p;
tr[u].mul=(tr[u].mul*k)%p;
return;
}
pushdown(u);
int mid=(tr[u].l+tr[u].r)/2;
if(aa<=mid) multiply(u<<1,aa,bb,k);
if(bb>mid) multiply(u<<1|1,aa,bb,k);
pushup(u);
return;
}
void modify(int u,int aa,int bb,ll k){ //区间加
if(aa<=tr[u].l&&bb>=tr[u].r){
tr[u].lazy=(tr[u].lazy+k)%p;
tr[u].sum=(tr[u].sum+(tr[u].r-tr[u].l+1)*k)%p;
return;
}
pushdown(u);
int mid=(tr[u].l+tr[u].r)>>1;
if(aa<=mid) modify(u<<1,aa,bb,k);
if(bb>mid) modify(u<<1|1,aa,bb,k);
pushup(u);
return;
}
ll query(int u,int aa,int bb){//区间查询
if(aa<=tr[u].l&&bb>=tr[u].r) return tr[u].sum;
pushdown(u);
int mid=(tr[u].l+tr[u].r)>>1;
ll ans=0;
if(aa<=mid) ans=(ans+query(u<<1,aa,bb))%p;
if(bb>mid) ans=(ans+query(u<<1|1,aa,bb))%p;
return ans%p;
}
int main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int aaa,bbb,ccc,ddd;
cin>>n>>m>>p;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
for(int i=1;i<=m;i++){
cin>>aaa;
if(aaa==1){
cin>>bbb>>ccc>>ddd;
multiply(1,bbb,ccc,ddd);
}
if(aaa==2){
cin>>bbb>>ccc>>ddd;
modify(1,bbb,ccc,ddd);
}
if(aaa==3){
cin>>bbb>>ccc;
cout<<query(1,bbb,ccc)<<'\n';
}
}
return 0;
}