#include<bits/stdc++.h>
#define mn 1000010
typedef long long ll;
using namespace std;
ll n,m,mod;
ll opt,x,y,K;
ll arr[mn],tree[mn];
ll tag[mn][2];
inline void pushup(ll node){
ll node_lft=node<<1;
ll node_rgt=node<<1|1;
tree[node]=(tree[node_lft]+tree[node_rgt])%mod;
}
inline void pushdown(ll node,ll s,ll e){
ll node_lft=node<<1;
ll node_rgt=node<<1|1;
ll mid=(s+e)>>1;
if(tag[node][0]){
tree[node_lft]*=tag[node][0];
tree[node_lft]%=mod;
tag[node_lft][0]*=tag[node][0];
tag[node_lft][0]%=mod;
tag[node_lft][1]*=tag[node][0];
tag[node_lft][1]%=mod;
tree[node_rgt]*=tag[node][0];
tree[node_rgt]%=mod;
tag[node_rgt][0]*=tag[node][0];
tag[node_rgt][0]%=mod;
tag[node_rgt][1]*=tag[node][0];
tag[node_rgt][1]%=mod;
tag[node][0]=1;
}
if(tag[node][1]){
tree[node_lft]+=tag[node][1]*(mid-s+1);
tree[node_lft]%=mod;
tag[node_lft][1]+=tag[node][1];
tag[node_lft][1]%=mod;
tree[node_rgt]+=tag[node][1]*(e-mid);
tree[node_rgt]%=mod;
tag[node_rgt][1]+=tag[node][1];
tag[node_rgt][1]%=mod;
tag[node][1]=0;
}
}
inline void build(ll node,ll s,ll e){
tag[node][0]=1;
if(s==e){
tree[node]=arr[s]%mod;
return;
}
ll node_lft=node<<1;
ll node_rgt=node<<1|1;
ll mid=(s+e)>>1;
build(node_lft,s,mid);
build(node_rgt,mid+1,e);
pushup(node);
}
inline void updata(ll node,ll s,ll e,ll l,ll r,ll p,ll k){
if(s==l&&e==r){
if(p==0){
tag[node][0]*=k;
tag[node][0]%=mod;
tag[node][1]*=k;
tag[node][1]%=mod;
tree[node]*=k;
tree[node]%=mod;
}
else{
tag[node][1]+=k;
tag[node][1]%=mod;
tree[node]+=(r-l+1)*k;
tree[node]%=mod;
}
return;
}
ll node_lft=node<<1;
ll node_rgt=node<<1|1;
ll mid=(s+e)>>1;
pushdown(node,s,e);
if(l<=mid)
updata(node_lft,s,mid,l,min(mid,r),p,k);
if(r>mid)
updata(node_rgt,mid+1,e,max(mid+1,l),r,p,k);
pushup(node);
}
inline ll query(ll node,ll s,ll e,ll l,ll r){
if(s==l&&e==r)return tree[node];
ll node_lft=node<<1;
ll node_rgt=node<<1|1;
ll mid=(s+e)>>1;
ll tmp=0;
pushdown(node,s,e);
if(l<=mid)
tmp+=query(node_lft,s,mid,l,min(mid,r))%mod;
if(r>mid)
tmp+=query(node_rgt,mid+1,e,max(mid+1,l),r)%mod;
return tmp%mod;
}
int main(){
scanf("%lld%lld%lld",&n,&m,&mod);
for(ll i=1;i<=n;i++){
scanf("%lld",arr+i);
}
build(1,1,n);
while(m--){
scanf("%lld%lld%lld",&opt,&x,&y);
if(opt==3){
printf("%lld\n",query(1,1,n,x,y)%mod);
}
else{
scanf("%lld",&K);
updata(1,1,n,x,y,opt-1,K);
}
}
return 0;
}