#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=100010;
int n,m,mod;
struct node{
int l,r;
int sum;
int lazy1,lazy2;
}tree[4*N];
int num[N];
void build(int l,int r,int cnt){
tree[cnt].l=l; tree[cnt].r=r;
tree[cnt].lazy2=1;
if(l==r){
tree[cnt].sum=num[l]%mod;
return ;
}
int mid=(l+r)/2;
build(l,mid,2*cnt);
build(mid+1,r,2*cnt+1);
tree[cnt].sum=(tree[cnt*2].sum+tree[cnt*2+1].sum)%mod;
}
void push_down(int cnt){
tree[2*cnt].sum=(tree[2*cnt].sum+(tree[cnt].lazy1*(tree[2*cnt].r-tree[2*cnt].l+1))%mod)%mod;
tree[2*cnt+1].sum=(tree[2*cnt+1].sum+(tree[cnt].lazy1*(tree[2*cnt+1].r-tree[2*cnt+1].l+1))%mod)%mod;
tree[2*cnt].lazy2=(tree[2*cnt].lazy2*tree[cnt].lazy2)%mod;
tree[2*cnt+1].lazy2=(tree[2*cnt+1].lazy2*tree[cnt].lazy2)%mod;
tree[2*cnt].lazy1=(tree[2*cnt].lazy1*tree[cnt].lazy2+tree[cnt].lazy1)%mod;
tree[2*cnt+1].lazy1=(tree[2*cnt+1].lazy1*tree[cnt].lazy2+tree[cnt].lazy1)%mod;
tree[cnt].lazy1=0; tree[cnt].lazy2=1;
}
void change_add(int l,int r,int cnt,int k){
if(l<=tree[cnt].l&&r>=tree[cnt].r){
tree[cnt].lazy1=(tree[cnt].lazy1+k)%mod;
tree[cnt].sum=(tree[cnt].sum+k*(tree[cnt].r-tree[cnt].l+1))%mod;
return ;
}
push_down(cnt);
int mid=(tree[cnt].l+tree[cnt].r)/2;
if(mid>=l)
change_add(l,r,2*cnt,k);
if(mid<r)
change_add(l,r,2*cnt+1,k);
tree[cnt].sum=(tree[2*cnt].sum+tree[2*cnt+1].sum)%mod;
}
void change_mul(int l,int r,int cnt,int k){
if(l<=tree[cnt].l&&r>=tree[cnt].r){
tree[cnt].lazy2=(tree[cnt].lazy2*k)%mod;
tree[cnt].lazy1=(tree[cnt].lazy1*k)%mod;
tree[cnt].sum=(tree[cnt].sum*k)%mod;
return ;
}
push_down(cnt);
int mid=(tree[cnt].l+tree[cnt].r)/2;
if(mid>=l)
change_mul(l,r,2*cnt,k);
if(mid<r)
change_mul(l,r,2*cnt+1,k);
tree[cnt].sum=(tree[2*cnt].sum+tree[2*cnt+1].sum)%mod;
}
int getsum(int l,int r,int cnt){
if(l<=tree[cnt].l&&r>=tree[cnt].r)
return tree[cnt].sum;
push_down(cnt);
int mid=(tree[cnt].l+tree[cnt].r)>>1,ans=0;
if(mid>=l)
ans=(ans+getsum(l,r,2*cnt))%mod;
if(mid<r)
ans=(ans+getsum(l,r,2*cnt+1))%mod;
return ans;
}
signed main(){
cin>>n>>m>>mod;
for(int i=1;i<=n;i++)
cin>>num[i];
build(1,n,1);
while(m--){
int t; cin>>t;
if(t==1){
int x,y,k; cin>>x>>y>>k;
change_mul(x,y,1,k);
}
else if(t==2){
int x,y,k; cin>>x>>y>>k;
change_add(x,y,1,k);
}
else if(t==3){
int x,y; cin>>x>>y;
cout<<getsum(x,y,1)<<endl;;
}
}
return 0;
}