#include <bits/stdc++.h>
using namespace std;
#define int long long
#define maxn 100005
struct SegmentTree {
int l, r;
int dat, add, mul = 1;
} t[maxn * 4];
int n, m;
int P;
int a[maxn];
void build(int p, int l, int r) {
t[p].l = l, t[p].r = r;
if (l == r) { t[p].dat = a[l]; return; }
int mid = (l + r) >> 1;
build(p << 1, l, mid), build((p << 1) | 1, mid + 1, r);
t[p].dat = (t[p << 1].dat + t[(p << 1) | 1].dat) % P;
}
void spread(int p) {
t[p << 1].dat = ((t[p << 1].dat * t[p].mul % P) + (t[p << 1].r - t[p << 1].l + 1) * t[p].add % P) % P;
t[(p << 1) | 1].dat = ((t[(p << 1) | 1].dat * t[p].mul % P) + (t[(p << 1) | 1].r - t[(p << 1) | 1].l + 1) * t[p].add % P) % P;
t[p << 1].add += t[p].add, t[p << 1].mul *= t[p].mul;
t[(p << 1) | 1].add += t[p].add, t[(p << 1) | 1].dat *= t[p].mul;
t[p].add = 0, t[p].mul = 1;
}
void change1(int p, int l, int r, int k) {
if (l <= t[p].l && r >= t[p].r) {
t[p].dat = t[p].dat * k % P;
t[p].add = t[p].add * k % P;
t[p].mul = t[p].mul * k % P;
return;
}
spread(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) change1(p << 1, l, r, k);
if (r > mid) change1((p << 1) + 1, l, r, k);
t[p].dat = (t[p << 1].dat + t[(p << 1) | 1].dat) % P;
}
void change2(int p, int l, int r, int k) {
if (l <= t[p].l && r >= t[p].r) {
t[p].dat = (t[p].dat + (t[p].r - t[p].l + 1) * k) % P;
t[p].add = (t[p].add + k) % P;
return;
}
spread(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) change2(p << 1, l, r, k);
if (r > mid) change2((p << 1) | 1, l, r, k);
t[p].dat = (t[p << 1].dat + t[(p << 1) | 1].dat) % P;
}
int ask(int p, int l, int r) {
if (l <= t[p].l && r >= t[p].r) return t[p].dat;
spread(p);
int mid = (t[p].l + t[p].r) >> 1, ans = 0;
if (l <= mid) ans += ask(p << 1, l, r), ans %= P;
if (r > mid) ans += ask((p << 1) | 1, l, r), ans %= P;
return ans;
}
signed main() {
cin >> n >> m >> P;
for (int i = 1; i <= n; i++) cin >> a[i], a[i] %= P;
build(1, 1, n);
for (int i = 1; i <= m; i++) {
int flag, x, y, k;
cin >> flag;
if (flag == 1) {
cin >> x >> y >> k;
change1(1, x, y, k);
}
else if (flag == 2) {
cin >> x >> y >> k;
change2(1, x, y, k);
}
else {
cin >> x >> y;
cout << ask(1, x, y) << endl;
}
}
return 0;
}