#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,c,x,y,k,mod,m[500001],p[500001],j;
struct node{
long long v,add,mul;
}t[500001];
inline long long lt(long long i){
return i<<1;
}
inline long long rt(long long i){
return i<<1|1;
}
void build(int l,int r,int k){
t[k].mul=1;
t[k].add=0;
if(l==r){
t[k].v=m[l];
}
else{
ll mid=(l+r)>>1;
build(l,mid,lt(k));
build(mid+1,r,rt(k));
t[k].v=t[lt(k)].v+t[rt(k)].v;
}
t[k].v%=mod;
return;
}
void put(int l,int r,int i){
int mid=(l+r)>>1;
t[lt(i)].v=(t[lt(i)].v*t[i].mul+t[i].add*(mid-l+1))%mod;
t[rt(i)].v=(t[rt(i)].v*t[i].mul+t[i].add*(r-mid))%mod;
t[lt(i)].mul=(t[lt(i)].mul*t[i].mul)%mod;
t[rt(i)].mul=(t[rt(i)].mul*t[i].mul)%mod;
t[lt(i)].add=(t[lt(i)].add*t[i].mul+t[i].add)%mod;
t[rt(i)].add=(t[rt(i)].add*t[i].mul+t[i].add)%mod;
t[k].mul=1;
t[k].add=0;
return ;
}
void update1(int l,int r,int i,int x,int y,ll k){
if(y<l||r<x){
return;
}
if(x<=l&&y>=r){
t[i].v=(t[i].v*k)%mod;
t[i].mul=(t[i].mul*k)%mod;
t[i].add=(t[i].add*k)%mod;
return ;
}
put(l,r,i);
int mid=(l+r)>>1;
update1(l,mid,lt(i),x,y,k);
update1(mid+1,r,rt(i),x,y,k);
t[i].v=(t[lt(i)].v+t[rt(i)].v)%mod;
return ;
}
void update2(int l,int r,int i,int x,int y,ll k){
if(y<l||r<x){
return;
}
if(x<=l&&y>=r){
t[i].add=(t[i].add+k)%mod;
t[i].v=(t[i].v+k*(r-l+1))%mod;
return;
}
put(l,r,i);
int mid=(l+r)>>1;
update2(l,mid,lt(i),x,y,k);
update2(mid+1,r,rt(i),x,y,k);
t[i].v=(t[lt(i)].v+t[rt(i)].v)%mod;
return ;
}
ll asd(int l,int r,int i,int x,int y){
if(y<l||r<x){
return 0;
}
if(x<=l&&y>=r){
return t[i].v;
}
put(l,r,i);
int mid=(l+r)>>1,sum=0;
return (asd(l,mid,lt(i),x,y)+asd(mid+1,r,rt(i),x,y))%mod;
}
int main(){
scanf("%d %d %d",&a,&b,&mod);
for(j=1;j<=a;j++)
scanf("%lld",&m[j]);
build(1,a,1);
for(j=1;j<=b;j++){
scanf("%d",&c);
if(c==1){
scanf("%d %d %lld",&x,&y,&k);
update1(1,a,1,x,y,k);
}
else if(c==2){
scanf("%d %d %lld",&x,&y,&k);
update2(1,a,1,x,y,k);
}
else if(c==3){
scanf("%lld %lld",&x,&y);
printf("%lld \n",asd(1,a,1,x,y));
}}
return 0;
}