#include <iostream>
using namespace std;
typedef long long ll;
const int kMaxN = 1e5 + 7;
ll n, q, op, x, y, k, a[kMaxN], d[kMaxN << 2], b[kMaxN << 2], m, d2[kMaxN << 2];
inline ll ls(ll p) { return (p << 1); }
inline ll rs(ll p) { return (p << 1) | 1; }
inline ll gmid(ll l, ll r) { return (l + r) >> 1; }
inline void pd(ll p, ll l, ll r, ll k, ll c) { b[p] = (b[p] * c + k) % m, d2[p] = d2[p] * c % m, d[p] = (d[p] * c + (r - l + 1) * k) % m; }
void pushdown(ll p, ll l, ll r) {
ll mid = gmid(l, r);
pd(ls(p), l, mid, b[p], d2[p]), pd(rs(p), mid + 1, r, b[p], d2[p]);
b[p] = 0, d2[p] = 1;
}
void build(ll l, ll r, ll p) {
d2[p] = 1;
if (l == r) {
d[p] = a[l] % m;
return;
}
ll mid = gmid(l, r);
build(l, mid, ls(p)), build(mid + 1, r, rs(p)), d[p] = (d[ls(p)] + d[rs(p)]) % m;
}
void update(ll l, ll r, ll c, ll s, ll t, ll p, ll e) {
if (l <= s && t <= r) {
d[p] = (d[p] * e + c * (s - t + 1)) % m;
b[p] = (b[p] * e + c) % m;
d2[p] = (d2[p] * e) % m;
return;
}
ll mid = gmid(s, t);
pushdown(p, s, t);
if (l <= mid) {
update(l, r, c, s, mid, ls(p), e);
}
if (r > mid) {
update(l, r, c, mid + 1, t, rs(p), e);
}
d[p] = (d[ls(p)] + d[rs(p)]) % m;
}
ll query(ll l, ll r, ll s, ll t, ll p) {
if (l <= s && t <= r) {
return d[p] % m;
}
ll mid = gmid(s, t), sum = 0;
(l <= mid) && (sum += (query(l, r, s, mid, ls(p)) % m));
(r > mid) && (sum += (query(l, r, mid + 1, t, rs(p)) % m));
return sum % m;
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> q >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
build(1, n, 1);
while (q--) {
cin >> op >> x >> y;
if (op == 1) {
cin >> k, update(x, y, 0, 1, n, 1, k);
} else if (op == 2) {
cin >> k, update(x, y, k, 1, n, 1, 1);
} else {
cout << query(x, y, 1, n, 1) % m << '\n';
}
}
return 0;
}