rt
#include <cmath>
#include <iostream>
using namespace std;
using ll = long long;
const ll kMaxN = 2e5 + 1;
ll n, q, m, a[kMaxN], id[kMaxN], bl[kMaxN], lbl[kMaxN], rbl[kMaxN], atag[kMaxN], len;
void C1(ll x, ll y, ll add) { // 区间加
if (id[x] != id[y]) {
for (ll i = x; i <= rbl[id[x]]; i++) { // 处理[x, rx]
a[i] = (a[i] + atag[id[x]] + add) % m;
bl[id[i]] = (bl[id[i]] + add) % m;
}
for (ll i = id[x] + 1; i <= id[y] - 1; i++) { // 处理整块
atag[i] = (atag[i] + add) % m;
bl[i] = (bl[i] + (rbl[i] - lbl[i] + 1) * add % m) % m;
}
for (ll i = lbl[id[y]]; i <= y; i++) { // 处理 [ly, y]
a[i] = (a[i] + atag[id[x]] + add) % m;
bl[id[i]] = (bl[id[i]] + add) % m;
}
} else {
for (ll i = x; i <= y; i++) { // [x, y]
a[i] = (a[i] + atag[id[x]] + add) % m;
bl[id[i]] = (bl[id[i]] + add) % m;
}
}
}
void C2(ll x, ll y, ll mod) { // 区间乘
if (id[x] != id[y]) {
for (ll i = x; i <= rbl[id[x]]; i++) { // 处理散块
ll j = id[x];
bl[j] = (bl[j] - a[i] - atag[j] + m * 10) % m; // 减去之前的
a[i] = (a[i] + atag[j]) % m * mod % m;
bl[j] = (bl[j] + a[i]) % m; // 加上之后的
}
for (ll i = id[x] + 1; i <= id[y] - 1; i++) { // 处理整块
bl[i] = bl[i] * mod % m;
atag[i] = atag[i] * mod % m;
}
for (ll i = lbl[id[y]]; i <= y; i++) {
ll j = id[y];
bl[j] = (bl[j] - a[i] - atag[j] + m * 10) % m;
a[i] = (a[i] + atag[j]) % m * mod % m;
bl[j] = (bl[j] + a[i]) % m;
}
} else {
for (ll i = x; i <= y; i++) { // 处理 [x, y]
ll j = id[x];
bl[j] = (bl[j] - a[i] - atag[j] + m * 10) % m;
a[i] = (a[i] + atag[j]) % m * mod % m;
bl[j] = (bl[j] + a[i]) % m;
}
}
}
ll G(ll x, ll y) { // 询问
ll ans = 0;
if (id[x] != id[y]) {
for (ll i = x; i <= rbl[id[x]]; i++) { // 处理整块
ll j = id[x];
ans = (ans + a[i] + atag[j]) % m; // 加上每一个的权值
}
for (ll i = lbl[id[y]]; i <= y; i++) {
ll j = id[y];
ans = (ans + a[i] + atag[j]) % m;
}
for (ll i = id[x] + 1; i <= id[y] - 1; i++) { // 处理整块
ans = (ans + bl[i]) % m; //直接加
}
} else {
for (ll i = x; i <= y; i++) { // [x, y]
ll j = id[x];
ans = (ans + a[i] + atag[j]) % m;
}
}
return ans;
}
int main() {
cin >> n >> q >> m, len = sqrt(n);
ll c = (n + len - 1) / len;
for (ll i = 1, x; i <= n; i++) { // 预处理
cin >> a[i];
id[i] = (i + len - 1) / len;
bl[id[i]] += a[i];
rbl[id[i]] = i;
lbl[id[i] + 1] = i + 1;
}
lbl[1] = 1;
for (ll op, x, y, k; q; q--) {
cin >> op >> x >> y;
if (op == 2) {
cin >> k;
C1(x, y, k);
} else if (op == 1) {
cin >> k;
C2(x, y, k);
} else {
cout << G(x, y) << '\n';
}
}
return 0;
}