#include<bits/stdc++.h>
#define ln (d<<1)
#define rn (d<<1|1)
#define mid ((r+l)>>1)
#define LL long long
using namespace std;
struct node {
int l,r;
LL num,ab,mb=1;
} tree[400005];
int n,m,a[100005],f,x,y;
LL mod,z;
void intn(int d,int l,int r) {
tree[d].l=l;
tree[d].r=r;
tree[d].mb=1;
if(l==r) {
tree[d].num=(LL)(a[l]);
return;
}
intn(ln,l,mid);
intn(rn,mid+1,r);
tree[d].num=tree[ln].num+tree[rn].num;
tree[d].num%=mod;
}
void New(int d){
if(tree[d].mb){
tree[ln].mb*=tree[d].mb;
tree[rn].mb*=tree[d].mb;
tree[ln].num*=tree[d].mb;
tree[rn].num*=tree[d].mb;
tree[d].mb=1;
}
if(tree[d].ab){
tree[ln].ab+=tree[d].ab;
tree[rn].ab+=tree[d].ab;
tree[ln].num+=tree[d].ab*(tree[ln].r-tree[ln].l+1);
tree[rn].num+=tree[d].ab*(tree[rn].r-tree[rn].l+1);
tree[d].ab=0;
}
}
void sw(int d,bool f) {
if(tree[d].l>=x&&tree[d].r<=y) {
if(f) {
tree[d].num*=z;
tree[d].num%=mod;
tree[d].mb*=z;
} else {
tree[d].num+=z*(tree[d].r-tree[d].l+1);
tree[d].num%=mod;
tree[d].ab+=z;
}
return;
}
New(d);
if(tree[ln].r>=x)sw(ln,f);
if(tree[rn].l<=y)sw(rn,f);
tree[d].num=tree[ln].num+tree[rn].num;
tree[d].num%=mod;
}
LL get(int d){
if(tree[d].l>=x&&tree[d].r<=y)return tree[d].num;
New(d);
return ((tree[ln].r>=x?get(ln):0)+(tree[rn].l<=y?get(rn):0))%mod;
}
int main() {
cin>>n>>m>>mod;
for(int i=1; i<=n; i++)cin>>a[i];
intn(1,1,n);
while(m--) {
cin>>f>>x>>y;
if(f!=3) {
cin>>z;
sw(1,f&1);
}else printf("%lld\n",get(1));
}
return 0;
}