#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+20;
int n,q,mod,opt,x,y,k,a[N];
struct Segment_Tree{
struct node{
int l,r,j,c,v;
}tree[N*4];
inline int lt(int p){return p<<1;}
inline int rt(int p){return p<<1|1;}
inline int fpow(int a,int n,int mod){
a%=mod;
int ans=1;
while(n){
if(n&1) ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
inline void push_up(int p){
tree[p].v=(tree[lt(p)].v+tree[rt(p)].v)%p;
}
inline void push_down(int p){
int k1=tree[p].c,k2=tree[p].j;
tree[lt(p)].v=(tree[lt(p)].v*k1+k2*(tree[lt(p)].r-tree[lt(p)].l+1))%mod;
tree[lt(p)|1].v=(tree[lt(p)|1].v*k1+k2*(tree[lt(p)|1].r-tree[lt(p)|1].l+1))%mod;
tree[lt(p)].c=(tree[lt(p)].c*k1)%mod;
tree[lt(p)|1].c=(tree[lt(p)|1].c*k1)%mod;
tree[lt(p)].j=(tree[lt(p)].j*k1+k2)%mod;
tree[lt(p)|1].j=(tree[lt(p)|1].j*k1+k2)%mod;
tree[p].j=0;
tree[p].c=1;
return ;
}
inline void build(int p,int l,int r){
tree[p].c=1;
tree[p].j=0;
tree[p].l=l;
tree[p].r=r;
if(l==r){
tree[p].v=a[l];
return ;
}
int m=(l+r)>>1;
build(lt(p),l,m);
build(rt(p),m+1,r);
push_up(p);
}
inline void add(int p,int l,int r,int k){
if(l>r) return ;
if(tree[p].r<l||tree[p].l>r) return ;
if(tree[p].l>=l&&tree[p].r<=r){
tree[p].v+=(r-l+1)*k;
tree[p].j+=k;
return ;
}
push_down(p);
int m=(l+r)>>1;
add(lt(p),l,m,k);
add(rt(p),m+1,r,k);
push_up(p);
return ;
}
inline void times(int p,int l,int r,int k){
if(l>r) return ;
if(tree[p].r<l||tree[p].l>r) return ;
if(tree[p].l>=l&&tree[p].r<=r){
tree[p].v=tree[p].v*k%mod;
tree[p].c=tree[p].c*k%mod;
tree[p].j=tree[p].j*k%mod;
return ;
}
push_down(p);
int m=(l+r)>>1;
add(lt(p),l,m,k);
add(rt(p),m+1,r,k);
push_up(p);
return ;
}
inline int query(int p,int l,int r){
if(tree[p].r<l||tree[p].l>r) return 0;
if(tree[p].l>=l&&tree[p].r<=r)
return tree[p].v;
int m=(l+r)>>1;
return (query(lt(p),l,m)+query(rt(p),m+1,r))%mod;
}
}tr;
signed main(){
cin>>n>>q>>mod;
for(int i=1;i<=n;i++) cin>>a[i];
tr.build(1,1,n);
while(q--){
cin>>opt>>x>>y;
if(opt==1){
cin>>k;
tr.add(1,x,y,k);
}else if(opt==2){
cin>>k;
tr.times(1,x,y,k);
}else{
cout<<tr.query(1,x,y)<<endl;
}
}
return 0;
}