#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <array>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <array>
using namespace std;
typedef long long LL;
struct edge {
int l, r;
LL sum, max_n;
};
struct Segment_Tree {
vector<edge> t;
vector<LL> a;
Segment_Tree(int n) : t(4 * n), a(n + 1) {}
void push_up(int u) {
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
t[u].max_n = t[u << 1].max_n + t[u << 1 | 1].max_n;
}
void build(int u, int l, int r) {
t[u].l = l;
t[u].r = r;
if (l == r) {
t[u].sum = a[l];
t[u].max_n = a[l];
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
push_up(u);
}
LL query(int u, int l, int r) {
if (t[u].l >= l && t[u].r <= r) {
return t[u].sum;
}
int mid = t[u].l + t[u].r >> 1;
LL s = 0;
if (l <= mid) {
s = query(u << 1, l, r);
}
if (r > mid) {
s += query(u << 1 | 1, l, r);
}
return s;
}
void modify(int u, int x, LL v) {
if (t[u].l == x && t[u].r == x) {
t[u].sum = v;
t[u].max_n = v;
return;
} else {
int mid = (t[u].l + t[u].r) >> 1;
if (x <= mid) {
modify(u << 1, x, v);
} else {
modify(u << 1 | 1, x, v);
}
push_up(u);
}
}
void mod_change(int u, int l, int r, LL x) {
if (t[u].l >= l && t[u].r <= r && t[u].max_n < x) {
return;
} else if (l <= t[u].l && r >= t[u].r && t[u].l == t[u].r) {
t[u].max_n %= x;
t[u].sum %= x;
return;
}
int mid = t[u].l + t[u].r >> 1;
if (l <= mid) {
mod_change(u << 1, l, r, x);
}
if (r > mid) {
mod_change(u << 1 | 1, l, r, x);
}
push_up(u);
}
};
void best_coder() {
int n, m;
scanf("%d%d", &n, &m);
Segment_Tree st(n);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &st.a[i]);
}
st.build(1, 1, n);
int q, l, r, k;
long long x;
for (int i = 0; i < m; ++i) {
scanf("%d", &q);
if (q == 1) {
scanf("%d%d", &l, &r);
printf("%lld\n", st.query(1, l, r));
} else if (q == 2) {
scanf("%d%d%lld", &l, &r, &x);
st.mod_change(1, l, r, x);
} else {
scanf("%d%lld", &k, &x);
st.modify(1, k, x);
}
}
}
void happy_coder() {
}
int main() {
best_coder();
return 0;
}