#include <bits/stdc++.h>
#define int long long
using namespace std;
struct jc {
int nul, add, sum;
} tree[10000005];
int n, m, mod, a[1000005], op, k;
void build (int p, int l, int r) {
tree[p].nul = 1;
tree[p].add = 0;
if (l == r) {
tree[p].sum = a[l];
return ;
}
int mid = (l + r) / 2;
build (p * 2, l, mid);
build (p * 2 + 1, mid + 1, r);
tree[p].sum = tree[p * 2].sum + tree[p * 2 + 1].sum;
}
void bj (int p, int l, int r) {
int mid = (l + r) / 2;
tree[p * 2].sum = (tree[p * 2].sum * tree[p].nul + tree[p].add * (m - l + 1)) % mod;
tree[p * 2 + 1].sum = (tree[p * 2 + 1].sum * tree[p].nul + tree[p].add * (r - m)) % mod;
tree[p * 2].nul = (tree[p * 2].nul * tree[p].nul) % mod;
tree[p * 2 + 1].nul = (tree[p * 2 + 1].nul * tree[p].nul) % mod;
tree[p * 2].add = (tree[p * 2].add * tree[p].nul + tree[p].add) % mod;
tree[p * 2 + 1].add = (tree[p * 2 + 1].add * tree[p].nul + tree[p].add) % mod;
tree[p].add = 0;
tree[p].nul = 1;
}
void up1 (int p, int ll, int rr, int l, int r, int k) {
if (l > ll || r < rr) return ;
if (l <= ll && r >= rr) {
tree[p].sum = (tree[p].sum * k) % mod;
tree[p].add = (tree[p].add * k) % mod;
tree[p].nul = (tree[p].nul * k) % mod;
return ;
}
bj (p, ll, rr);
int mid = (ll + rr) / 2;
up1 (p * 2, ll, mid, l, r, k);
up1 (p * 2 + 1, mid + 1, rr, l, r, k);
tree[p].sum = (tree[p * 2].sum + tree[p * 2 + 1].sum) % mod;
}
void up2 (int p, int ll, int rr, int l, int r, int k) {
if (l > ll || r < rr) return ;
if (l <= ll && r >= rr) {
tree[p].sum = (tree[p].sum + k * (rr - ll + 1)) % mod;
tree[p].add = (tree[p].add + k) % mod;
return ;
}
bj (p, ll, rr);
int mid = (ll + rr) / 2;
up2 (p * 2, ll, mid, l, r, k);
up2 (p * 2 + 1, mid + 1, rr, l, r, k);
tree[p].sum = (tree[p * 2].sum + tree[p * 2 + 1].sum) % mod;
}
int ask (int p, int ll, int rr, int l, int r) {
if (l > ll || r < rr) return 0;
if (l <= ll && r >= rr) return tree[p].sum;
int mid = (ll + rr) / 2;
bj (p, ll, rr);
return (ask (p * 2, ll, mid, l, r) + ask (p * 2 + 1, mid + 1, rr, l, r)) % mod;
}
signed main () {
ios::sync_with_stdio(0);
cin >> n >> m >> mod;
for (int i = 1; i <= n; i++) cin >> a[i];
build (1, 1, n);
while (m--) {
int l, r;
cin >> op >> l >> r;
if (op == 1) {
cin >> k;
up1 (1, 1, n, l, r, k);
}
else if (op == 2) {
cin >> k;
up2 (1, 1, n, l, r, k);
}
else cout << ask (1, 1, n, l, r) << '\n';
}
return 0;
}