#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],tree[4*N],tagc[4*N],tagj[4*N],mod;
void func(int now,int l,int r,int fa){
tagc[now]*=tagc[fa];
tagj[now]*=tagc[fa];
tagj[now]+=tagj[fa];
tagc[now]%=mod;
tagj[now]%=mod;
tree[now]*=tagc[fa];
tree[now]+=(r-l+1)*tagj[fa];
tree[now]%=mod;
}
void push_down(int now,int l,int r){
int mid=(l+r)>>1;
func(now<<1,l,mid,now);
func(now<<1|1,mid+1,r,now);
tagc[now]=1;
tagj[now]=0;
}
void build(int now,int l,int r){
tagc[now]=1;
tagj[now]=0;
if(l==r){
tree[now]=a[l];
return;
}
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
}
void change1(int now,int l,int r,int L,int R,int k){
if(l==L&&r==R){
tagc[now]*=k;
tagc[now]%=mod;
tagj[now]*=k;
tagj[now]%=mod;
tree[now]*=k;
tree[now]%=mod;
return;
}
push_down(now,l,r);
int mid=(l+r)>>1;
if(R<=mid) change1(now<<1,l,mid,L,R,k);
else if(L>mid) change1(now<<1|1,mid+1,r,L,R,k);
else{
change1(now<<1,l,mid,L,mid,k);
change1(now<<1|1,mid+1,r,mid+1,R,k);
}
}
void change2(int now,int l,int r,int L,int R,int k){
if(l==L&&r==R){
tagj[now]+=k;
tagj[now]%=mod;
tree[now]+=(r-l+1)*k;
tree[now]%=mod;
return;
}
push_down(now,l,r);
int mid=(l+r)>>1;
if(R<=mid) change2(now<<1,l,mid,L,R,k);
else if(L>mid) change2(now<<1|1,mid+1,r,L,R,k);
else{
change2(now<<1,l,mid,L,mid,k);
change2(now<<1|1,mid+1,r,mid+1,R,k);
}
}
int answer(int now,int l,int r,int L,int R){
if(l==L&&r==R) return tree[now];
push_down(now,l,r);
int mid=(l+r)>>1;
if(R<=mid) return answer(now<<1,l,mid,L,R);
else if(L>mid) return answer(now<<1|1,mid+1,r,L,R);
else return (answer(now<<1,l,mid,L,mid)+answer(now<<1|1,mid+1,r,mid+1,R))%mod;
}
signed main(){
int n,m;
cin>>n>>m>>mod;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(m--){
int opt;
cin>>opt;
if(opt==1){
int x,y,k;
cin>>x>>y>>k;
change1(1,1,n,x,y,k);
}
else if(opt==2){
int x,y,k;
cin>>x>>y>>k;
change2(1,1,n,x,y,k);
}
else{
int x,y;
cin>>x>>y;
cout<<answer(1,1,n,x,y)<<endl;
}
}
return 0;
}