#include <bits/stdc++.h>
#define int long long
#define ls pos * 2
#define rs pos * 2 + 1
using namespace std;
const int MAXN = 4e5 + 1;
struct node {
int l, r, a, add, mul;
} tree[MAXN << 2];
int n, m, q, mod, a[MAXN];
void build(int pos, int l, int r) {
tree[pos].l = l, tree[pos].r = r, tree[pos].mul = 1;
if (l == r)
return void(tree[pos].a = a[l] % mod);
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
tree[pos].a = (tree[ls].a + tree[rs].a) % mod;
}
void pushdown(int pos) {
tree[ls].a = (tree[pos].mul * tree[ls].a + ((tree[ls].r - tree[ls].l + 1) * tree[pos].add) % mod) % mod;
tree[rs].a = (tree[pos].mul * tree[rs].a + ((tree[rs].r - tree[rs].l + 1) * tree[pos].add) % mod) % mod;
tree[ls].mul = (tree[ls].mul * tree[pos].mul) % mod;
tree[rs].mul = (tree[rs].mul * tree[pos].mul) % mod;
tree[ls].add = (tree[ls].add * tree[pos].mul + tree[pos].add) % mod;
tree[rs].add = (tree[rs].add * tree[pos].mul + tree[pos].add) % mod;
tree[pos].mul = 1, tree[pos].add = 0;
}
void add(int pos, int l, int r, int ad) {
if (tree[pos].l >= l && tree[pos].r <= r) {
tree[pos].add = (tree[pos].add + ad) % mod;
tree[pos].a = (tree[pos].a + (tree[pos].r - tree[pos].l + 1) * ad) % mod;
return;
} pushdown(pos);
tree[pos].a = (tree[ls].a + tree[rs].a) % mod;
int mid = (tree[pos].l + tree[pos].r) >> 1;
if (l <= mid)
add(ls, l, r, ad);
if (r > mid)
add(rs, l, r, ad);
tree[pos].a = (tree[ls].a + tree[rs].a) % mod;
}
void mul(int pos, int l, int r, int mu) {
if (tree[pos].l >= l && tree[pos].r <= r) {
tree[pos].add = tree[pos].add * mu % mod;
tree[pos].mul = tree[pos].mul * mu % mod;
tree[pos].a = tree[pos].a * mu % mod;
return;
} pushdown(pos);
tree[pos].a = (tree[ls].a + tree[rs].a);
int mid = (tree[pos].l + tree[pos].r) >> 1;
if (l <= mid)
add(ls, l, r, mu);
if (r > mid)
add(rs, l, r, mu);
tree[pos].a = (tree[ls].a + tree[rs].a) % mod;
}
int query(int pos, int l, int r) {
if (tree[pos].l >= l && tree[pos].r <= r)
return tree[pos].a;
pushdown(pos);
int ans = 0, mid = (tree[pos].l + tree[pos].r) >> 1;
if (l <= mid)
ans = (ans + query(ls, l, r)) % mod;
if (r > mid)
ans = (ans + query(rs, l, r)) % mod;
return ans;
}
signed main(){
cin >> n >> q >> mod, m = n - 1;
for (int i = 1; i <= n; i++)
cin >> a[i];
build(1, 1, n);
while (q--) {
int op, x, y, k;
cin >> op >> x >> y;
if (op == 1)
cin >> k, add(1, x, y, k);
if (op == 2)
cin >> k, mul(1, x, y, k);
if (op == 3)
cout << query(1, x, y) << '\n';
} return 0;
}