#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX = 1e5+10;
int num[MAX];
int n,m,mod;
struct segTree
{
int left,right;
ll value,mark,mul;
}bt[MAX*4];
inline void build(int le,int ri,int p)
{
bt[p].left = le,bt[p].right = ri,bt[p].mark = 0, bt[p].mul = 1;
if(le==ri) bt[p].value = num[le];
else
{
int mid = (le+ri)>>1;
build(le,mid,p<<1);
build(mid+1,ri,p<<1|1);
bt[p].value = bt[p<<1].value + bt[p<<1|1].value;
}
}
inline void push_down(int p)
{
int len = bt[p].right - bt[p].left + 1;
bt[p<<1].value = (bt[p].mark*(len-len/2) + bt[p<<1].value*bt[p].mul)%mod;
bt[p<<1|1].value = (bt[p].mark*(len>>1) + bt[p<<1|1].value*bt[p].mul)%mod;
bt[p<<1].mul = (bt[p<<1].mul * bt[p].mul)%mod;
bt[p<<1|1].mul = (bt[p<<1].mul*bt[p].mul)%mod;
bt[p<<1].mark = (bt[p<<1].mark*bt[p].mul + bt[p].mark)%mod;
bt[p<<1|1].mark = (bt[p<<1|1].mark*bt[p].mul + bt[p].mark)%mod;
bt[p].mark = 0;
bt[p].mul = 1;
}
void add(int d,int p,int l,int r)
{
if(bt[p].left>r||bt[p].right<l) return ;
else if(bt[p].left>=l&&bt[p].right<=r)
{
bt[p].value = (bt[p].value + (bt[p].right-bt[p].left+1)*d)%mod ;
if(bt[p].left<bt[p].right) bt[p].mark = (bt[p].mark+d)%mod;
}
else
{
push_down(p);
add(d,p<<1,l,r);
add(d,p<<1|1,l,r);
bt[p].value = (bt[p<<1].value + bt[p<<1|1].value)%mod;
}
}
void multi(int d,int p,int l,int r)
{
if(bt[p].left>r||bt[p].right<l) return ;
else if(bt[p].left>=l&&bt[p].right<=r)
{
bt[p].mark = (bt[p].mark*d)%mod;
bt[p].value = (bt[p].value*d)%mod;
bt[p].mul = (bt[p].mul*d)%mod;
}
else
{
push_down(p);
multi(d,p<<1,l,r);
multi(d,p<<1|1,l,r);
bt[p].value = (bt[p<<1].value + bt[p<<1|1].value)%mod;
}
}
ll query(int p,int l,int r)
{
if(bt[p].left>r||bt[p].right<l) return 0;
else if(bt[p].left>=l&&bt[p].right<=r) return bt[p].value;
else
{
push_down(p);
return (query(p<<1,l,r) + query(p<<1|1,l,r))%mod;
}
}
main()
{
cin>>n>>m>>mod;
for(int i=1;i<=n;i++) cin>>num[i];
build(1,n,1);
while(m--)
{
int order,x,y,k;
scanf("%d",&order);
if(order==1)
{
scanf("%d%d%d",&x,&y,&k);
multi(k,1,x,y);
}
else if(order==2)
{
scanf("%d%d%d",&x,&y,&k);
add(k,1,x,y);
}
else
{
scanf("%d%d",&x,&y);
cout<<query(1,x,y)<<endl;
}
}
return 0;
}