#include<bits/stdc++.h>
using namespace std;
long long a[100010],w[400010],tag1[400010],tag2[400010],k,n,q,m,op,lx,rx;
void pushup(int u){
w[u] = (w[2*u]+w[2*u+1])%m;
}
void build(int u,int l,int r){
tag1[u] = 1;
if(l==r){
w[u] = a[l];
return ;
}
int mid = (l+r)/2;
build(2*u,l,mid);
build(2*u+1,mid+1,r);
pushup(u);
}
bool inrange(int L,int R,int l,int r){
return (l<=L)&&(R<=r);
}
bool outofrange(int L,int R,int l,int r){
return (R<l)||(r<L);
}
void maketag1(int u,int l,int r,int k){
tag2[u] = (tag2[u]*k)%m;
tag1[u] = (tag1[u]*k)%m;
w[u] = (w[u]*k)%m;
}
void maketag2(int u,int l,int r,int k){
w[u] = (w[u]+k*(r-l+1))%m;
tag2[u] = (tag2[u]+k)%m;
}
void pushdown(int u,int l,int r){
int mid = (l+r)/2;
if(tag1[u]==1){
maketag2(2*u,l,mid,tag2[u]);
maketag2(2*u+1,mid+1,r,tag2[u]);
tag2[u] = 0;
}
else{
maketag1(2*u,l,mid,tag1[u]);
maketag1(2*u+1,mid+1,r,tag1[u]);
tag1[u] = 1;
}
}
void updata1(int u,int L,int R,int l,int r,int k){
if(inrange(L,R,l,r)){
maketag1(u,L,R,k);
}
else if(!outofrange(L,R,l,r)){
int mid = (L+R)/2;
pushdown(u,L,R);
updata1(2*u,L,mid,l,r,k);
updata1(2*u+1,mid+1,R,l,r,k);
pushup(u);
}
}
void updata2(int u,int L,int R,int l,int r,int k){
if(inrange(L,R,l,r)){
maketag2(u,L,R,k);
}
else if(!outofrange(L,R,l,r)){
int mid = (L+R)/2;
pushdown(u,L,R);
updata2(2*u,L,mid,l,r,k);
updata2(2*u+1,mid+1,R,l,r,k);
pushup(u);
}
}
long long Q(int u,int L,int R,int l,int r){
if(inrange(L,R,l,r)){
return w[u];
}
else if(!outofrange(L,R,l,r)){
int mid = (L+R)/2;
pushdown(u,L,R);
return (Q(2*u,L,mid,l,r)+Q(2*u+1,mid+1,R,l,r))%m;
}
else{
return 0;
}
}
int main(){
cin>>n>>q>>m;
for(int i = 1;i<=n;i++){
cin>>a[i];
a[i] = a[i]%m;
}
build(1,1,n);
for(int i = 1;i<=q;i++){
cin>>op>>lx>>rx;
if(op==1){
cin>>k;
updata1(1,1,n,lx,rx,k);
}
else if(op==2){
cin>>k;
updata2(1,1,n,lx,rx,k);
}
else if(op==3){
cout<<Q(1,1,n,lx,rx)<<"\n";
}
}
return 0;
}