#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define ws ws_____________________ #define y1 y1_____________________ #define y0 y0_____________________ #define left left_________________ #define right right_______________ #define next next_________________ #define prev prev_________________ #define hash hash_________________ #define pb push_back #define fst first #define snd second #define mp make_pair #define sz(C) ((int) (C).size()) #define forn(i, n) for (int i = 0; i < int(n); ++i) #define ford(i, n) for (int i = int(n) - 1; i >= 0; --i) #define all(C) begin(C), end(C) typedef long long ll; typedef unsigned long long ull; typedef unsigned int uint; typedef pair pii; typedef pair pll; typedef vector vll; typedef vector vi; typedef vector vvi; typedef vector vii; typedef long double ld; typedef complex cd; #ifdef LOCAL #define eprintf(args...) fprintf(stderr, args), fflush(stderr) #else #define eprintf(...) ; #endif #define FILE_NAME "a" int n; vi a; bool read() { if (scanf("%d", &n) < 1) { return 0; } a.resize(n); forn(i, n) { scanf("%d", &a[i]); } return 1; } int gcd(int a, int b) { a = abs(a); b = abs(b); return b ? gcd(b, a % b) : a; } const ll INF = 1e18; struct SegmTreeMax { vector> t; int sz; SegmTreeMax(int n = 0) { sz = 1; while (sz < n) sz *= 2; t.assign(sz * 2, mp(-INF, -1)); } void put(int pos, ll val) { int v = sz + pos; t[v] = mp(val, pos); v >>= 1; while (v > 0) { t[v] = max(t[v * 2], t[v * 2 + 1]); v >>= 1; } } pair get_max(int l, int r) { l += 1; r += 1; l += sz; r += sz; pair res(-INF, -1); while (l <= r) { res = max(res, t[l]); res = max(res, t[r]); l = (l + 1) >> 1; r = (r - 1) >> 1; } return res; } }; int L; vll pref; vi next_greater; vector g; vi mem_log2; SegmTreeMax TPref; ll get_g(int l, int r, bool precalc = false) { if (l > r) { return -INF; } int k = mem_log2[r - l + 1]; if (precalc) { --k; } assert(k >= 0); const int rr = l + (1 << k) - 1; ll ans = g[k][l]; int mx = next_greater[l]; if (mx > rr) { mx = l; } int j = next_greater[mx]; if (j > r) { return ans; } if (j > rr + 1) { int mx_pref = TPref.get_max(rr + 1, j - 1).snd; ans = max(ans, pref[mx_pref] - pref[l] - a[mx]); } ans = max(ans, get_g(j, r) + (pref[j + 1] - pref[l])); return ans; } ll solve() { mem_log2.assign(n + 1, -1); for (int l = 0; (1 << l) <= sz(mem_log2); ++l) { for (int i = 1 << l; i < sz(mem_log2); ++i) { mem_log2[i] = l; } } pref.assign(n + 1, 0); forn(i, n) { pref[i + 1] = pref[i] + a[i]; } TPref = SegmTreeMax(sz(pref)); forn(i, n + 1) { TPref.put(i, pref[i]); } next_greater.assign(n, -1); { vi st; ford(i, n) { while (!st.empty() && a[st.back()] <= a[i]) { st.pop_back(); } next_greater[i] = st.empty() ? -1 : st.back(); st.pb(i); } } { L = 0; while ((1 << L) <= n) ++L; forn(i, n) { g[0][i] = 0; } for (int l = 1; l < L; ++l) { forn(i, n) { int j = i + (1 << l) - 1; g[l][i] = get_g(i, j, true); } } } ll ans = -INF; vii st; ford(i, n) { int g = abs(a[i]); if (!st.empty()) { g = gcd(g, st.back().snd); } st.pb(mp(i, g)); for (auto& e : st) { e.snd = gcd(e.snd, g); } vii nst; for (const auto& e : st) { if (nst.empty() || nst.back().snd != e.snd) { nst.pb(e); } else { if (!nst.empty()) { nst.back().fst = e.fst; } else { nst.pb(e); } } } st.swap(nst); int mx = -1; ford(id, sz(st)) { const int l = st[id].fst; const int r = id > 0 ? st[id - 1].fst - 1 : n - 1; const int cur_g = st[id].snd; int from = -1; if (mx != -1) { int nxt = next_greater[mx]; nxt = min(nxt, r + 1); assert(nxt >= l); if (l <= nxt - 1) { int mx_pref = TPref.get_max(l, nxt - 1).snd; ans = max(ans, cur_g * 1ll * (pref[mx_pref] - pref[i] - a[mx])); } if (nxt <= r) { from = nxt; } } else { from = l; } ans = max(ans, cur_g * 1ll * get_g(from, r)); } } return ans; } int main() { #ifdef LOCAL freopen(FILE_NAME ".in", "r", stdin); // freopen(FILE_NAME ".out", "w", stdout); #endif while (read()) { printf("%lld\n", solve()); } #ifdef LOCAL eprintf("Time: %.10f\n", (double) clock() / CLOCKS_PER_SEC); #endif return 0; }