#include <bits/stdc++.h>
using namespace std;
int n,q,m;
int t[400005];
int lzt1[400005];
int lzt2[400005];
void upd1(int l,int r,int mid,int u){
if(lzt1[u]!=1&&l!=r){
t[u*2]*=lzt1[u];
t[u*2]%=m;
t[u*2+1]*=lzt1[u];
t[u*2+1]%=m;
lzt2[u*2]*=lzt1[u];
lzt2[u*2]%=m;
lzt2[u*2+1]*=lzt1[u];
lzt2[u*2+1]%=m;
lzt1[u*2]*=lzt1[u];
lzt1[u*2]%=m;
lzt1[u*2+1]*=lzt1[u];
lzt1[u*2+1]%=m;
lzt1[u]=1;
}
}
void upd2(int l,int r,int mid,int u){
upd1(l,r,mid,u);
if(lzt2[u]&&l!=r){
t[u*2]+=(((mid-l+1)*lzt2[u])%m);
t[u*2]%=m;
t[u*2+1]+=(((r-mid)*lzt2[u])%m);
t[u*2+1]%=m;
lzt2[u*2]+=lzt2[u];
lzt2[u*2]%=m;
lzt2[u*2+1]+=lzt2[u];
lzt2[u*2+1]%=m;
lzt2[u]=0;
}
}
void mul(int l,int r,int sl,int sr,int u,int val){
int mid=(r+l-1)/2;
if(l>=sl&&r<=sr){
lzt1[u]*=val;
lzt1[u]%=m;
lzt2[u]*=val;
lzt2[u]%=m;
t[u]*=val;
t[u]%=m;
return;
}
upd1(l,r,mid,u);
if(mid>=sl)mul(l,mid,sl,sr,u*2,val);
if(mid<sr)mul(mid+1,r,sl,sr,u*2+1,val);
t[u]=t[u*2]+t[u*2+1];
t[u]%=m;
}
void add(int l,int r,int sl,int sr,int u,int val){
int mid=(r+l-1)/2;
if(l>=sl&&r<=sr){
upd1(l,r,mid,u);
lzt2[u]+=val;
lzt2[u]%=m;
t[u]+=(r-l+1)*val;
t[u]%=m;
return;
}
upd2(l,r,mid,u);
if(mid>=sl)add(l,mid,sl,sr,u*2,val);
if(mid<sr)add(mid+1,r,sl,sr,u*2+1,val);
t[u]=t[u*2]+t[u*2+1];
t[u]%=m;
}
int get(int l,int r,int sl,int sr,int u){
if(sl<=l&&r<=sr){
return t[u];
}
int mid=(r+l-1)/2;
upd2(l,r,mid,u);
int sum=0;
if(mid>=sl)sum+=get(l,mid,sl,sr,u*2);
if(mid<sr)sum+=get(mid+1,r,sl,sr,u*2+1);
return sum%m;
}
int main(){
scanf("%d%d%d",&n,&q,&m);
int ln=0,tt=n;
for(;tt/2;tt/=2)ln++;
if(n-(1<<ln))ln++;
for(int i=0;i<n;i++){
scanf("%d",&t[(1<<ln)+i]);
lzt1[(1<<n)+i]=1;
}
for(int i=(1<<ln)-1;i>=1;i--){
t[i]=t[i*2]+t[i*2+1];
t[i]%=m;
lzt1[i]=1;
}
for(int i=1;i<=q;i++){
int opt,x,y,k;
scanf("%d%d%d",&opt,&x,&y);
if(opt==1){
scanf("%d",&k);
mul(1,1<<ln,x,y,1,k);
}
if(opt==2){
scanf("%d",&k);
add(1,1<<ln,x,y,1,k);
}
if(opt==3){
printf("%d\n",get(1,1<<ln,x,y,1));
}
}
return 0;
}