#include<bits/stdc++.h>
using namespace std;
long long n,p,a,b,ans,x,y,caozuo;
struct node
{
long long l,r,f,w;
}tree[400001];
inline void build(long long k,long long ll,long long rr)
{
tree[k].l=ll;
tree[k].r=rr;
if(tree[k].l==tree[k].r)
{
cin>>tree[k].w;
return;
}
long long m=(ll+rr)/2;
build(k*2,ll,m);
build(k*2+1,m+1,rr);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
inline void down(long long k)
{
tree[k*2].f+=tree[k].f;
tree[k*2+1].f+=tree[k].f;
tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].f=0;
}
inline void ask_point(long long k)
{
if(tree[k].l==tree[k].r)
{
ans=tree[k].w;
return ;
}
if(tree[k].f)
down(k);
long long mid=(tree[k].l+tree[k].r)/2;
if(x<=mid)
ask_point(k*2);
else
ask_point(k*2+1);
}
inline void change_point(long long k)
{
if(tree[k].l==tree[k].r)
{
tree[k].w+=y;
return ;
}
if(tree[k].f)
down(k);
long long mid=(tree[k].l+tree[k].r)/2;
if(x<=mid)
change_point(k*2);
else
change_point(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
inline void ask_interval(long long k)
{
if(tree[k].l>=a&&tree[k].r<=b)
{
ans+=tree[k].w;
return ;
}
if(tree[k].f)
down(k);
long long mid=(tree[k].l+tree[k].r)/2;
if(a<=mid)
ask_interval(k*2);
if(b>mid)
ask_interval(k*2+1);
}
inline void change_interval(long long k)
{
if(tree[k].l>=a&&tree[k].r<=b)
{
tree[k].w+=(tree[k].r-tree[k].l+1)*y;
tree[k].f+=y;
return;
}
if(tree[k].f)
down(k);
long long mid=(tree[k].l+tree[k].r)/2;
if(a<=mid)
change_interval(k*2);
if(b>mid)
change_interval(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
inline void changet_interval(long long k)
{
if(tree[k].l>=a&&tree[k].r<=b)
{
tree[k].w*=(tree[k].r-tree[k].l+1)*y;
tree[k].f*=y;
return;
}
if(tree[k].f)
down(k);
long long mid=(tree[k].l+tree[k].r)/2;
if(a<=mid)
changet_interval(k*2);
if(b>mid)
changet_interval(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
int main()
{
cin>>n>>caozuo;
long long ppp;
cin>>ppp;
build(1,1,n);
for(long long qq=1;qq<=caozuo;qq++)
{
long long gg;
cin>>gg;
if(gg==2)
{
cin>>a>>b>>y;
change_interval(1);
}
if(gg==1)
{
cin>>a>>b>>y;
changet_interval(1);
//cout<<ans<<endl;
}
if(gg==3)
{
cin>>a>>b;
ask_interval(1);
cout<<(ans%ppp)<<endl;
ans=0;
}
}
return 0;
}
//退役两年刚刚回来不久,下载数据一看跟输出相去甚远,求帮忙改错