#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
inline int read(){
int s=0,t=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') t=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
s=s*10+c-'0';c=getchar();
}
return s*t;
}
inline void write(int p){
if(p<10){
putchar(p+'0');return;
}
write(p/10);
putchar(p%10+'0');
}
struct node{
int s,ls,rs,tag1,tag2;
}t[MAXN<<1];
int m,a[MAXN],tot=0;
inline void build(int &rt,int l,int r){
if(!rt) rt=++tot;
t[rt].tag1=1;t[rt].tag2=0;
if(l==r){
t[rt].s=a[l]%m;return;
}
int mid=(l+r)>>1;
build(t[rt].ls,l,mid);build(t[rt].rs,mid+1,r);
t[rt].s=(t[t[rt].ls].s+t[t[rt].rs].s)%m;
}
inline void pushdown(int rt,int l,int r){
if(t[rt].tag1!=1||t[rt].tag2){
int mid=(l+r)>>1;
t[t[rt].ls].s=(t[t[rt].ls].s*t[rt].tag1%m+t[rt].tag2*(mid-l+1))%m;
t[t[rt].rs].s=(t[t[rt].rs].s*t[rt].tag1%m+t[rt].tag2*(r-mid))%m;
t[t[rt].ls].tag1*=t[rt].tag1;t[t[rt].ls].tag1%=m;
t[t[rt].rs].tag1*=t[rt].tag1;t[t[rt].rs].tag1%=m;
t[t[rt].ls].tag2=(t[t[rt].ls].tag2*t[rt].tag1+t[rt].tag2)%m;
t[t[rt].rs].tag2=(t[t[rt].rs].tag2*t[rt].tag1+t[rt].tag2)%m;
t[rt].tag1=1;t[rt].tag2=0;
}
}
inline void update1(int rt,int l,int r,int left,int right,int k){
if(l>=left&&r<=right){
t[rt].s*=k;t[rt].s%=m;
t[rt].tag1*=k;t[rt].tag1%=m;
t[rt].tag2*=k;t[rt].tag2%=m;
return;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
if(left<=mid) update1(t[rt].ls,l,mid,left,right,k);
if(right>mid) update1(t[rt].rs,mid+1,r,left,right,k);
t[rt].s=(t[t[rt].ls].s+t[t[rt].rs].s)%m;
}
inline void update2(int rt,int l,int r,int left,int right,int k){
if(l>=left&&r<=right){
t[rt].s+=k*(r-l+1);t[rt].s%=m;
t[rt].tag2+=k;t[rt].tag2%=m;
return;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
if(left<=mid) update2(t[rt].ls,l,mid,left,right,k);
if(right>mid) update2(t[rt].rs,mid+1,r,left,right,k);
t[rt].s=(t[t[rt].ls].s+t[t[rt].rs].s)%m;
}
inline int query(int rt,int l,int r,int left,int right){
if(l>=left&&r<=right) return t[rt].s;
pushdown(rt,l,r);
int mid=(l+r)>>1,ans=0;
if(left<=mid) ans+=query(t[rt].ls,l,mid,left,right);
if(right>mid) ans+=query(t[rt].rs,mid+1,r,left,right);
return ans%m;
}
int main(){
int n,q,p=0,op,x,y,k;
n=read();q=read();m=read();
for(register int i=1;i<=n;++i) a[i]=read();
build(p,1,n);
while(q--){
op=read();x=read();y=read();
if(op==1){
k=read();update1(1,1,n,x,y,k);
}
else if(op==2){
k=read();update2(1,1,n,x,y,k);
}
else{
write(query(1,1,n,x,y));putchar('\n');
}
}
return 0;
}