// #define ONLINE_JUDGE
#include "bits/stdc++.h"
using namespace std;
#if !defined(mhnd01s) || defined(ONLINE_JUDGE)
#define print(...) ((void)0)
#endif
using ll = long long;
void solve();
signed main() {
#ifdef mhnd01s
    int x = mt19937(random_device()())()%100;printf("%d\n", x);
    freopen("out", "wt", stdout);
#else
    cin.tie(0)->sync_with_stdio(0);
#endif
    cin.exceptions(cin.failbit);
    int t = 1;
    // cin >> t;
    while(t--) {
        solve();
        if(t) cout << '\n';
    }return 0;
}

struct segtreebeats {
    static const ll INF = 2e18, UNSET = LLONG_MIN;

    struct Node {
        ll sum, mx1, mx2, mxc, mn1, mn2, mnc, d_gcd, lz_add, lz_set;
    };

    int sz;
    vector<Node> tree;

    inline ll absgcd(ll a, ll b) {
        a = abs(a); b = abs(b);
        while (b) { a %= b; swap(a, b); }
        return a;
    }

    Node leaf(ll v) { return {v, v, -INF, 1, v, INF, 1, 0, 0, UNSET}; }

    segtreebeats(int n, const vector<ll> &a) {
        for (sz = 1; sz < n; sz <<= 1);
        tree.assign(sz << 1, leaf(0));
        build(a, n, 1, 0, sz - 1);
    }

    inline void pull(int x) {
        int lc = x << 1, rc = x << 1 | 1;
        auto &U = tree[x], &L = tree[lc], &R = tree[rc];

        U.sum = L.sum + R.sum;
        U.lz_add = 0; U.lz_set = UNSET;

        if (L.mx1 == R.mx1) U.mx1 = L.mx1, U.mx2 = max(L.mx2, R.mx2), U.mxc = L.mxc + R.mxc;
        else if (L.mx1 > R.mx1) U.mx1 = L.mx1, U.mx2 = max(L.mx2, R.mx1), U.mxc = L.mxc;
        else U.mx1 = R.mx1, U.mx2 = max(L.mx1, R.mx2), U.mxc = R.mxc;

        if (L.mn1 == R.mn1) U.mn1 = L.mn1, U.mn2 = min(L.mn2, R.mn2), U.mnc = L.mnc + R.mnc;
        else if (L.mn1 < R.mn1) U.mn1 = L.mn1, U.mn2 = min(L.mn2, R.mn1), U.mnc = L.mnc;
        else U.mn1 = R.mn1, U.mn2 = min(L.mn1, R.mn2), U.mnc = R.mnc;

        U.d_gcd = absgcd(L.d_gcd, R.d_gcd);
        ll aL = L.mx2, aR = R.mx2;
        if (aL != -INF && aL != L.mn1 && aR != -INF && aR != R.mn1)
            U.d_gcd = absgcd(U.d_gcd, aL - aR);

        ll any = UNSET;
        if (aL != -INF && aL != L.mn1) any = aL;
        else if (aR != -INF && aR != R.mn1) any = aR;

        ll vals[4] = {L.mn1, L.mx1, R.mn1, R.mx1};
        for (int i = 0; i < 4; ++i) {
            if (vals[i] != U.mn1 && vals[i] != U.mx1) {
                if (any != UNSET) U.d_gcd = absgcd(U.d_gcd, vals[i] - any);
                else any = vals[i];
            }
        }
    }

    inline void apply_set(int x, int lx, int rx, ll v) {
        ll len = rx - lx + 1;
        tree[x] = {len * v, v, -INF, len, v, INF, len, 0, 0, v};
    }

    inline void apply_add(int x, int lx, int rx, ll v) {
        if (!v) return;
        auto &nd = tree[x];
        if (nd.lz_set != UNSET) return apply_set(x, lx, rx, nd.lz_set + v);
        if (nd.mx1 == nd.mn1) return apply_set(x, lx, rx, nd.mn1 + v);
        ll len = rx - lx + 1;
        nd.sum += len * v;
        nd.mx1 += v; if (nd.mx2 != -INF) nd.mx2 += v;
        nd.mn1 += v; if (nd.mn2 != INF) nd.mn2 += v;
        nd.lz_add += v;
    }

    inline void apply_chmin(int x, int lx, int rx, ll v) {
        auto &nd = tree[x];
        if (nd.mx1 <= v) return;
        if (nd.mn1 >= v) return apply_set(x, lx, rx, v);
        if (nd.mn2 == nd.mx1) nd.mn2 = v;
        nd.sum -= (nd.mx1 - v) * nd.mxc;
        nd.mx1 = v;
    }

    inline void apply_chmax(int x, int lx, int rx, ll v) {
        auto &nd = tree[x];
        if (nd.mn1 >= v) return;
        if (nd.mx1 <= v) return apply_set(x, lx, rx, v);
        if (nd.mx2 == nd.mn1) nd.mx2 = v;
        nd.sum += (v - nd.mn1) * nd.mnc;
        nd.mn1 = v;
    }

    inline void push(int x, int lx, int rx) {
        if (lx == rx) return tree[x].lz_add = 0, tree[x].lz_set = UNSET, void();
        int m = (lx + rx) >> 1, lc = x << 1, rc = x << 1 | 1;

        if (tree[x].lz_set != UNSET) {
            apply_set(lc, lx, m, tree[x].lz_set);
            apply_set(rc, m + 1, rx, tree[x].lz_set);
            tree[x].lz_set = UNSET;
        }
        if (tree[x].lz_add) {
            apply_add(lc, lx, m, tree[x].lz_add);
            apply_add(rc, m + 1, rx, tree[x].lz_add);
            tree[x].lz_add = 0;
        }
        if (tree[lc].mx1 > tree[x].mx1) apply_chmin(lc, lx, m, tree[x].mx1);
        if (tree[rc].mx1 > tree[x].mx1) apply_chmin(rc, m + 1, rx, tree[x].mx1);
        if (tree[lc].mn1 < tree[x].mn1) apply_chmax(lc, lx, m, tree[x].mn1);
        if (tree[rc].mn1 < tree[x].mn1) apply_chmax(rc, m + 1, rx, tree[x].mn1);
    }

    void build(const vector<ll> &a, int n, int x, int lx, int rx) {
        if (lx == rx) return void(tree[x] = (lx < n) ? leaf(a[lx]) : leaf(0));
        int m = (lx + rx) >> 1;
        build(a, n, x << 1, lx, m);
        build(a, n, x << 1 | 1, m + 1, rx);
        pull(x);
    }

    void chmin(int l, int r, ll v, int x, int lx, int rx) {
        if (lx > r || rx < l || tree[x].mx1 <= v) return;
        if (lx >= l && rx <= r && tree[x].mx2 < v) return apply_chmin(x, lx, rx, v);
        push(x, lx, rx);
        int m = (lx + rx) >> 1;
        chmin(l, r, v, x << 1, lx, m);
        chmin(l, r, v, x << 1 | 1, m + 1, rx);
        pull(x);
    }

    void chmax(int l, int r, ll v, int x, int lx, int rx) {
        if (lx > r || rx < l || tree[x].mn1 >= v) return;
        if (lx >= l && rx <= r && tree[x].mn2 > v) return apply_chmax(x, lx, rx, v);
        push(x, lx, rx);
        int m = (lx + rx) >> 1;
        chmax(l, r, v, x << 1, lx, m);
        chmax(l, r, v, x << 1 | 1, m + 1, rx);
        pull(x);
    }

    void assign(int l, int r, ll v, int x, int lx, int rx) {
        if (lx > r || rx < l) return;
        if (lx >= l && rx <= r) return apply_set(x, lx, rx, v);
        push(x, lx, rx);
        int m = (lx + rx) >> 1;
        assign(l, r, v, x << 1, lx, m);
        assign(l, r, v, x << 1 | 1, m + 1, rx);
        pull(x);
    }

    void add(int l, int r, ll v, int x, int lx, int rx) {
        if (lx > r || rx < l) return;
        if (lx >= l && rx <= r) return apply_add(x, lx, rx, v);
        push(x, lx, rx);
        int m = (lx + rx) >> 1;
        add(l, r, v, x << 1, lx, m);
        add(l, r, v, x << 1 | 1, m + 1, rx);
        pull(x);
    }

    ll sum(int l, int r, int x, int lx, int rx) {
        if (lx > r || rx < l) return 0;
        if (lx >= l && rx <= r) return tree[x].sum;
        push(x, lx, rx);
        int m = (lx + rx) >> 1;
        return sum(l, r, x << 1, lx, m) + sum(l, r, x << 1 | 1, m + 1, rx);
    }

    ll qmin(int l, int r, int x, int lx, int rx) {
        if (lx > r || rx < l) return INF;
        if (lx >= l && rx <= r) return tree[x].mn1;
        push(x, lx, rx);
        int m = (lx + rx) >> 1;
        return min(qmin(l, r, x << 1, lx, m), qmin(l, r, x << 1 | 1, m + 1, rx));
    }

    ll qmax(int l, int r, int x, int lx, int rx) {
        if (lx > r || rx < l) return -INF;
        if (lx >= l && rx <= r) return tree[x].mx1;
        push(x, lx, rx);
        int m = (lx + rx) >> 1;
        return max(qmax(l, r, x << 1, lx, m), qmax(l, r, x << 1 | 1, m + 1, rx));
    }

    ll qgcd(int l, int r, int x, int lx, int rx) {
        if (lx > r || rx < l) return 0;
        if (lx >= l && rx <= r) {
            ll ans = absgcd(tree[x].d_gcd, tree[x].mx1);
            if (tree[x].mx2 != -INF) ans = absgcd(ans, tree[x].mx2 - tree[x].mx1);
            if (tree[x].mn2 != INF) ans = absgcd(ans, tree[x].mn2 - tree[x].mn1);
            return ans;
        }
        push(x, lx, rx);
        int m = (lx + rx) >> 1;
        return absgcd(qgcd(l, r, x << 1, lx, m), qgcd(l, r, x << 1 | 1, m + 1, rx));
    }

    void chmin(int l, int r, ll v) { chmin(l, r, v, 1, 0, sz - 1); }
    void chmax(int l, int r, ll v) { chmax(l, r, v, 1, 0, sz - 1); }
    void assign(int l, int r, ll v) { assign(l, r, v, 1, 0, sz - 1); }
    void add(int l, int r, ll v) { add(l, r, v, 1, 0, sz - 1); }
    ll qsum(int l, int r) { return sum(l, r, 1, 0, sz - 1); }
    ll qmin(int l, int r) { return qmin(l, r, 1, 0, sz - 1); }
    ll qmax(int l, int r) { return qmax(l, r, 1, 0, sz - 1); }
    ll qgcd(int l, int r) { return qgcd(l, r, 1, 0, sz - 1); }
};

void solve() {
    int n, q; cin >> n;
    vector<ll> v(n);
    for (auto &i : v) cin >> i;
    segtreebeats sgt(n, v);
    cin >> q;
    while (q--) {
        int type; cin >> type;
        if (type == 1) {
            int l, r, x; cin >> l >> r >> x;
            sgt.chmin(--l, --r, x);
        } else if (type == 2) {
            int l, r, x; cin >> l >> r >> x;
            sgt.chmax(--l, --r, x);
        } else if (type == 3) {
            int l, r, x; cin >> l >> r >> x;
            sgt.assign(--l, --r, x);
        } else if (type == 4) {
            int l, r, x; cin >> l >> r >> x;
            sgt.add(--l, --r, x);
        } else if (type == 5) {
            int l, r; cin >> l >> r;
            cout << sgt.qsum(--l, --r);
        } else if (type == 6) {
            int l, r; cin >> l >> r;
            cout << sgt.qmin(--l, --r);
        } else if (type == 7) {
            int l, r; cin >> l >> r;
            cout << sgt.qmax(--l, --r);
        } else if (type == 8) {
            int l, r; cin >> l >> r;
            cout << sgt.qgcd(--l, --r);
        }
        cout << '\n';
    }
}