#include<iostream>
#define lc p << 1
#define rc p << 1 | 1
#define int long long
using namespace std;
const int maxn = 1e5 + 1;
struct Tree{
int l,r,sum,add,mul;
}tr[maxn << 2];
int n,q,m,a[maxn];
void pushup(int p){
tr[p].sum = tr[lc].sum + tr[rc].sum;
tr[p].sum %= m;
}
void pushdown(int p){
if(tr[p].mul != 1){
tr[lc].sum *= tr[p].mul;
tr[lc].sum %= m;
tr[lc].mul *= tr[p].mul;
tr[lc].mul %= m;
tr[rc].sum *= tr[p].mul;
tr[rc].sum %= m;
tr[rc].mul *= tr[p].mul;
tr[rc].mul %= m;
tr[p].mul = 1;
}
if(tr[p].add){
tr[lc].sum += tr[p].add * (tr[lc].r - tr[lc].l + 1);
tr[lc].sum %= m;
tr[lc].add += tr[p].add;
tr[lc].add %= m;
tr[rc].sum += tr[p].add * (tr[rc].r - tr[rc].l + 1);
tr[rc].sum %= m;
tr[rc].add += tr[p].add;
tr[rc].add %= m;
tr[p].add = 0;
}
}
void build(int p,int l,int r){
tr[p] = (Tree) {l,r,a[l]%m,0,1};
if(l == r) return;
int m = l + (r - l >> 1);
build(lc,l,m);
build(rc,m+1,r);
pushup(p);
}
void update1(int p,int x,int y,int k){
if(x <= tr[p].l && tr[p].r <= y){
tr[p].add *= k;
tr[p].add %= m;
tr[p].sum *= k;
tr[p].sum %= m;
tr[p].mul *= k;
tr[p].mul %= m;
return;
}
pushdown(p);
int m = tr[p].l + (tr[p].r - tr[p].l >> 1);
if(x <= m) update1(lc,x,y,k);
if(y > m) update1(rc,x,y,k);
pushup(p);
}
void update2(int p,int x,int y,int k){
if(x <= tr[p].l && tr[p].r <= y){
tr[p].sum += (tr[p].r - tr[p].l + 1) * k;
tr[p].sum %= m;
tr[p].add += k;
tr[p].add %= m;
return;
}
pushdown(p);
int m = tr[p].l + (tr[p].r - tr[p].l >> 1);
if(x <= m) update2(lc,x,y,k);
if(y > m) update2(rc,x,y,k);
pushup(p);
}
int query(int p,int l,int r){
if(l <= tr[p].l && tr[p].r <= r) return tr[p].sum;
pushdown(p);
int m = tr[p].l + (tr[p].r - tr[p].l >> 1),res = 0;
if(l <= m) res = query(lc,l,r);
if(r > m) res += query(rc,l,r);
return res;
}
signed main(){
scanf("%d%d%lld",&n,&q,&m);
for(int i = 1;i <= n;++i) scanf("%lld",&a[i]);
build(1,1,n);
for(int i = 0,opt,x,y,k;i < q;++i){
scanf("%d%d%d",&opt,&x,&y);
if(opt == 1){
scanf("%lld",&k);
update1(1,x,y,k);
}else if(opt == 2){
scanf("%lld",&k);
update2(1,x,y,k);
}else printf("%lld\n",query(1,x,y)%m);
}
return 0;
}