#include<bits/stdc++.h>
#define ls (p<<1)
#define rs ((p<<1)|1)
#define mid ((l+r)>>1)
#define int long long
using namespace std;
const int N=1e5;
int n,m,mod;
int a[N+5];
int op,x,y;
int k;
struct node{
int l,r;
int ans=0;
int mul=1,plus=0;
}tree[4*N+5];
void push_up(int p,int l,int r)
{
tree[p].ans=((tree[ls].ans*tree[ls].mul%mod+tree[ls].plus*(mid-l+1)%mod)%mod+
(tree[rs].ans*tree[rs].mul%mod+tree[rs].plus*(r-mid)%mod)%mod)%mod;
}
void push_down(int p,int l,int r)
{
tree[ls].mul=tree[ls].mul*tree[p].mul%mod;
tree[ls].plus=(tree[ls].plus*tree[p].mul%mod+tree[p].plus)%mod;
tree[rs].mul=tree[rs].mul*tree[p].mul%mod;
tree[rs].plus=(tree[rs].plus*tree[p].mul%mod+tree[p].plus)%mod;
tree[p].mul=1;
tree[p].plus=0;
}
void build(int p,int l,int r)
{
tree[p].l=l;
tree[p].r=r;
if(l==r)
{
tree[p].ans=a[l];
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
push_up(p,l,r);
}
int query(int p,int l,int r,int left,int right)
{
if(l==left&&r==right)
{
return (tree[p].ans*tree[p].mul%mod+tree[p].plus)%mod;
}
int ret=0;
push_down(p,l,r);
if(right<=mid) ret=query(ls,l,mid,left,right);
else if(left>mid) ret=query(rs,mid+1,r,left,right);
else ret=(query(ls,l,mid,left,mid)+query(rs,mid+1,r,mid+1,right))%mod;
push_up(p,l,r);
return ret%mod;
}
void update_mul(int p,int l,int r,int left,int right,int val)
{
if(l==left&&r==right)
{
tree[p].mul=tree[p].mul*val%mod;
tree[p].plus=tree[p].plus*val%mod;
return;
}
push_down(p,l,r);
if(right<=mid) update_mul(ls,l,mid,left,right,val);
else if(left>mid) update_mul(rs,mid+1,r,left,right,val);
else update_mul(ls,l,mid,left,mid,val),update_mul(rs,mid+1,r,mid+1,right,val);
push_up(p,l,r);
}
void update_plus(int p,int l,int r,int left,int right,int val)
{
if(l==left&&r==right)
{
tree[p].plus+=val;
return;
}
push_down(p,l,r);
if(right<=mid) update_plus(ls,l,mid,left,right,val);
else if(left>mid) update_plus(rs,mid+1,r,left,right,val);
else update_plus(ls,l,mid,left,mid,val),update_plus(rs,mid+1,r,mid+1,right,val);
push_up(p,l,r);
}
signed main()
{
cin>>n>>m>>mod;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
while(m--)
{
cin>>op>>x>>y;
if(op==1)
{
cin>>k;
update_mul(1,1,n,x,y,k);
}
else if(op==2)
{
cin>>k;
update_plus(1,1,n,x,y,k);
}
else
{
cout<<query(1,1,n,x,y)<<"\n";
}
}
return 0;
}