#include<bits/stdc++.h>
using namespace std;
struct node{
long long sum,add,mul;
int l,r;
}v[400005];
int n,q,m,a[100005];
int fast_pow(int a,int b){
int ans=1,base=a;
while(b>0){
if(b&1)ans=ans*base%m;
base=base*base%m;
b>>=1;
}
return ans;
}
void push_up(int rt){
v[rt].sum=v[rt<<1].sum+v[rt<<1|1].sum;
}
void push_add(int rt,int k){
v[rt].sum+=(v[rt].r-v[rt].l+1)*k%m;
v[rt].add+=k;
}
void push_mul(int rt,int k){
v[rt].sum*=fast_pow(k,v[rt].r-v[rt].l+1)%m;
v[rt].add*=k;
v[rt].mul*=k;
}
void push_down(int rt){
push_mul(rt<<1,v[rt].mul);
push_mul(rt<<1|1,v[rt].mul);
push_add(rt<<1,v[rt].add);
push_add(rt<<1|1,v[rt].add);
v[rt].mul=1;
v[rt].add=0;
}
void build(int rt,int l,int r){
v[rt].l=l;
v[rt].r=r;
v[rt].mul=1;
if(l==r){
v[rt].sum=a[l];
return;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
push_up(rt);
}
void add(int rt,int l,int r,int k){
if(l<=v[rt].l&&r>=v[rt].r){
push_add(rt,k);
return;
}
push_down(rt);
int mid=(v[rt].l+v[rt].r)/2;
if(l<=mid)add(rt<<1,l,r,k);
if(r>=mid+1)add(rt<<1|1,l,r,k);
push_up(rt);
}
void mul(int rt,int l,int r,int k){
if(v[rt].l>=l&&r>=v[rt].r){
push_mul(rt,k);
return;
}
push_down(rt);
int mid=(v[rt].l+v[rt].r)/2;
if(l<=mid)mul(rt<<1,l,r,k);
if(r>=mid+1)mul(rt<<1|1,l,r,k);
push_up(rt);
}
int ask(int rt,int l,int r){
if(l<=v[rt].l&&r>=v[rt].r)return v[rt].sum%m;
push_down(rt);
int mid=(v[rt].l+v[rt].r)/2;
int sum=0;
if(l<=mid)sum+=ask(rt<<1,l,r);
if(r>=mid+1)sum+=ask(rt<<1|1,l,r);
return sum%m;
}
int main(){
cin>>n>>q>>m;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,1,n);
while(q--){
int op;
cin>>op;
if(op==2){
int x,y,k;
cin>>x>>y>>k;
add(1,x,y,k);
}else if(op==1){
int x,y,k;
cin>>x>>y>>k;
mul(1,x,y,k);
}else{
int x,y;
cin>>x>>y;
cout<<ask(1,x,y)<<endl;
}
}
}