#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct Tree{
int a,tmp,mult;
}t[4*N];
bool vis[N];
int n,q,mod,f[N];
void pushdown(int rot,int Len){
t[rot<<1].tmp+=t[rot].tmp;
t[rot<<1|1].tmp+=t[rot].tmp;
t[rot<<1].a+=t[rot].tmp*(Len-(Len>>1));
t[rot<<1].a%=mod;
t[rot<<1|1].a+=t[rot].tmp*(Len>>1);
t[rot<<1|1].a%=mod;
t[rot].tmp=0;
}
void pushmul(int rot,int len){
t[rot<<1].mult+=t[rot].mult;
t[rot<<1|1].mult+=t[rot].mult;
t[rot<<1].tmp+=t[rot].mult;
t[rot<<1|1].tmp+=t[rot].mult;
t[rot<<1].a+=t[rot].mult;
t[rot<<1|1].a+=t[rot].mult;
t[rot<<1].mult%=mod;
t[rot<<1|1].mult%=mod;
t[rot<<1].tmp%=mod;
t[rot<<1|1].tmp%=mod;
t[rot<<1].a%=mod;
t[rot<<1|1].a%=mod;
t[rot].mult=1;
}
void build(int rot,int l,int r){
t[rot].mult=1;
if(l==r){
t[rot].a=f[l];
return;
}
int mid=((l+r)>>1);
build(rot<<1,l,mid);
build(rot<<1|1,mid+1,r);
t[rot].a=t[rot<<1].a+t[rot<<1|1].a;
t[rot].a%=mod;
}
long long query(int rot,int l,int r,int L,int R){
if(L<=l&&r<=R)return t[rot].a;
int mid=((l+r)>>1);
if(t[rot].mult!=1)pushmul(rot,r-l+1);
if(t[rot].tmp)pushdown(rot,(r-l+1));
long long res=0;
if(L<=mid)res+=query(rot<<1,l,mid,L,R);
res%=mod;
if(R>mid)res+=query(rot<<1|1,mid+1,r,L,R);
res%=mod;
return res;
}
void update_add(int rot,int l,int r,int L,int R,long long k){
if(L<=l&&r<=R){
t[rot].tmp+=k;
t[rot].a+=k*(r-l+1);
t[rot].tmp%=mod;
t[rot].a%=mod;
}
else{
int mid=((l+r)>>1);
if(t[rot].mult!=1)pushmul(rot,r-l+1);
if(t[rot].tmp)pushdown(rot,(r-l+1));
if(L<=mid)update_add(rot<<1,l,mid,L,R,k);
if(R>mid)update_add(rot<<1|1,mid+1,r,L,R,k);
t[rot].a=(t[rot<<1].a+t[rot<<1|1].a)%mod;
}
}
void update_times(int rot,int l,int r,int L,int R,long long k){
if(L<=l&&r<=R){
t[rot].tmp+=k;
t[rot].a+=k;
t[rot].mult+=k;
t[rot].tmp%=mod;
t[rot].a%=mod;
t[rot].mult%=mod;
}
else{
int mid=((l+r)>>1);
if(t[rot].mult!=1)pushmul(rot,r-l+1);
if(t[rot].tmp)pushdown(rot,(r-l+1));
if(L<=mid)update_times(rot<<1,l,mid,L,R,k);
if(R>mid)update_times(rot<<1|1,mid+1,r,L,R,k);
t[rot].a=(t[rot<<1].a+t[rot<<1|1].a)%mod;
}
}
int main(){
scanf("%d%d%d",&n,&q,&mod);
build(1,1,n);
for(int i=1;i<=n;i++)scanf("%d",&f[i]);
for(int i=1;i<=q;i++){
int op,x,y;
long long z;
scanf("%d",&op);
if(op==1){
scanf("%d%d%lld",&x,&y,&z);
update_times(1,1,n,x,y,z);
}
else{
if(op==2){
scanf("%d%d%lld",&x,&y,&z);
update_add(1,1,n,x,y,z);
}
else{
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
}
}
}