#include #ifndef TEMP #define TEMP template std::ostream &operator<<(std::ostream &os, const std::pair &x) { return os << "(" << x.first << ", " << x.second << ")"; } template std::ostream &operator<<(std::ostream &os, const std::vector &vec) { os << '[' << vec[0]; for (int _ = 1, __ = vec.size(); _ < __; _++) os << ", " << vec[_]; return os << ']'; } template std::ostream &operator<<(std::ostream &os, const std::array &arr) { os << '[' << arr[0]; for (std::size_t _ = 1; _ < _Nm; _++) os << ", " << arr[_]; return os << ']'; } template void print(std::ostream &os, const Tup &x, std::index_sequence) { using swallow = int[]; (void)swallow{(os << std::get(x) << ", ", 0)...}; } template std::ostream &operator<<(std::ostream &os, const std::tuple &x) { static constexpr std::size_t N = sizeof...(Args); os << "("; if constexpr (N >= 2) print(os, x, std::make_index_sequence()); return os << std::get(x) << ")"; } #ifdef __LOCAL const std::string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", ITALIC = "\033[3m", BOLD = "\033[1m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m"; #define func_LINE_FILE \ NORMAL_FAINT << " in " << BOLD << __func__ << NORMAL_FAINT << ITALIC \ << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET #define checkpoint() \ std::cerr << BRIGHT_RED << "< check point! >" << func_LINE_FILE << '\n' #define debug(x) \ std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) \ << func_LINE_FILE << '\n' #define debugArray(x, n) \ do { \ std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = [" << x[0]; \ for (int _ = 1; _ < (int)(n); ++_) std::cerr << ", " << x[_]; \ std::cerr << "]" << func_LINE_FILE << '\n'; \ } while (0) #define debugMatrix(x, h, w) \ do { \ std::cerr << BRIGHT_CYAN << #x << "\n" << COLOR_RESET << "= "; \ for (int _ = 0; (_) < (int)(h); ++_) { \ std::cerr << ((_ ? " [" : "[[")); \ for (int __ = 0; __ < (int)(w); ++__) \ std::cerr << ((__ ? ", " : "")) << x[_][__]; \ std::cerr << "]" << (_ + 1 == (int)(h) ? "]" : ",\n"); \ } \ std::cerr << func_LINE_FILE << '\n'; \ } while (0) #else #define checkpoint() (void(0)) #define debug(x) (void(0)) #define debugArray(x, n) (void(0)) #define debugMatrix(x, h, w) (void(0)) #endif template auto compress(std::vector &v) { std::sort(v.begin(), v.end()); v.erase(std::unique(v.begin(), v.end()), v.end()); return [&v](T x) { return std::lower_bound(v.begin(), v.end(), x) - v.begin(); }; } struct ClosedSection { long long l, r; ClosedSection() : l(1), r(0) {} ClosedSection(long long l_, long long r_) : l(l_), r(r_) {} bool valid() { return l <= r; } }; template // closed [l,r] ClosedSection bin_search(const Check &isok, int l, int r) { bool res_l = isok(l), res_r = isok(r); if (res_l && res_r) return ClosedSection(l, r); if (!res_l && !res_r) return ClosedSection(); int lb, ub; for (int x; ub - lb > 1;) (isok(x = (lb + ub) / 2) == res_l ? lb : ub) = x; return res_l ? ClosedSection(l, lb) : ClosedSection(ub, r); } template ClosedSection bin_search(const Check &isok, ClosedSection cs) { return cs.valid() ? bin_search(isok, cs.l, cs.r) : cs; } #endif template struct SegmentTree_Beats { using T = typename M::T; using E = typename M::E; SegmentTree_Beats() {} SegmentTree_Beats(int n_) : n(n_), height(ceil(log2(n))), dat(n * 2, M::ti()), laz(n * 2, {E(), false}) {} SegmentTree_Beats(int n_, T v1) : SegmentTree_Beats(n_) { for (int i = n; i--;) dat[i + n] = v1; for (int i = n; --i;) update(i); } SegmentTree_Beats(const std::vector &v) : SegmentTree_Beats(v.size()) { for (int i = n; i--;) dat[i + n] = v[i]; for (int i = n; --i;) update(i); } void unsafe_set(int k, T x) { dat[k + n] = x; } void rebuild() { for (int i = n + n; i--;) laz[i].flg = false; for (int i = n; --i;) update(i); } void apply(int a, int b, E x) { a += n, b += n; for (int i = height; i; i--) if (((a >> i) << i) != a) eval(a >> i); for (int i = height; i; i--) if (((b >> i) << i) != b) eval((b - 1) >> i); for (int l = a, r = b; l < r; l >>= 1, r >>= 1) { if (l & 1) propagate(l++, x); if (r & 1) propagate(--r, x); } for (int i = 1; a >> i; i++) if (((a >> i) << i) != a) update(a >> i); for (int i = 1; b >> i; i++) if (((b >> i) << i) != b) update((b - 1) >> i); } void set(int k, T x) { int i = height; for (k += n; i; i--) eval(k >> i); for (dat[k] = x, laz[k].flg = false, i = 1; k >> i; i++) update(k >> i); } T fold(int a, int b) { //[a,b) a += n, b += n; for (int i = height; i; i--) if (((a >> i) << i) != a) eval(a >> i); for (int i = height; i; i--) if (((b >> i) << i) != b) eval(b >> i); T vl = M::ti(), vr = M::ti(); for (int l = a, r = b; l < r; l >>= 1, r >>= 1) { if (l & 1) vl = M::op(vl, dat[l++]); if (r & 1) vr = M::op(dat[--r], vr); } return M::op(vl, vr); } T operator[](const int k) { return fold(k, k + 1); } private: const int n, height; struct Lazy { E val; bool flg; }; std::vector dat; std::vector laz; inline void eval(int k) { if (!laz[k].flg) return; propagate(k << 1 | 0, laz[k].val), propagate(k << 1 | 1, laz[k].val); laz[k].flg = false; } inline void propagate(int k, const E &x) { if (bool success = M::mapping(dat[k], x); k < n) { laz[k] = {laz[k].flg ? M::composition(laz[k].val, x) : x, true}; if (!success) eval(k), update(k); } } inline void update(int k) { dat[k] = M::op(dat[k << 1 | 0], dat[k << 1 | 1]); } }; using namespace std; struct Mono { struct T { uint32_t max; uint64_t sum; uint32_t sz; }; static T ti() { return T(); } static T op(const T &vl, const T &vr) { return {max(vl.max, vr.max), vl.sum + vr.sum, vl.sz + vr.sz}; } struct E { uint32_t upd, gcd; }; static bool mapping(T &v, const E &f) { if (v.max * v.sz != v.sum && f.gcd != 0) return false; v.max = f.gcd == 0 ? f.upd : gcd(v.max, f.gcd); v.sum = v.max * v.sz; return true; } static E composition(const E &pre, const E &suf) { if (pre.gcd != 0 && suf.gcd != 0) return {0, gcd(pre.gcd, suf.gcd)}; return {suf.gcd == 0 ? suf.upd : gcd(pre.upd, suf.gcd), 0}; } }; signed main() { cin.tie(0); ios::sync_with_stdio(false); int N, Q; cin >> N >> Q; SegmentTree_Beats seg(N); for (int i = 0; i < N; i++) { unsigned a; cin >> a; seg.unsafe_set(i, {a, a, 1}); } seg.rebuild(); while (Q--) { int op, l, r; cin >> op >> l >> r, l--; if (op < 3) { unsigned x; cin >> x; if (op == 1) seg.apply(l, r, {x, 0}); if (op == 2) seg.apply(l, r, {0, x}); } else { if (op == 3) cout << seg.fold(l, r).max << '\n'; if (op == 4) cout << seg.fold(l, r).sum << '\n'; } } return 0; }