#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,q,m,a[100005],tree[400005],lazy1[400005],lazy2[400005];
void push_up(int id){
tree[id]=tree[id*2]+tree[id*2+1];
tree[id]%=m;
}
void push_down(int id,int l,int r){
if(lazy2[id]!=1){
tree[id*2]*=lazy2[id];
lazy1[id*2]*=lazy2[id];
lazy2[id*2]*=lazy2[id];
tree[id*2+1]*=lazy2[id];
lazy1[id*2+1]*=lazy2[id];
lazy2[id*2+1]*=lazy2[id];
lazy2[id]=1;
}
if(lazy1[id]!=0){
int mid=(l+r)/2;
tree[id*2]+=lazy1[id]*(mid-l+1);
lazy1[id*2]+=lazy1[id];
tree[id*2+1]=lazy1[id]*(r-mid);
lazy1[id*2+1]+=lazy1[id];
lazy1[id]=0;
}
lazy1[id*2]%=m;
lazy2[id*2]%=m;
lazy1[id*2+1]%=m;
lazy2[id*2+1]%=m;
tree[id*2]%=m;
tree[id*2+1]%=m;
}
void build(int id,int l,int r){
if(l==r){
tree[id]=a[l];
tree[id]%=m;
return;
}
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
push_up(id);
lazy2[id]=1;
}
void add(int id,int s,int t,int l,int r,int num){
if(s<=l&&r<=t){
tree[id]+=num*(r-l+1);
tree[id]%=m;
lazy1[id]+=num;
return ;
}
int mid=(l+r)/2;
push_down(id,l,r);
if(s<=mid) add(id*2,s,t,l,mid,num);
if(t>mid) add(id*2+1,s,t,mid+1,r,num);
push_up(id);
}
void mul(int id,int s,int t,int l,int r,int num){
if(s<=l&&r<=t){
tree[id]*=num;
tree[id]%=m;
lazy2[id]*=num;
lazy1[id]*=num;
return ;
}
int mid=(l+r)/2;
push_down(id,l,r);
if(s<=mid) mul(id*2,s,t,l,mid,num);
if(t>mid) mul(id*2+1,s,t,mid+1,r,num);
push_up(id);
}
int find(int id,int s,int t,int l,int r){
int ans=0;
if(s<=l&&r<=t){
return tree[id]%m;
}
int mid=(l+r)/2;
push_down(id,l,r);
if(s<=mid) ans+=find(id*2,s,t,l,mid);
if(t>mid) ans+=find(id*2+1,s,t,mid+1,r);
return ans%m;
}
signed main(){
cin>>n>>q>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(q--){
int op,x,y,k;
cin>>op;
if(op==1){
cin>>x>>y>>k;
add(1,x,y,1,n,k);
}else if(op==2){
cin>>x>>y>>k;
mul(1,x,y,1,n,k);
}else{
cin>>x>>y;
cout<<find(1,x,y,1,n)<<endl;
}
}
return 0;
}