#include<bits/stdc++.h>
#define int long long
#define ls(k) (k<<1)
#define rs(k) ((k<<1)+1)
using namespace std;
const int N=1e5+5;
int n,q,mod;
int op,x,y,k;
int tree[N*4];
int a[N];
int tag_add[N*4],tag_mu[N*4];
void push_up(int p)
{
tree[p]=(tree[ls(p)]+tree[rs(p)])%mod;
}
void push_down(int p,int s,int t)
{
int mid=s+((t-s)>>1);
int lt=ls(p),rt=rs(p);
if(tag_mu[p]>1)
{
tag_add[lt]=(tag_add[lt]*tag_mu[p])%mod;
tag_mu[lt]=(tag_mu[lt]*tag_mu[p])%mod;
tree[lt]=(tree[lt]*tag_mu[p])%mod;
tag_add[rt]=(tag_add[rt]*tag_mu[p])%mod;
tag_mu[rt]=(tag_mu[rt]*tag_mu[p])%mod;
tree[rt]=(tree[rt]*tag_mu[p])%mod;
tag_mu[p]=1;
}
if(tag_add[p])
{
tag_add[lt]=(tag_add[lt]+tag_add[p])%mod;
tree[lt]=(tree[lt]+tag_add[p]*(mid-s+1))%mod;
tag_add[rt]=(tag_add[rt]+tag_add[p])%mod;
tree[rt]=(tree[rt]+tag_add[p]*(t-mid))%mod;
tag_add[p]=0;
}
return;
}
void build(int l,int r,int p)
{
if(l==r)
{
tree[p]=a[l];
return ;
}
int mid=l+((r-l)>>1);
build(l,mid,ls(p));
build(mid+1,r,rs(p));
push_up(p);
}
void update_Mu(int l,int r,int k,int s,int t,int p)
{
if(l<=s and t<=r)
{
tag_add[p]=(tag_add[p]*k)%mod;
tag_mu[p]=(tag_mu[p]*k)%mod;
tree[p]=(tree[p]*k)%mod;
return;
}
push_down(p,s,t);
int mid=s+((t-s)>>1);
if(l<=mid) update_Mu(l,r,k,s,mid,ls(p));
if(r>=mid+1) update_Mu(l,r,k,mid+1,t,rs(p));
push_up(p);
}
void update_Add(int l,int r,int k,int s,int t,int p)
{
if(l<=s and t<=r)
{
tag_add[p]=(tag_add[p]+k)%mod;
tree[p]=(tree[p]+k*(t-s+1))%mod;
return ;
}
push_down(p,s,t);
int mid=s+((t-s)>>1);
if(l<=mid) update_Add(l,r,k,s,mid,ls(p));
if(r>=mid+1) update_Add(l,r,k,mid+1,t,rs(p));
push_up(p);
}
int query(int l,int r,int s,int t,int p)
{
if(l<=s and t<=r) return tree[p];
push_down(p,s,t);
int mid=s+((t-s)>>1);
int ans=0;
if(l<=mid) ans+=query(l,r,s,mid,ls(p)),ans%=mod;
if(mid+1<=r) ans+=query(l,r,mid+1,t,rs(p)),ans%=mod;
return ans;
}
signed main()
{
cin>>n>>q>>mod;
for(int i=1;i<=n;i++)
cin>>a[i],a[i]%=mod;
build(1,n,1);
while(q--)
{
cin>>op;
if(op==1)
{
cin>>x>>y>>k;
update_Mu(x,y,k,1,n,1);
}
else if(op==2)
{
cin>>x>>y>>k;
update_Add(x,y,k,1,n,1);
}
else
{
cin>>x>>y;
cout<<query(x,y,1,n,1)<<'\n';
}
}
return 0;
}