#include #define rep(i,n) for(int i=0;i<(int)(n);i++) #define rep1(i,n) for(int i=1;i<=(int)(n);i++) #define all(c) c.begin(),c.end() #define pb push_back #define fs first #define sc second #define chmin(x,y) x=min(x,y) #define chmax(x,y) x=max(x,y) using namespace std; template ostream& operator<<(ostream& o,const pair &p){ return o<<"("< ostream& operator<<(ostream& o,const vector &vc){ o<<"{"; for(const T& v:vc) o< using V = vector; template using VV = vector>; constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); } #ifdef LOCAL #define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl #else #define show(x) true #endif template struct segbeats{ V x; int s; template segbeats(const V& a){ int n = a.size(); s = 1; while(s0;i--) upd(i); } template void ch(int a,int b,F f,Args... args){ ch_(a,b,0,s,1,f,args...); } template auto get(int a,int b,F f,G g,H h){ return get_(a,b,0,s,1,f,g,h); } template pair findl(int a,int b,F f,Args&... args){ return findl_(a,b,0,s,1,f,args...); } private: void push(int i){ x[i].push(x[i*2],x[i*2+1]); } void upd(int i){ x[i] = N::merge(x[i*2],x[i*2+1]); } template void ch_(int a,int b,int l,int r,int i,F f,Args... args){ if(b<=l || r<=a){ return; } if(a<=l && r<=b && (x[i].*f)(args...)){ //f : put_tag, early_break return; } push(i); int m = (l+r)/2; ch_(a,b,l,m,i*2 ,f,args...); ch_(a,b,m,r,i*2+1,f,args...); upd(i); } template auto get_(int a,int b,int l,int r,int i,F f,G g,H h){ if(b<=l || r<=a){ return h; } if(a<=l && r<=b){ return (x[i].*f)(); } push(i); int m = (l+r)/2; return g(get_(a,b,l,m,i*2,f,g,h),get_(a,b,m,r,i*2+1,f,g,h)); } template pair findl_(int a,int b,int l,int r,int i,F f,Args&... args){ if(b<=l || r<=a){ return {b,N()}; } if(a<=l && r<=b){ if(!(x[i].*f)(args...)) return {b,N()}; if(r-l == 1) return {l,x[i]}; } push(i); int m = (l+r)/2; auto x = findl_(a,b,l,m,i*2,f,args...); if(x.fs < b) return x; return findl_(a,b,m,r,i*2+1,f,args...); } // template // pair findr_(int a,int b,int l,int r,int i,F f,Args&... args){ // if(b<=l || r<=a){ // return {a-1,N()}; // } // if(a<=l && r<=b){ // if(!(x[i].*f)(args...)) return {a-1,N()}; // if(r-l == 1) return {l,x[i]}; // } // push(i); // int m = (l+r)/2; // auto y = findr_(a,b,m,r,i*2+1,f,args...); // if(y.fs >= a) return y; // return findr_(a,b,l,m,i*2,f,args...); // } }; const ll inf = TEN(9)+1; ll lcm(ll x,ll y){ return min(x / __gcd(x,y) * y, inf); } struct D{ int sz=1; ll sm=0,mx=-1; ll L=0; D(ll v=1){sm=mx=L=v;} static D merge(D l,D r){ D z; z.sz = l.sz + r.sz; z.sm = l.sm + r.sm; z.mx = max(l.mx,r.mx); z.L = lcm(l.L,r.L); return z; } void push(D& x,D& y){ if(mx * sz == sm){ x.set(mx); y.set(mx); } } bool set(ll x){ sm = x * sz; mx = L = x; return true; } bool gcd(ll x){ if(x % L == 0) return true; // break_condition if(mx * sz == sm){ // put_tag_condition set(__gcd(mx,x)); return true; } return false; } ll getmax(){ return mx; } ll getsum(){ return sm; } }; int main(){ int N,Q; cin >> N >> Q; V a(N); rep(i,N) cin >> a[i]; segbeats seg(a); rep(_,Q){ int t; cin >> t; if(t == 1){ int l,r,x; cin >> l >> r >> x; l--; seg.ch(l,r,&D::set,x); } if(t == 2){ int l,r,x; cin >> l >> r >> x; l--; seg.ch(l,r,&D::gcd,x); } if(t == 3){ int l,r; cin >> l >> r; l--; cout << seg.get(l,r,&D::getmax,[](ll x,ll y){return max(x,y);},-1LL) << endl; } if(t == 4){ int l,r; cin >> l >> r; l--; cout << seg.get(l,r,&D::getsum,[](ll x,ll y){return x+y;},0LL) << endl; } } }