#include<bits/stdc++.h>
using namespace std;
long long p,a[100005];
struct node {
long long n,sum,pro;
} tree[400005];
void build(int root,int l,int r) {
tree[root].sum=0,tree[root].pro=1;
if (l==r) {
tree[root].n=a[l];
} else {
int mid=l+r>>1;
build(root<<1,l,mid);
build((root<<1)+1,mid+1,r);
tree[root].n=tree[root<<1].n+tree[(root<<1)+1].n;
}
tree[root].n%=p;
return;
}
void mt(int root,int l,int r) {
int mid=l+r>>1;
tree[root<<1].n=(tree[root<<1].n*tree[root].pro+tree[root].sum*(mid-l+1))%p;
tree[(root<<1)+1].n=(tree[(root<<1)+1].n*tree[root].pro+tree[root].sum*(r-mid))%p;
tree[root<<1].pro=(tree[root<<1].pro*tree[root].pro)%p;
tree[(root<<1)+1].pro=(tree[(root<<1)+1].pro*tree[root].pro)%p;
tree[root<<1].sum=(tree[root<<1].sum*tree[root].pro+tree[root].sum)%p;
tree[(root<<1)+1].sum=(tree[(root<<1)+1].sum*tree[root].pro+tree[root].sum)%p;
tree[root].pro=1;
tree[root].sum=0;
}
void add(int root,int l1,int r1,int l2,int r2,long long k) {
if (r2<l1||r1<l2)return;
if (l2<=l1&&r1<=r2) {
tree[root].sum=(tree[root].sum+k)%p;
tree[root].n=(tree[root].n+k*(r1-l1+1))%p;
return;
}
mt(root,l1,r1);
int mid=l1+r1>>1;
add(root<<1,l1,mid,l2,r2,k);
add((root<<1)+1,mid+1,r1,l2,r2,k);
tree[root].n=(tree[root<<1].n+tree[(root<<1)+1].n)%p;
return;
}
void mul(int root,int l1,int r1,int l2,int r2,long long k) {
if (r2<l1||r1<l2)return;
if (l2<=l1&&r1<=r2) {
tree[root].n=(tree[root].n*k)%p;
tree[root].pro=(tree[root].pro*k)%p;
tree[root].sum=(tree[root].sum*k)%p;
return;
}
mt(root,l1,r1);
int mid=l1+r1>>1;
add(root<<1,l1,mid,l2,r2,k);
add((root<<1)+1,mid+1,r1,l2,r2,k);
tree[root].n=(tree[root<<1].n+tree[(root<<1)+1].n)%p;
return;
}
long long query(int root,int l1,int r1,int l2,int r2) {
if (r2<l1||r1<l2)return 0;
if (l2<=l1&&r1<=r2)return tree[root].n;
mt(root,l1,r1);
int mid=l1+r1>>1;
return (query(root<<1,l1,mid,l2,r2)+query((root<<1)+1,mid+1,r1,l2,r2))%p;
}
int main() {
int n,q;
cin>>n>>q>>p;
for (int i=1; i<=n; cin>>a[i++]);
build(1,1,n);
while (q--) {
int op,l,r;
long long k;
cin>>op>>l>>r;
if (op==1) {
cin>>k;
mul(1,1,n,l,r,k);
} else if (op==2) {
cin>>k;
add(1,1,n,l,r,k);
} else {
cout<<query(1,1,n,l,r)<<'\n';
}
}
return 0;
}