#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,q,mod,op,ax,bx,cx;
struct node{
ll l,r,sum,tag1,tag2;
};
node t[10000005];
void build(ll x,ll y,ll tot){
if(x==y){
cin >> op;
t[tot]=node{x,y,op%mod,0,0};
return ;
}
ll mid=x+y>>1;
build(x,mid,tot*2);
build(mid+1,y,tot*2+1);
t[tot]=node{x,y,0,1,0};
t[tot].sum=(t[tot*2].sum+t[tot*2+1].sum)%mod;
}
void update(ll tot){
if(t[tot].tag1){
t[tot*2].sum=t[tot*2].sum*t[tot].tag1%mod;
t[tot*2+1].sum=t[tot*2+1].sum*t[tot].tag1%mod;
t[tot*2].tag1*=t[tot].tag1;
t[tot*2+1].tag1*=t[tot].tag1;
t[tot].tag1=1;
}
if(t[tot].tag2){
t[tot*2].sum+=(t[tot*2].r-t[tot*2].l+1)*t[tot].tag2;
t[tot*2].sum%=mod;
t[tot*2+1].sum+=(t[tot*2+1].r-t[tot*2+1].l+1)*t[tot].tag2;
t[tot*2+1].sum%=mod;
t[tot*2].tag2+=t[tot].tag2;
t[tot*2+1].tag2+=t[tot].tag2;
t[tot].tag2=0;
}
}
void change1(ll x,ll y,ll z,ll tot){
if(x<=t[tot].l&&t[tot].r<=y){
t[tot].sum*=z;
t[tot].sum%=mod;
t[tot].tag1*=z;
t[tot].tag2*=z;
return ;
}
update(tot);
ll mid=t[tot].l+t[tot].r>>1;
if(x<=mid) change1(x,y,z,tot*2);
if(y>=mid+1) change1(x,y,z,tot*2+1);
t[tot].sum=(t[tot*2].sum+t[tot*2+1].sum)%mod;
}
void change2(ll x,ll y,ll z,ll tot){
if(x<=t[tot].l&&t[tot].r<=y){
t[tot].sum+=(t[tot].r-t[tot].l+1)*z;
t[tot].sum%=mod;
t[tot].tag2+=z;
return ;
}
update(tot);
ll mid=t[tot].l+t[tot].r>>1;
if(x<=mid) change2(x,y,z,tot*2);
if(y>=mid+1) change2(x,y,z,tot*2+1);
t[tot].sum=t[tot*2].sum%mod+t[tot*2+1].sum%mod;
t[tot].sum%=mod;
}
ll ask(ll x,ll y,ll tot){
ll ans=0;
if(x<=t[tot].l&&t[tot].r<=y){
return t[tot].sum%mod;
}
update(tot);
ll mid=t[tot].l+t[tot].r>>1;
if(x<=mid) ans+=ask(x,y,tot*2);
if(y>=mid+1) ans+=ask(x,y,tot*2+1);
return ans%mod;
}
int main(){
std::ios::sync_with_stdio(false);
cin >> n >> q >> mod;
build(1,n,1);
for(ll i=1;i<=q;i++){
cin >> op;
if(op==1){
cin >> ax >> bx >> cx;
change1(ax,bx,cx,1);
}else if(op==2){
cin >> ax >> bx >> cx;
change2(ax,bx,cx,1);
}else{
cin >> ax >> bx;
cout << ask(ax,bx,1)%mod << endl;
}
}
return 0;
}