#include<bits/stdc++.h>
#define ls (root<<1)
#define rs (root<<1|1)
#define mid ( l+r >> 1)
#define LL long long
using namespace std;
const int MXN=1e5+5;
int a[MXN];
struct Tree{//cf乘法缓存,sum加法缓存,val值
LL cf,sum,val;
}tree[MXN];
int mod;
void date(int l,int r,int root)
{
tree[root].val=(tree[l].val+tree[r].val)%mod;
return;
}
void build_tree(int l,int r,int root)
{
// if(l>r)return;
if(l==r)
{
tree[root].cf=1;
tree[root].val=a[l];
return;
}
build_tree(l,mid,ls);
build_tree(mid+1,r,rs);
date(ls,rs,root);
tree[root].cf=1;
}
void push_down(int l,int r,int root)
{
if(tree[root].cf!=1)
{
tree[ls].cf=(tree[ls].cf*tree[root].cf)%mod;
tree[rs].cf=(tree[rs].cf*tree[root].cf)%mod;
tree[ls].sum=(tree[ls].sum*tree[root].cf)%mod;
tree[rs].sum=(tree[rs].sum*tree[root].cf)%mod;
tree[ls].val=(tree[ls].val*tree[root].cf)%mod;
tree[rs].val=(tree[rs].val*tree[root].cf)%mod;
tree[root].cf=1;
}
if(tree[root].sum)
{
tree[ls].sum=(tree[ls].sum+tree[root].sum)%mod;
tree[rs].sum=(tree[rs].sum+tree[root].sum)%mod;
tree[ls].val=(tree[ls].val+tree[root].sum*(mid-l+1))%mod;
tree[rs].val=(tree[rs].val+tree[root].sum*(r-mid))%mod;
tree[root].sum=0;
}
return;
}
LL query(int l,int r,int L,int R,int root)
{
if(r<L||l>R)return 0;
if(L<=l&&R>=r)
{
return tree[root].val;
}
push_down(l,r,root);
LL s1=query(l,mid,L,R,ls);
LL s2=query(mid+1,r,L,R,rs);
return (s1+s2)%mod;
}
void update(int l,int r,int L,int R,int root,int v,int flag)
{
if(r<L||l>R)return;
if(L<=l&&R>=r)
{
if(flag==1)
{
tree[root].val=(tree[root].val*v)%mod;
tree[root].cf=(tree[root].cf*v)%mod;
tree[root].sum=(tree[root].sum*v)%mod;
return;
}
if(flag==2)
{
tree[root].val=(tree[root].val+v*(r-l+1))%mod;
tree[root].sum=(tree[root].sum+v)%mod;
return;
}
push_down(l,r,root);
update(l,mid,L,R,ls,v,flag);
update(mid+1,r,L,R,rs,v,flag);
date(ls,rs,root);
}
}
int main()
{
int n,m,p;
scanf("%d%d%d",&n,&m,&p);
mod=p;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build_tree(1,n,1);
int flag=0;
for(int i=1;i<=m;i++)
{
scanf("%d",&flag);
if(flag==1)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
update(1,n,x,y,1,k,flag);
}
if(flag==2)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
update(1,n,x,y,1,k,flag);
}
if(flag==3)
{
int x,y;
scanf("%d%d",&x,&y);
cout<<query(1,n,x,y,1)<<endl;
}
}
return 0;
}