#include<iostream>
#include<stdio.h>
#define int long long
#define maxn 100005
using namespace std;
int a[maxn],mod;
struct node{
int l,r,lazy1,lazy2,sum;
}tree[maxn<<4];
inline void pushdown1(int i){
int lazy=tree[i].lazy1;
tree[i<<1].sum+=(tree[i<<1].r-tree[i<<1].l+1)*lazy;
tree[i<<1|1].sum+=(tree[i<<1|1].r-tree[i<<1|1].l+1)*lazy;
tree[i<<1].sum%=mod;
tree[i<<1|1].sum%=mod;
tree[i<<1].lazy1+=lazy;
tree[i<<1|1].lazy1+=lazy;
tree[i].lazy1=0;
}
inline void pushdown2(int i){
int lazy=tree[i].lazy2;
tree[i<<1].sum*=lazy;
tree[i<<1|1].sum*=lazy;
tree[i<<1].sum%=mod;
tree[i<<1|1].sum%=mod;
tree[i<<1].lazy1*=lazy;
tree[i<<1|1].lazy1*=lazy;
tree[i<<1].lazy2*=lazy;
tree[i<<1|1].lazy2*=lazy;
tree[i].lazy2=1;
}
inline void build(int i,int l,int r){
tree[i].l=l;
tree[i].r=r;
tree[i].lazy2=1;
if(l==r){
tree[i].sum=a[l];
return;
}
int mid=l+r>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
tree[i].sum%=mod;
}
inline void add(int i,int l,int r,int num){
if(tree[i].lazy2!=1)pushdown2(i);
if(tree[i].lazy1)pushdown1(i);
if(tree[i].l>=l&&tree[i].r<=r){
tree[i].lazy1+=num;
tree[i].sum+=num*(tree[i].r-tree[i].l+1);
tree[i].sum%=mod;
}
else{
int mid=tree[i].r+tree[i].l>>1;
if(mid>=l)add(i<<1,l,r,num);
if(mid<r)add(i<<1|1,l,r,num);
tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
tree[i].sum%=mod;
}
}
inline void mul(int i,int l,int r,int num){
if(tree[i].lazy2!=1)pushdown2(i);
if(tree[i].lazy1)pushdown1(i);
if(tree[i].l>=l&&tree[i].r<=r){
tree[i].lazy1*=num;
tree[i].lazy2*=num;
tree[i].sum*=num;
tree[i].sum%=mod;
}
else{
int mid=tree[i].r+tree[i].l>>1;
if(mid>=l)mul(i<<1,l,r,num);
if(mid<r)mul(i<<1|1,l,r,num);
tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
tree[i].sum%=mod;
}
}
inline int query(int i,int l,int r){
if(tree[i].lazy2!=1)pushdown2(i);
if(tree[i].lazy1)pushdown1(i);
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].sum%mod;
int mid=tree[i].r+tree[i].l>>1;
int ans=0;
if(mid>=l)ans+=query(i<<1,l,r);
if(mid<r)ans+=query(i<<1|1,l,r);
return ans%mod;
}
signed main(){
int n,m;
scanf("%lld%lld%lld",&n,&m,&mod);
//mod=0x7fffffffffffff;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
while(m--){
int op,x,y,k;
cin>>op;
if(op==1){
cin>>x>>y>>k;
if(x>y)swap(x,y);
mul(1,x,y,k);
}
else if(op==2){
cin>>x>>y>>k;
if(x>y)swap(x,y);
add(1,x,y,k);
}
else{
cin>>x>>y;
if(x>y)swap(x,y);
cout<<query(1,x,y)<<endl;
}
}
return 0;
}