#include<bits/stdc++.h>
using namespace std;
int n,m,mod,op;
long long x,y,k;
long long a[100009];
struct tr{
int l,r;
long long sum;
long long clazy;
int lazy;
}tree[400009];
void build_tree(int rt,int l,int r){
if(l==r){
tree[rt].sum=(a[l])%mod;
tree[rt].l=l;
tree[rt].r=r;
tree[rt].lazy=0;
tree[rt].clazy=1;
return;
}
int mid=(l+r)/2;
build_tree(rt*2,l,mid);
build_tree(rt*2+1,mid+1,r);
tree[rt].sum=(tree[rt*2].sum+tree[rt*2+1].sum)%mod;
tree[rt].l=l;
tree[rt].r=r;
tree[rt].lazy=0;
tree[rt].clazy=1;
}
void pushdown(int rt){
tree[rt*2].sum=tree[rt*2].sum*tree[rt].clazy+(tree[rt*2].r-tree[rt*2].l+1)*tree[rt].lazy;
tree[rt*2+1].sum=tree[rt*2+1].sum*tree[rt].clazy+(tree[rt*2+1].r-tree[rt*2+1].l+1)*tree[rt].lazy;
tree[rt*2+1].clazy*=tree[rt].clazy;
tree[rt*2].clazy*=tree[rt].clazy;
tree[rt*2].clazy%=mod;
tree[rt*2+1].clazy%=mod;
tree[rt*2].sum%=mod;
tree[rt*2+1].sum%=mod;
tree[rt*2].lazy=(tree[rt*2].lazy*tree[rt].clazy+tree[rt].lazy)%mod;
tree[rt*2+1].lazy=(tree[rt*2+1].lazy*tree[rt].clazy+tree[rt].lazy)%mod;
tree[rt].lazy=0;
tree[rt].clazy=1;
}
void update(int rt,int l,int r,long long k){
if(l==tree[rt].l && r==tree[rt].r){
tree[rt].lazy+=k;
tree[rt].sum+=(r-l+1)*k;
tree[rt].lazy%=mod;
tree[rt].sum%=mod;
return;
}
pushdown(rt);
int mid=(tree[rt].r+tree[rt].l)/2;
if(r<=mid){
update(rt*2,l,r,k);
}else if(l>=mid+1){
update(rt*2+1,l,r,k);
}else{
update(rt*2,l,mid,k);
update(rt*2+1,mid+1,r,k);
}
tree[rt].sum=(tree[rt*2].sum+tree[rt*2+1].sum)%mod;
}
void update1(int rt,int l,int r,long long k){
if(l==tree[rt].l && r==tree[rt].r){
tree[rt].clazy*=k;
tree[rt].lazy*=k;
tree[rt].sum*=k;
tree[rt].sum%=mod;
tree[rt].lazy%=mod;
tree[rt].clazy%=mod;
return;
}
pushdown(rt);
int mid=(tree[rt].r+tree[rt].l)/2;
if(r<=mid){
update1(rt*2,l,r,k);
}else if(l>=mid+1){
update1(rt*2+1,l,r,k);
}else{
update1(rt*2,l,mid,k);
update1(rt*2+1,mid+1,r,k);
}
tree[rt].sum=(tree[rt*2].sum+tree[rt*2+1].sum)%mod;
}
long long query(int rt,int l,int r){
if(l==tree[rt].l && r==tree[rt].r){
return tree[rt].sum%mod;
}
pushdown(rt);
int mid=(tree[rt].r+tree[rt].l)/2;
long long res=0;
if(r<=mid){
res+=query(rt*2,l,r)%mod;
}else if(l>=mid+1){
res+=query(rt*2+1,l,r)%mod;
}else{
res+=query(rt*2,l,mid)%mod;
res+=query(rt*2+1,mid+1,r)%mod;
}
return res%mod;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>mod;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]%=mod;
}
build_tree(1,1,n);
while(m--){
cin>>op;
if(op==3){
cin>>x>>y;
cout<<query(1,x,y)<<'\n';
}else if(op==2){
cin>>x>>y>>k;
update(1,x,y,k);
}else{
cin>>x>>y>>k;
update1(1,x,y,k);
}
}
return 0;
}