#include <iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<algorithm>
//#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
using namespace std;
const int N=100001;
ULL read()
{
LL x=0,f=1;char c=getchar();
while(c<'0' or c>'9')
{if(c=='-') f=-1;c=getchar();}
while(c>='0' and c<='9')
{x=x*10+c-'0',c=getchar();}
return x*f;
}
ULL n,m,q;
ULL a[N];
ULL tre[4*N],add[N*4],mu[N*4];
void maketree(int id,int l,int r)
{
if(l==r)
{
tre[id]=a[l];
return ;
}
int mid=(l+r)>>1;
maketree(id<<1,l,mid);
maketree(id<<1|1,mid+1,r);
tre[id]=tre[id<<1]+tre[id<<1|1];
tre[id]%=q;
return ;
}
void addt(int id,int l,int r,ULL val,ULL muval)
{
add[id]+=val;mu[id]*=muval;add[id]%=q;mu[id]%=q;
tre[id]*=muval;tre[id]%=q;
tre[id]+=val*(r-l+1);tre[id]%=q;
return ;
}
void pushdown(int id,int l,int r,int mid)
{
addt(id<<1,l,mid,add[id],mu[id]);
addt(id<<1|1,mid+1,r,add[id],mu[id]);
add[id]=0,mu[id]=1;
return ;
}
void moadd(int id,int l,int r,int ml,int mr,ULL val)//modify add
{
if(l>=ml and r<=mr)
{
tre[id]+=val*(r-l+1);
tre[id]%=q;
add[id]+=val;
add[id]%=q;
return;
}
int mid=(l+r)>>1;
pushdown(id,l,r,mid);
if(ml<=mid) moadd(id<<1,l,mid,ml,mr,val);
if(mr>mid) moadd(id<<1|1,mid+1,r,ml,mr,val);
tre[id]=tre[id<<1]+tre[id<<1|1];
tre[id]%=q;
return ;
}
void momu(int id,int l,int r,int ml,int mr,ULL val)//modify multiply
{
if(l>=ml and r<=mr)
{
tre[id]*=val;
tre[id]%=q;
add[id]*=val;
add[id]%=q;
mu[id]*=val;
mu[id]%=q;
return;
}
int mid=(l+r)>>1;
pushdown(id,l,r,mid);
if(ml<=mid) momu(id<<1,l,mid,ml,mr,val);
if(mr>mid) momu(id<<1|1,mid+1,r,ml,mr,val);
tre[id]=tre[id<<1]+tre[id<<1|1];
tre[id]%=q;
return ;
}
ULL ans;
void query(int id,int l,int r,int ql,int qr)
{
if(l>=ql and r<=qr)
{
ans+=tre[id];
ans%=q;
return ;
}
int mid=(l+r)>>1;
pushdown(id,l,r,mid);
if(ql<=mid) query(id<<1,l,mid,ql,qr);
if(qr>mid/*没“=”*/) query(id<<1|1,mid+1,r,ql,qr);
return ;
}
int main()
{
//freopen("P3373_2.in","r",stdin);
//freopen("myans.out","w",stdout);
n=read();m=read();q=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
}
maketree(1,1,n);
for(int i=1;i<=n*4;i++)
{
mu[i]=1;
}
for(int i=1;i<=m;i++)
{
int op=read();
int x,y,k;
if(op==1)
{
x=read();y=read();k=read();
momu(1,1,n,x,y,k);
}
else if(op==2)
{
x=read();y=read();k=read();
moadd(1,1,n,x,y,k);
}
else
{
ans=0;
x=read();y=read();
query(1,1,n,x,y);
printf("%lld\n",ans);
}
}
return 0;
}
十个点过三个