RT
#define ll long long
#include<bits/stdc++.h>
using namespace std;
ll a[40001],pt[40001],mp[40001],data[10001];
//a存储线段树,pt存储加法标记,mp存储乘法标记,data存储原数组
ll MOD,n,m;
ll ls(ll x) {return x*2;} //左儿子快捷方式
ll rs(ll x) {return x*2+1;} //右儿子快捷方式
void pushup(ll x)
{a[x]=(a[ls(x)]+a[rs(x)])%MOD;} //更新
void build(ll x,ll l,ll r) //构建
{
if (l==r) {a[x]=data[l];return;} //叶子节点
ll mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r); //左右儿子构造
pushup(x);
}
void plus_put_tag(ll T,ll x,ll y,ll k) //加法更改
{
pt[T]=(pt[T]+k)%MOD;
a[T]=(a[T]+(y-x+1)*k)%MOD;
}
void multiply_put_tag(ll T,ll k)
{
pt[T]=pt[T]*k%MOD;
mp[T]=mp[T]*k%MOD;
a[T]=a[T]*k%MOD;
}
void add(ll T,ll al,ll ar,ll x,ll y,ll k) //区间加操作,T表示当前节点,al ar表示要加的范围,x y表示当前节点的范围,k表示加的数
{
if (al<=x&&y<=ar)
{
plus_put_tag(T,x,y,k);
return;
}
if (x<al&&y>ar) return;
ll mid=(x+y)>>1;
add(ls(T),al,ar,x,mid,k);
add(rs(T),al,ar,mid+1,y,k);
pushup(T);
}
void multiply(ll T,ll al,ll ar,ll x,ll y,ll k) //区间乘法,变量同上
{
if (al<=x&&y<=ar)
{
multiply_put_tag(T,k);
return;
}
if (x<al&&y>ar) return;
ll mid=(x+y)>>1;
multiply(ls(T),al,ar,x,mid,k);
multiply(rs(T),al,ar,mid+1,y,k);
pushup(T);
}
void pushdown (ll T,ll x,ll y) //标记下传
{
if (x==y) return;
ll mid=(x+y)>>1;
if (mp[T])
{
multiply_put_tag(ls(T),mp[T]);
multiply_put_tag(rs(T),mp[T]);
mp[T]=0;
}
if (pt[T])
{
plus_put_tag(ls(T),x,mid,pt[T]);
plus_put_tag(rs(T),mid+1,y,pt[T]);
pt[T]=0;
}
}
ll query(ll T,ll al,ll ar,ll x,ll y)//区间查询,变量同上
{
if (x<al&&y>ar) return 0;
if (al<=x&&y<=ar)
{
return a[T]%MOD;
}
pushdown(T,x,y);
ll ans=0,mid=(x+y)>>1;
ans=(ans+query(ls(T),al,ar,x,mid))%MOD;
ans=(ans+query(rs(T),al,ar,mid+1,y))%MOD;
return ans%MOD;
}
int main()
{
cin>>n>>m>>MOD;
for (int i=1;i<=n;++i) cin>>data[i];
build(1,1,n);
for (int i=1;i<=m;++i)
{
ll op,x,y,k;cin>>op>>x>>y;
if (op==1)
{
cin>>k;
multiply(1,x,y,1,n,k);
}
if (op==2)
{
cin>>k;
add(1,x,y,1,n,k);
}
if (op==3)
{
cout<<query(1,x,y,1,n);
}
}
return 0;
}