#include <bits/stdc++.h>
#define kien long long
#define FOR(i, a, b) for (int i = a;i <= b; i++)
#define FORD(i, a, b) for (int i = a;i >= b; i--)
#define task "a"
#define fin(x) freopen(x".inp","r",stdin)
#define fou(x) freopen(x".out","w",stdout)
using namespace std;
const int mxn = 1e5 + 5;
kien n, k, q, a[mxn];
struct segment {
int st[4 * mxn], lazy[4 * mxn];
void build (int id, int l, int r) {
if (l == r) {
st[id] = lazy[id] = a[l];
return;
}
int mid = (l + r) >> 1;
build (id << 1, l , mid);
build (id << 1 | 1, mid + 1, r);
st[id] = st[id << 1] + st[id << 1 | 1];
lazy[id] = max(lazy[id << 1], lazy[id << 1 | 1]);
}
void update (int id, int l, int r, int u, int v, int val) {
if (u > r or v < l or lazy[id] == 0) return;
if (l == r) {
st[id] /= val;
lazy[id] = st[id];
return;
}
int mid = (l + r) >> 1;
update (id << 1, l, mid, u, v, val);
update (id << 1 | 1, mid + 1, r, u ,v, val);
st[id] = st[id << 1] + st[id << 1 | 1];
lazy[id] = max(lazy[id << 1], lazy[id << 1 | 1]);
}
void update1 (int id, int l, int r, int pos, int val) {
if (l == r) {
st[id] = lazy[id] = val;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid)
update1 (id << 1, l, mid, pos, val);
else
update1 (id << 1 | 1, mid + 1, r, pos, val);
st[id] = st[id << 1] + st[id << 1 | 1];
lazy[id] = max(lazy[id << 1], lazy[id << 1 | 1]);
}
kien get (int id, int l, int r, int u, int v) {
if (u > r or v < l) return 0;
if (u <= l and r <= v) return st[id];
int mid = (l + r) >> 1;
return get (id << 1, l, mid, u, v) + get(id << 1 | 1, mid + 1, r, u, v);
}
} ST;
main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
if (fopen(task".inp", "r")) {
fin(task); fou(task);
}
cin >> n >> q >> k;
FOR (i, 1, n) cin >> a[i];
ST.build(1, 1, n);
int type, L, R;
while(q--) {
cin >> type >> L >> R;
if (type == 1) {
ST.update1(1, 1, n, L, R);
}
else if (type == 2) {
if (k == 1) continue;
ST.update(1, 1, n, L, R, k);
}
else {
cout << ST.get(1, 1, n, L, R) << "\n";
}
}
}
//5 10 3
//1 2 8 1 3
//1 2 5
//2 3 5
//3 2 5
//2 1 4
//1 3 2
//3 3 5
//1 2 4
//2 1 2
//1 1 4
//3 1