#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6+10;
ll n,m,mod;
ll a[N],ans[N<<2],add[N<<2],mul[N<<2];
int x,y,k;
void push_up(ll i){
ans[i]=ans[i<<1]+ans[i<<1|1];
}
void push_down(ll i,ll l,ll r){
ll mid=l+r>>1;
ans[i<<1]=(ans[i<<1]*mul[i]%mod+(mid-l+1)*add[i])%mod;
ans[i<<1|1]=(ans[i<<1|1]*mul[i]%mod+(r-mid)*add[i])%mod;
mul[i<<1]=(mul[i<<1]*mul[i])%mod;
mul[i<<1|1]=(mul[i<<1|1]*mul[i])%mod;
add[i<<1]=(add[i<<1]*mul[i]+add[i])%mod;
add[i<<1|1]=(add[i<<1|1]*mul[i]+add[i])%mod;
add[i]=0;mul[i]=1;
}
void build(ll i,ll l,ll r){
int mid=l+r>>1;
add[i]=0;mul[i]=1;
if(l==r) {
ans[i]=a[l];
return ;
}
build(i<<1,l,mid);
build((i<<1)|1,mid+1,r);
push_up(i);
}
void update_add(ll i,ll l,ll r,ll m,ll n,ll k){
if(m<=l&&r<=n){
add[i]=(add[i]+k)%mod;
ans[i]=(ans[i]+k*(r-l+1))%mod;
return ;
}
push_down(i,l,r);
ll mid=l+r>>1;
update_add(i<<1,l,mid,m,n,k);
update_add(i<<1|1,mid+1,r,m,n,k);
push_up(i);
}
void update_mul(ll i,ll l,ll r,ll m,ll n,ll k){
if(m<=l&&r<<n){
ans[i]=(ans[i]*k)%k;
mul[i]=mul[i]*k%mod;
add[i]=add[i]*k%mod;
return ;
}
ll mid=l+r>>1;
if(m<=mid) update_mul(i<<1,l,mid,m,n,k);
if(mid<n) update_mul(i<<1|1,mid+1,r,m,n,k);
push_up(i);
}
ll query(int i,int l,int r,int m,int n){
if(m<=l&&r<=n){
return ans[i];
}
ll sum=0;
ll mid=(l+r)>>1;
push_down(i,l,r);
if(m<=mid) sum=(sum+query(i<<1,l,mid,x,y))%mod;
if(mid<n) sum=(sum+query(i<<1|1,mid+1,r,x,y))%mod;
return sum;
}
int main(){
scanf("%d%d%lld",&n,&m,&mod);
build(1,1,n);int op;
while(m--){
scanf("%d%d%d",&op,&x,&y);
if(op==1){
scanf("%lld",&k);
update_mul(1,1,n,x,y,k);
}else if(op==2){
scanf("%lld",&k);
update_add(1,1,n,x,y,k);
}else{
printf("%lld\n",query(1,1,n,x,y));
}
}
}