#include<bits/stdc++.h>
using namespace std;
int n,m,p,a[100005];
struct node {
long long id,l,r,sum,add,mul;
} tree[400005];
void build(int id,int l,int r) {
tree[id].mul=1;
tree[id].add=0;
tree[id].l=l;
tree[id].r=r;
if(l==r) {
tree[id].sum=a[l];
return;
}
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
tree[id].sum%=p;
}
void pushdown(int id) {
tree[id*2].sum=(tree[id*2].sum*tree[id].mul+tree[id].add*(tree[2*id].r-tree[2*id].l+1))%p;
tree[id*2+1].sum=(tree[id*2+1].sum*tree[id].mul+tree[id].add*(tree[2*id+1].r-tree[2*id+1].l+1))%p;
//维护懒标记
tree[id*2].mul=(tree[id*2].mul*tree[id].mul)%p;
tree[id*2+1].mul=(tree[id*2+1].mul*tree[id].mul)%p;
tree[id*2].add=(tree[id*2].add*tree[id].mul+tree[id].add)%p;
tree[id*2+1].add=(tree[id*2+1].add*tree[id].mul+tree[id].add)%p;
tree[id].mul=1;
tree[id].add=0;
return;
}
void update1(int id,int l,int r,int v) { //加法
if(tree[id].r<l||tree[id].l>r)return;
if(tree[id].l>=l&&tree[id].r<=r) {
tree[id].add=(tree[id].add+v)%p;
tree[id].sum=(tree[id].sum+(tree[id].r-tree[id].l+1)*v)%p;
return;
}
pushdown(id);
int m=(l+r)/2;
update1(id*2,l,m,v);
update1(id*2+1,m+1,r,v);
tree[id].sum=(tree[id*2].sum+tree[id*2+1].sum)%p;
}
void update2(int id,int l,int r,int v) { //乘法
if(tree[id].r<l||tree[id].l>r)return;
if(tree[id].l>=l&&tree[id].r<=r) {
tree[id].sum=(tree[id].sum*v)%p;
tree[id].mul=(tree[id].mul*v)%p;
tree[id].add=(tree[id].add*v)%p;
return;
}
pushdown(id);
update2(id*2,l,r,v);
update2(id*2+1,l,r,v);
tree[id].sum=(tree[id*2].sum+tree[id*2+1].sum)%p;
}
long long query(int id,int l,int r) {
if(tree[id].r<l||tree[id].l>r)return 0;
if(tree[id].l>=l&&tree[id].r<=r)return tree[id].sum;
pushdown(id);
return (query(id*2,l,r)+query(id*2+1,l,r))%p;
}
int main() {
scanf("%d%d%d",&n,&m,&p);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
build(1,1,n);
for(int i=1; i<=m; i++) {
int o,x,y,k;
scanf("%d",&o);
if(o==2) {
scanf("%d%d%d",&x,&y,&k);
update1(1,x,y,k);
} else if(o==1) {
scanf("%d%d%d",&x,&y,&k);
update2(1,x,y,k);
} else {
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,x,y));
}
}
return 0;
}