#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
int n,m,mod,opt;
long long a[maxn],w[maxn*4];
long long add[maxn*4],mu[maxn*4]; //加法和乘法的lazy标记
void pushop(int u){ //计算当前节点的和
w[u]=w[u*2]+w[u*2+1];
}
void build(int u,int L,int R){ //建树
if(L==R){
w[u]=a[L];
return;
}
int mid=(L+R)/2;
build(u*2,L,mid);
build(u*2+1,mid+1,R);
pushop(u);
}
void maketag(int u,int L,int R,int x,int y){ //+x,*y
w[u]*=y;
w[u]+=(R-L+1)*x;
w[u]%=mod;
add[u]+=x;
if(y!=0){
add[u]*=y;
mu[u]*=y;
}
add[u]%=mod;
mu[u]%=mod;
}
void pushdown(int u,int L,int R){
int mid=(L+R)/2;
maketag(u*2,L,mid,add[u],mu[u]);
maketag(u*2+1,mid+1,R,add[u],mu[u]);
add[u]=0;
mu[u]=1;
}
bool OutofRange(int L,int R,int l,int r){ //完全没有交集
return L>r||R<l;
}
bool InRange(int L,int R,int l,int r){ //完全包含
return L>=l&&R<=r;
}
int query(int u,int L,int R,int l,int r){
if(OutofRange(L,R,l,r))return 0;
if(InRange(L,R,l,r))return w[u];
pushdown(u,L,R);
int mid=(L+R)/2;
return query(u*2,L,mid,l,r)%mod+query(u*2+1,mid+1,R,l,r)%mod;
}
void update_add(int u,int L,int R,int l,int r,int x){
if(OutofRange(L,R,l,r))return;
if(InRange(L,R,l,r)){
maketag(u,L,R,x,0);
return;
}
pushdown(u,L,R);
int mid=(L+R)/2;
update_add(u*2,L,mid,l,r,x);
update_add(u*2+1,mid+1,R,l,r,x);
pushop(u);
}
void update_mu(int u,int L,int R,int l,int r,int x){
if(OutofRange(L,R,l,r))return;
if(InRange(L,R,l,r)){
maketag(u,L,R,0,x);
return;
}
pushdown(u,L,R);
int mid=(L+R)/2;
update_mu(u*2,L,mid,l,r,x);
update_mu(u*2+1,mid+1,R,l,r,x);
pushop(u);
}
int main(){
cin>>n>>m>>mod;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1,1,n);
while(m--){
int x,y,k;
cin>>opt;
if(opt==1){
cin>>x>>y>>k;
update_mu(1,1,n,x,y,k);
}
if(opt==2){
cin>>x>>y>>k;
update_add(1,1,n,x,y,k);
}
if(opt==3){
cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
}
}
return 0;
}