#include <bits/stdc++.h>   using namespace std;   struct node {     long long mx, sm, idx;     node() {       mx = 0;       sm = 0;       idx = 0;     }   };   struct segTree {     long long n;     vector<node> st;     segTree(long long n) {       this->n = n;       st.resize(4 * n + 5);     }     void combine(long long pos, long long lc, long long rc) {       st[pos].sm = st[lc].sm + st[rc].sm;       if (st[lc].mx >= st[rc].mx)         st[pos].mx = st[lc].mx, st[pos].idx = st[lc].idx;       else         st[pos].mx = st[rc].mx, st[pos].idx = st[rc].idx;     }     void _build(long long l, long long r, long long pos, long long *arr) {       if (l == r) {         st[pos].mx = arr[l];         st[pos].sm = arr[l];         st[pos].idx = l;         return;       }       long long lc = pos << 1, rc = lc ^ 1, mid = (l + r) >> 1;       _build(l, mid, lc, arr);       _build(mid + 1, r, rc, arr);       combine(pos, lc, rc);     }     void _upd(long long id, long long val, long long l, long long r,               long long pos) {       if (l == r) {         st[pos].mx = val;         st[pos].sm = val;         st[pos].idx = l;         return;       }       long long lc = pos << 1, rc = lc ^ 1, mid = (l + r) >> 1;       if (id <= mid)         _upd(id, val, l, mid, lc);       else         _upd(id, val, mid + 1, r, rc);       combine(pos, lc, rc);     }     pair<long long, long long> _qrymax(long long ql, long long qr, long long l,                                        long long r, long long pos) {       if (qr < l || ql > r)         return make_pair(-LONG_LONG_MAX, -1);       else if (ql <= l && qr >= r)         return make_pair(st[pos].mx, st[pos].idx);       long long lc = pos << 1, rc = lc ^ 1, mid = (l + r) >> 1;       pair<long long, long long> lef = _qrymax(ql, qr, l, mid, lc),                                  rig = _qrymax(ql, qr, mid + 1, r, rc);       if (lef.first >= rig.first) return lef;       return rig;     }     long long _qrysm(long long ql, long long qr, long long l, long long r,                      long long pos) {       if (qr < l || ql > r)         return 0;       else if (ql <= l && qr >= r)         return st[pos].sm;       long long lc = pos << 1, rc = lc ^ 1, mid = (l + r) >> 1;       return _qrysm(ql, qr, l, mid, lc) + _qrysm(ql, qr, mid + 1, r, rc);     }     pair<long long, long long> qry_max(long long ql, long long qr) {       return _qrymax(ql, qr, 1, n, 1);     }     void upd(long long idx, long long val) { _upd(idx, val, 1, n, 1); }     long long qry_sum(long long ql, long long qr) {       return _qrysm(ql, qr, 1, n, 1);     }     void build(long long *arr) { _build(1, n, 1, arr); }   };   const long long N = 1e5 + 5;   long long n, m, a[N];   int main() {     cin >> n >> m;     for (int i = 1; i <= n; i++) cin >> a[i];     segTree S(n);     S.build(a);     while (m--) {       long long type;       cin >> type;       if (type == 1) {         long long l, r;         cin >> l >> r;         cout << S.qry_sum(l, r) <<   n ;       } else if (type == 2) {         long long l, r, x;         cin >> l >> r >> x;         pair<long long, long long> pp = S.qry_max(l, r);         while (pp.first >= x) {           long long newval = pp.first % x, idx = pp.second;           S.upd(idx, newval);           pp = S.qry_max(l, r);         }       } else {         long long idx, val;         cin >> idx >> val;         S.upd(idx, val);       }     }     return 0;   }