#include <bits/stdc++.h>
#define int long long
#define lc p*2
#define rc p*2+1
using namespace std;
const int N=100001;
struct tree{
int l,r,sum,add,mul;
}tr[N*4];
int w[N],mod;
void pushup(int p)
{
tr[p].sum=(tr[lc].sum+tr[rc].sum)%mod;
}
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
void pushdown(int p)
{
tr[lc].sum=((tr[lc].sum*tr[p].mul)%mod+((tr[lc].r-tr[lc].l+1)*tr[p].add)%mod)%mod;
tr[rc].sum=((tr[rc].sum*tr[p].mul)%mod+((tr[rc].r-tr[rc].l+1)*tr[p].add)%mod)%mod;
tr[lc].mul=tr[lc].mul*tr[p].mul%mod;
tr[rc].mul=tr[rc].mul*tr[p].mul%mod;
tr[lc].add=(tr[lc].add+tr[p].add)%mod;
tr[rc].add=(tr[rc].add+tr[p].add)%mod;
tr[p].add=0,tr[p].mul=1;
}
void build(int p,int l,int r)
{
tr[p]={l,r,w[l],0,1};
if(l==r)return;
int m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
pushup(p);
}
void add(int p,int l,int r,int k)
{
if(l<=tr[p].l&&tr[p].r<=r)
{
tr[p].add=(tr[p].add+k)%mod;
tr[p].sum=(tr[p].sum+(tr[p].r-tr[p].l+1)*k)%mod;
return;
}
pushdown(p);
pushup(p);
int m=tr[p].l+tr[p].r>>1;
if(l<=m)add(lc,l,r,k);
if(m<r)add(rc,l,r,k);
pushup(p);
}
void mul(int p,int l,int r,int k)
{
if(l<=tr[p].l&&tr[p].r<=r)
{
tr[p].add=(tr[p].add*k)%mod;
tr[p].mul=(tr[p].mul*k)%mod;
tr[p].sum=(tr[p].sum*k)%mod;
return;
}
pushdown(p);
pushup(p);
int m=tr[p].l+tr[p].r>>1;
if(l<=m)mul(lc,l,r,k);
if(m<r)mul(rc,l,r,k);
pushup(p);
}
int ask(int p,int l,int r)
{
if(l<=tr[p].l&&tr[p].r<=r)return tr[p].sum;
pushdown(p);
int sum=0;
int m=tr[p].l+tr[p].r>>1;
if(l<=m)sum=(sum+ask(lc,l,r))%mod;
if(m<r)sum=(sum+ask(rc,l,r))%mod;
return sum;
}
int n,q,m;
int c,x,y,k;
signed main()
{
n=read(),q=read(),mod=read();
for(int x=1;x<=n;x++)w[x]=read();
build(1,1,n);
while(q--)
{
c=read();
if(c==1)
{
x=read(),y=read(),k=read();
mul(1,x,y,k);
}
else if(c==2)
{
x=read(),y=read(),k=read();
add(1,x,y,k);
}
else
{
x=read(),y=read();
cout<<ask(1,x,y)<<endl;
}
}
return 0;
}