#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
#define ls(x) x<<1
#define rs(x) x<<1|1
#define bi(x) x>>1
#define get_m(x) x%mod
int n,q,mod,op,x,y,k;
int a[N];
ll w[4*N],add[4*N],mul[4*N],siz[4*N];
void pushup(int u){
siz[u]=siz[ls(u)]+siz[rs(u)];
w[u]=(w[ls(u)]+w[rs(u)])%mod;
}
void build(int u,int l,int r){
mul[u]=1;
if(l==r){
w[u]=a[l]%mod;
siz[u]=1;
return;
}
int mid=bi(l+r);
build(ls(u),l,mid);
build(rs(u),mid+1,r);
pushup(u);
}
void pushdown(int u){
if(mul[u]!=1){
w[ls(u)]*=mul[u];
add[ls(u)]*=mul[u];
mul[ls(u)]*=mul[u];
get_m(w[ls(u)]); get_m(add[ls(u)]); get_m(mul[ls(u)]);
w[rs(u)]*=mul[u];
add[rs(u)]*=mul[u];
mul[rs(u)]*=mul[u];
get_m(w[rs(u)]); get_m(add[rs(u)]); get_m(mul[rs(u)]);
mul[u]=1;
}
if(add[u]){
w[ls(u)]+=add[u]*siz[ls(u)];
add[ls(u)]+=add[u];
get_m(w[ls(u)]); get_m(add[ls(u)]);
w[rs(u)]+=add[u]*siz[rs(u)];
add[rs(u)]+=add[u];
get_m(w[rs(u)]); get_m(add[rs(u)]);
add[u]=0;
}
}
void mul_modify(int u,int l,int r,int L,int R,ll p){
if(L<=l&&R>=r){
w[u]*=p;
mul[u]*=p;
add[u]*=p;
get_m(w[u]); get_m(mul[u]); get_m(add[u]);
return;
}
pushdown(u);
int mid=bi(l+r);
if(L<=mid){
mul_modify(ls(u),l,mid,L,R,p);
}
if(R>mid){
mul_modify(rs(u),mid+1,r,L,R,p);
}
pushup(u);
}
void add_modify(int u,int l,int r,int L,int R,ll p){
if(L<=l&&R>=r){
w[u]+=p*siz[u];
add[u]+=p;
get_m(w[u]); get_m(add[u]);
return;
}
pushdown(u);
int mid=bi(l+r);
if(L<=mid){
add_modify(ls(u),l,mid,L,R,p);
}
if(R>mid){
add_modify(rs(u),mid+1,r,L,R,p);
}
pushup(u);
}
ll qry(int u,int l,int r,int L,int R){
if(L<=l&&R>=r){
return w[u];
}
pushdown(u);
int mid=bi(l+r);
ll ans=0ll;
if(L<=mid){
ans+=qry(ls(u),l,mid,L,R);
get_m(ans);
}
if(R>mid){
ans+=qry(rs(u),mid+1,r,L,R);
get_m(ans);
}
pushup(u);
return ans;
}
int main(){
cin.tie(0)->sync_with_stdio(0);
cin>>n>>q>>mod;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
while(q--){
cin>>op>>x>>y;
if(op==1){
cin>>k;
mul_modify(1,1,n,x,y,k);
}
else if(op==2){
cin>>k;
add_modify(1,1,n,x,y,k);
}
else{
cout<<qry(1,1,n,x,y)%mod<<"\n";
}
}
return 0;
}