#include <bits/stdc++.h>
using namespace std;
#define N 100005
#define int long long
int id=1,n,q,m;
struct node
{
int l,r,cnt,add,mul=1;
}t[N*2];
void add_tag(int &x,int l,int r,int num)
{
num%=m;
if(!x)
x=++id;
t[x].add+=num;
t[x].cnt+=num*(r-l+1)%m;
t[x].add%=m;
t[x].cnt%=m;
}
void mul_tag(int &x,int num)
{
num%=m;
if(!x)
x=++id;
t[x].add*=num;
t[x].mul*=num;
t[x].cnt*=num;
t[x].add%=m;
t[x].mul%=m;
t[x].cnt%=m;
}
void pushup(int x)
{
t[x].cnt=(t[t[x].l].cnt+t[t[x].r].cnt)%m;
}
void pushdown(int x,int l,int r)
{
if(l>=r)
return;
if(!t[x].l)
t[x].l=++id;
if(!t[x].r)
t[x].r=++id;
t[t[x].l].cnt=t[t[x].l].cnt*t[x].mul%m+t[x].add*(t[t[x].l].r-t[t[x].l].l+1)%m;
t[t[x].r].cnt=t[t[x].r].cnt*t[x].mul%m+t[x].add*(t[t[x].r].r-t[t[x].r].l+1)%m;
t[t[x].l].cnt%=m;
t[t[x].r].cnt%=m;
t[t[x].l].add=t[t[x].l].add*t[x].mul%m+t[x].add;
t[t[x].r].add=t[t[x].r].add*t[x].mul%m+t[x].add;
t[t[x].l].add%=m;
t[t[x].r].add%=m;
t[t[x].l].mul=t[t[x].l].mul*t[x].mul%m;
t[t[x].r].mul=t[t[x].r].mul*t[x].mul%m;
t[t[x].l].mul%=m;
t[t[x].r].mul%=m;
t[x].add=0;
t[x].mul=1;
}
void update_add(int x,int l,int r,int ql,int qr,int num)
{
num%=m;
if(ql>r || qr<l)
return;
if(ql<=l && qr>=r)
{
add_tag(x,l,r,num);
return;
}
pushdown(x,l,r);
int mid=(l+r-1)/2;
update_add(t[x].l,l,mid,ql,qr,num);
update_add(t[x].r,mid+1,r,ql,qr,num);
pushup(x);
}
void update_mul(int x,int l,int r,int ql,int qr,int num)
{
num%=m;
if(ql>r || qr<l)
return;
if(ql<=l && qr>=r)
{
mul_tag(x,num);
return;
}
pushdown(x,l,r);
int mid=(l+r-1)/2;
update_mul(t[x].l,l,mid,ql,qr,num);
update_mul(t[x].r,mid+1,r,ql,qr,num);
pushup(x);
}
int query(int x,int l,int r,int ql,int qr)
{
if(ql>r || qr<l)
return 0;
if(ql<=l && qr>=r)
return t[x].cnt;
pushdown(x,l,r);
int mid=(l+r-1)/2;
return (query(t[x].l,l,mid,ql,qr)+query(t[x].r,mid+1,r,ql,qr))%m;
}
signed main( void )
{
cin>>n>>q>>m;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
update_add(1,1,n,i,i,x);
}
while(q--)
{
int op,x,y,k;
cin>>op;
if(op==1)
{
cin>>x>>y>>k;
update_mul(1,1,n,x,y,k);
}
if(op==2)
{
cin>>x>>y>>k;
update_add(1,1,n,x,y,k);
}
if(op==3)
{
cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
}
}
return 0;
}