#include<bits/stdc++.h>
using namespace std;
long long n,m,ans,p;
struct node
{
long long l,r,val,f;
}a[114514*4+1];
void tre(int l,int r,int root)
{
a[root].l=l;
a[root].r=r;
if(l==r)
{
cin>>a[root].val;
return;
}
int mid=(l+r)/2;
tre(l,mid,root*2);
tre(mid+1,r,root*2+1);a[root].val=a[root*2].val+a[root*2+1].val;
}
void down(int root)
{
a[root*2].f+=a[root].f;
a[root*2+1].f+=a[root].f;
a[root*2].val+=(a[root*2].r-a[root*2].l+1)*a[root].f;
a[root*2+1].val+=(a[root*2+1].r-a[root*2+1].l+1)*a[root].f;
a[root].f=0;
}
void sum(int x,int y,int root)
{
if(a[root].l>=x&&a[root].r<=y)
{
ans+=a[root].val;
return;
}
if(a[root].f)
down(root);
int mid=(a[root].l+a[root].r)/2;
if(x<=mid)
sum(x,y,root*2);
if(y>mid)
sum(x,y,root*2+1);
}
void add(int x,int y,int k,int root)
{
if(a[root].l>=x&&a[root].r<=y)
{
a[root].val+=(a[root].r-a[root].l+1)*k;
a[root].f+=k;
return;
}
if(a[root].f)
down(root);
int mid=(a[root].l+a[root].r)/2;
if(x<=mid)
add(x,y,k,root*2);
if(y>mid)
add(x,y,k,root*2+1);
a[root].val=a[root*2].val+a[root*2+1].val;
}
void add1(int x,int y,int k,int root)
{
if(a[root].l>=x&&a[root].r<=y)
{
a[root].val*=k;
a[root].f*=k;
return;
}
if(a[root].f)
down(root);
int mid=(a[root].l+a[root].r)/2;
if(x<=mid)
add(x,y,k,root*2);
if(y>mid)
add(x,y,k,root*2+1);
a[root].val=a[root*2].val+a[root*2+1].val;
}
int main()
{
cin>>n>>m>>p;
tre(1,n,1);
for(int i=1;i<=m;i++)
{
int x,y,f,k;
cin>>f>>x>>y;
if(f==1)
{
cin>>k;
add1(x,y,k,1);
}
else if(f==2)
{
cin>>k;
add(x,y,k,1);
}
else
{
ans=0;
sum(x,y,1);
cout<<ans%p<<endl;
}
}
return 0;
}