#include<bits/stdc++.h>
using namespace std;
struct SegmentTree{
int l,r;
long long sum,add,mul;
}tree[4*100010];
int a[100010],n,m,q,op,x,y,k;
void build(int p,int l,int r){
tree[p].l=l,tree[p].r=r,tree[p].mul=1;
if(l==r){
tree[p].sum=a[l]%m;
return;
}
long long mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
tree[p].sum=(tree[p*2].sum+tree[p*2+1].sum)%m;
}
void spread(int p){
tree[p*2].sum=(long long)((tree[p*2].sum*tree[p].mul)%m+(tree[p].add*(tree[p*2].r-tree[p*2].l+1))%m)%m;
tree[p*2+1].sum=(long long)((tree[p*2+1].sum*tree[p].mul)%m+(tree[p].add*(tree[p*2+1].r-tree[p*2+1].l+1))%m)%m;
tree[p*2].add=(long long)(tree[p].add+tree[p*2].add)%m;
tree[p*2+1].add=(long long)(tree[p].add+tree[p*2+1].add)%m;
tree[p*2].mul=(long long)tree[p].mul*tree[p*2].mul%m;
tree[p*2+1].mul=(long long)tree[p].mul*tree[p*2+1].mul%m;
tree[p].add=0,tree[p].mul=1;
}
void change(int p,int l,int r,int d){
if(tree[p].l>=l&&tree[p].r<=r){
tree[p].sum=(long long)(d*(tree[p].r-tree[p].l+1)+tree[p].sum)%m;
tree[p].add=(d+tree[p].add)%m;
return;
}
spread(p);
long long mid=(tree[p].l+tree[p].r)>>1;
tree[p].sum=(tree[2*p].sum+tree[p*2+1].sum)%m;
if(l<=mid)change(p*2,l,r,d);
if(r>mid)change(p*2+1,l,r,d);
tree[p].sum=(tree[2*p].sum+tree[p*2+1].sum)%m;
}
void change2(int p,int l,int r,int d){
if(tree[p].l>=l&&tree[p].r<=r){
tree[p].sum=(tree[p].sum*d)%m;
tree[p].mul=d*tree[p].mul%m;
tree[p].add=(d*tree[p].add)%m;
return;
}
spread(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid)change2(p*2,l,r,d);
if(r>mid)change2(p*2+1,l,r,d);
tree[p].sum=(tree[2*p].sum+tree[p*2+1].sum)%m;
}
long long ask(int p,int l,int r){
if(l<=tree[p].l&&r>=tree[p].r)return tree[p].sum;
spread(p);
int mid=(tree[p].l+tree[p].r)>>1;
long long ans=0;
if(l<=mid)ans=(ans+ask(p*2,l,r))%m;
if(r>mid)ans=(ans+ask(p*2+1,l,r))%m;
return ans%m;
}
int main(){
scanf("%d%d%d",&n,&q,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build(1,1,n);
while(q--){
scanf("%d%d%d",&op,&x,&y);
if(op==2){
scanf("%d",&k);
change(1,x,y,k);
}else if(op==1){
scanf("%d",&k);
change2(1,x,y,k);
}else printf("%lld\n",ask(1,x,y));
}
return 0;
}