#include<bits/stdc++.h>
using namespace std;
long long n,m,q,a[100010],d[300000],ld[300000],ld2[300000];//懒惰标记
void gz(long long int s,long long int t,long long int p) {//构造线段树
if(s==t) {
d[p]=a[s];
return;
}
long long int mind=s+((t-s)>>1);
gz(s,mind,p*2);
gz(mind+1,t,p*2+1);
d[p]=d[p*2]+d[p*2+1];
}
void zj(long long int x,long long int y,long long int s,long long int t,long long int k,long long int p) {
if(x<=s&&y>=t){
d[p]+=((t-s+1)*k)%m;
ld[p]+=k;
return;
}
long long int mind=s+((t-s)>>1);
if(ld[p]&&s!=t){
d[p*2]+=(ld[p]*((mind-s+1)%m))%m;ld[p*2]+=ld[p];
d[p*2+1]+=(ld[p]*((t-mind)%m)%m);ld[p*2+1]+=ld[p];
ld[p]=0;
}
if(x<=mind){
zj(x,y,s,mind,k,p*2);
}
if(y>mind){
zj(x,y,mind+1,t,k,p*2+1);
}
d[p]=(d[p*2]+d[p*2+1])%m;
}
void xc(long long int x,long long int y,long long int s,long long int t,long long int k,long long int p) {
if(x<=s&&y>=t){
d[p]=(d[p]*(k%m))%m;
ld2[p]+=k;
return;
}
long long int mind=s+((t-s)>>1);
if(ld2[p]&&s!=t){
d[p*2]=ld2[p]*(d[mind-s+1]%m)%m;ld2[p*2]+=ld2[p];
d[p*2+1]=ld2[p]*(d[t-mind]%m)%m;ld2[p*2+1]+=ld2[p];
ld2[p]=0;
}
if(x<=mind){
zj(x,y,s,mind,k,p*2);
}
if(y>mind){
zj(x,y,mind+1,t,k,p*2+1);
}
d[p]=(d[p*2]+d[p*2+1])%m;
}
long long int cx(long long int l,long long int r,long long int s,long long int t,long long int p) {
if(s>=l&&t<=r) {
return d[p];//[l,r]包含[s,t]
}
long long int mind=s+((t-s)>>1),sum=0;
if(ld[p]){
d[p*2]+=ld[p]*((mind-s+1)%m)%m;ld[p*2]+=ld[p];
d[p*2+1]+=ld[p]*((t-mind)%m)%m;ld[p*2+1]+=ld[p];
ld[p]=0;
}
if(ld2[p]){
d[p*2]=ld2[p]*(d[mind-s+1]%m)%m;ld2[p*2]+=ld2[p];
d[p*2+1]=ld2[p]*(d[t-mind]%m)%m;ld2[p*2+1]+=ld2[p];
ld2[p]=0;
}
if(l<=mind) {
sum+=(cx(l,r,s,mind,p*2))%m;
sum%=m;
}
if(r>mind) {
sum+=(cx(l,r,mind+1,t,p*2+1))%m;
sum%=m;
}
return sum%m;
}
int main() {
cin>>n>>q>>m;
for(int i=1; i<=n; i++) {
cin>>a[i];
}
gz(1,n,1);
for(int i=1; i<=q; i++) {
long long int nu,x,y;
cin>>nu>>x>>y;
if(nu==2) {
long long int k;
cin>>k;
zj(x,y,1,n,k,1);
} else {
if(nu==1){
long long k;
cin>>k;
xc(x,y,1,n,k,1);
}else{
long long int a;
a=cx(x,y,1,n,1);
cout<<a<<"\n";
}
}
}
}