#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
long long ans=0,a[N];
struct node{
int l,r;
long long sum,j,k;
}tree[N<<2];
void pushup(int i)
{
tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
}
void build(int i,int l,int r)
{
tree[i].l=l;tree[i].r=r;tree[i].k=0;
if(l==r)
{
tree[i].sum=a[l];
return ;
}
int mid=l+r>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
pushup(i);
}
void pushdown(int i)
{
if(tree[i].k)
{
tree[i<<1].sum+=(tree[i<<1].r-tree[i<<1].l+1)*tree[i].k;
tree[i<<1|1].sum+=(tree[i<<1|1].r-tree[i<<1|1].l+1)*tree[i].k;
tree[i<<1].k+=tree[i].k;
tree[i<<1|1].k+=tree[i].k;
tree[i].k=0;
}
}
void add(int i,int l,int r,long long k)
{
if(tree[i].l>=l && tree[i].r<=r)
{
tree[i].sum=tree[i].sum+(tree[i].r-tree[i].l+1)*k;
tree[i].k+=k;
return ;
}
pushdown(i);
if(tree[i<<1].r>=l)
{
add(i<<1,l,r,k);
}
if(tree[i<<1|1].l<=r)
{
add(i<<1|1,l,r,k);
}
pushup(i);
}
void abb(int i,int l,int r,long long k)
{
if(tree[i].l>=l && tree[i].r<=r)
{
tree[i].sum=tree[i].sum*k;
tree[i].k=tree[i].k*k;
return ;
}
pushdown(i);
if(tree[i<<1].r>=l)
{
abb(i<<1,l,r,k);
}
if(tree[i<<1|1].l<=r)
{
abb(i<<1|1,l,r,k);
}
pushup(i);
}
void find(int i,int l,int r)
{
if(tree[i].l>=l && tree[i].r<=r)
{
ans+=tree[i].sum;
return ;
}
pushdown(i);
if(tree[i<<1].r>=l)
{
find(i<<1,l,r);
}
if(tree[i<<1|1].l<=r)
{
find(i<<1|1,l,r);
}
}
int main()
{
int n,q,m;
cin >> n >> q >> m;
for(int i=1;i<=n;i++)
{
cin >> a[i];
}
build(1,1,n);
while(q--)
{
int op,x,y;
cin >> op >> x >> y;
long long k;
if(op==2)
{
cin >> k;
add(1,x,y,k);
}
else if(op==1)
{
cin >> k;
abb(1,x,y,k);
}
else
{
ans=0;
find(1,x,y);
cout << ans%m << endl;
}
}
}