#include using namespace std; using int64 = long long; const int mod = 1e9 + 7; const int64 infll = (1LL << 62) - 1; const int inf = (1 << 30) - 1; struct IoSetup { IoSetup() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(10); cerr << fixed << setprecision(10); } } iosetup; template< typename T1, typename T2 > ostream &operator<<(ostream &os, const pair< T1, T2 > &p) { os << p.first << " " << p.second; return os; } template< typename T1, typename T2 > istream &operator>>(istream &is, pair< T1, T2 > &p) { is >> p.first >> p.second; return is; } template< typename T > ostream &operator<<(ostream &os, const vector< T > &v) { for(int i = 0; i < (int) v.size(); i++) { os << v[i] << (i + 1 != v.size() ? " " : ""); } return os; } template< typename T > istream &operator>>(istream &is, vector< T > &v) { for(T &in : v) is >> in; return is; } template< typename T1, typename T2 > inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); } template< typename T1, typename T2 > inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); } template< typename T = int64 > vector< T > make_v(size_t a) { return vector< T >(a); } template< typename T, typename... Ts > auto make_v(size_t a, Ts... ts) { return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...)); } template< typename T, typename V > typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) { t = v; } template< typename T, typename V > typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) { for(auto &e : t) fill_v(e, v); } template< typename F > struct FixPoint : F { FixPoint(F &&f) : F(forward< F >(f)) {} template< typename... Args > decltype(auto) operator()(Args &&... args) const { return F::operator()(*this, forward< Args >(args)...); } }; template< typename F > inline decltype(auto) MFP(F &&f) { return FixPoint< F >{forward< F >(f)}; } template< typename Monoid, typename OperatorMonoid = Monoid > struct SegmentTreeBeats { using F = function< Monoid(Monoid, Monoid) >; using G = function< Monoid(Monoid, OperatorMonoid) >; using H = function< OperatorMonoid(OperatorMonoid, OperatorMonoid) >; int sz, height; vector< Monoid > data; vector< OperatorMonoid > lazy; const F f; const G g; const H h; const Monoid M1; const OperatorMonoid OM0; SegmentTreeBeats(int n, const F f, const G g, const H h, const Monoid &M1, const OperatorMonoid OM0) : f(f), g(g), h(h), M1(M1), OM0(OM0) { sz = 1; height = 0; while(sz < n) sz <<= 1, height++; data.assign(2 * sz, M1); lazy.assign(2 * sz, OM0); } void set(int k, const Monoid &x) { data[k + sz] = x; } void build() { for(int k = sz - 1; k > 0; k--) { data[k] = f(data[2 * k + 0], data[2 * k + 1]); } } inline void propagate(int k) { if(lazy[k] != OM0) { lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]); lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]); data[k] = reflect(k); lazy[k] = OM0; } } inline Monoid reflect(int k) { return lazy[k] == OM0 ? data[k] : g(data[k], lazy[k]); } inline void recalc(int k) { while(k >>= 1) data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1)); } inline void thrust(int k) { for(int i = height; i > 0; i--) propagate(k >> i); } void update(int a, int b, const OperatorMonoid &x) { thrust(a += sz); thrust(b += sz - 1); for(int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) { if(l & 1) lazy[l] = h(lazy[l], x), ++l; if(r & 1) --r, lazy[r] = h(lazy[r], x); } recalc(a); recalc(b); } Monoid query(int a, int b) { thrust(a += sz); thrust(b += sz - 1); Monoid L = M1, R = M1; for(int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) { if(l & 1) L = f(L, reflect(l++)); if(r & 1) R = f(reflect(--r), R); } return f(L, R); } Monoid operator[](const int &k) { return query(k, k + 1); } template< typename Uku, typename Check, typename Func, typename X > void update_beats_subtree(int k, const X &x, const Uku &uku, const Check &check, const Func &func) { if(k >= sz) { auto v = reflect(k); if(uku(v, x)) return; if(check(v)) lazy[k] = func(v, x); return; } propagate(k); if(uku(data[k], x)) return; if(check(data[k])) { lazy[k] = func(data[k], x); return; } update_beats_subtree(k * 2 + 0, x, uku, check, func); update_beats_subtree(k * 2 + 1, x, uku, check, func); data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1)); } template< typename Uku, typename Check, typename Func, typename X > void update_beats(int a, int b, const X &x, const Uku &uku, const Check &check, const Func &func) { thrust(a += sz); thrust(b += sz - 1); for(int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) { if(l & 1) update_beats_subtree(l++, x, uku, check, func); if(r & 1) update_beats_subtree(--r, x, uku, check, func); } recalc(a); recalc(b); } }; int main() { int N, Q; cin >> N >> Q; struct Node { int64 latte, malta, sum, lcm, sz; Node() : latte(infll), malta(-infll), sum(0), lcm(1), sz(0) {} Node(int64 x, int64 sz) : latte(x), malta(x), sum(x * sz), lcm(x), sz(sz) {}; }; auto f = [](Node a, const Node &b) { a.latte = min(a.latte, b.latte); a.malta = max(a.malta, b.malta); a.sum += b.sum; if(a.lcm >= inf || b.lcm >= inf) a.lcm = inf; else a.lcm = a.lcm / __gcd(a.lcm, b.lcm) * b.lcm; a.sz += b.sz; return a; }; auto g = [](const Node &a, int64 b) { return Node(b, a.sz); }; auto h = [](int64 a, int64 b) { return b; }; SegmentTreeBeats< Node, int64 > seg(N, f, g, h, Node(), infll); for(int i = 0; i < N; i++) { int x; cin >> x; seg.set(i, Node(x, 1)); } seg.build(); auto uku = [](const Node &a, int64 x) { return x % a.lcm == 0; }; auto check = [](const Node &a) { return a.latte == a.malta; }; auto func = [](const Node &a, int64 x) { return __gcd(a.latte, x); }; for(int i = 0; i < Q; i++) { int t; cin >> t; if(t == 1) { int l, r, x; cin >> l >> r >> x; --l; seg.update(l, r, x); } else if(t == 2) { int l, r, x; cin >> l >> r >> x; --l; seg.update_beats(l, r, x, uku, check, func); } else if(t == 3) { int l, r; cin >> l >> r; --l; cout << seg.query(l, r).malta << "\n"; } else { int l, r; cin >> l >> r; --l; cout << seg.query(l, r).sum << "\n"; } } }