#include<bits/stdc++.h>
using namespace std;
int op,l,r,k;
const int N=100005;
int n,q,mod,mid;
int a[N];
struct dat{
int v,tagch,tagjia;
}w[N*4];
bool inrange(int L,int R,int l,int r)
{
return (L>=l)&&(R<=r);
}
bool outrange(int L,int R,int l,int r)
{
return (L>r)||(R<l);
}
void pushup(int u)
{
w[u].v=(w[u*2].v+w[u*2+1].v)%mod;
}
void build(int u,int L,int R)
{
if(L==R)
{
w[u].tagch=1;
w[u].v=a[L]%mod;
return ;
}
mid=L+R>>1;
build(u*2,L,mid);
build(u*2+1,mid+1,R);
pushup(u);
w[u].tagch=1;
}
void mak(int u,int L,int R,int x,int typ)
{
if(typ==1)//乘
{
(w[u].tagjia*=x)%=mod;
(w[u].tagch*=x)%=mod;
(w[u].v*=x)%=mod;
}
else
{
(w[u].tagjia+=x)%=mod;
w[u].v=(w[u].v+((x*(R-L+1))%mod))%mod;
}
}
void pushdown(int u,int L,int R)
{
mid=L+R>>1;
mak(u*2,L,mid,w[u].tagch,1);
mak(u*2,L,mid,w[u].tagjia,2);
mak(u*2+1,mid+1,R,w[u].tagch,1);
mak(u*2+1,mid+1,R,w[u].tagjia,2);
w[u].tagch=1;
w[u].tagjia=0;
}
int query(int u,int L,int R)//当前结点覆盖的范围
{
if(inrange(L,R,l,r))return w[u].v;
else if(outrange(L,R,l,r))return 0;
else//覆盖一部分
{
pushdown(u,L,R);
mid=L+R>>1;
return (query(u*2,L,mid)+query(u*2+1,mid+1,R))%mod;
}
}
void mu(int u,int L,int R,int x)
{
if(inrange(L,R,l,r))
{
w[u].tagjia=(w[u].tagjia*x)%mod;
w[u].tagch=(w[u].tagch*x)%mod;
w[u].v=(w[u].v*(x))%mod;
}
else if(outrange(L,R,l,r))return ;
else //部分相交
{
pushdown(u,L,R);
mid=L+R>>1;
mu(u*2,L,mid,x);
mu(u*2+1,mid+1,R,x);
pushup(u);
}
}
void jia(int u,int L,int R,int x)
{
if(inrange(L,R,l,r))
{
mak(u,L,R,x,2);
}
else if(outrange(L,R,l,r))
{
return ;
}
else
{
mid=L+R>>1;
pushdown(u,L,R);
jia(u*2,L,mid,x);
jia(u*2+1,mid+1,R,x);
pushup(u);
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>q>>mod;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1,1,n);
while(q--)
{
cin>>op;
if(op==1)//乘
{
cin>>l>>r>>k;
mu(1,1,n,k);
}
else if(op==2)//加
{
cin>>l>>r>>k;
jia(1,1,n,k);
}
else //查
{
cin>>l>>r;
cout<<query(1,1,n)<<endl;
}
}
return 0;
}
全wa求调