#include using namespace std; typedef long long ll; template T gcd(T a, T b) { T t; while (a) { t = a; a = b % a; b = t; } return b; } ll a[50005]; int n; template struct segtree_lazy { struct updater { /* DATA MEMBERS */ ll x; updater(ll x = 0) : x(x) {} updater& operator+= (const updater& other) { /* ADDITION */ x += other.x; return *this; } operator bool () const { /* BOOL CAST */ return x != 0; } }; struct node_t { /* DATA MEMBERS */ ll x; /* CONSTRUCTOR */ node_t(ll x = 0) : x(x) {} node_t& operator+= (const node_t& other) { /* ADDITION */ x = max(x, other.x); return *this; } node_t& operator+= (const updater& other) { /* UPDATE ADDITION */ x += other.x; return *this; } node_t operator+ (const node_t& other) const { node_t tmp = *this; tmp += other; return tmp; } }; node_t a[2*MAXN]; updater b[2*MAXN]; void init() { for (int i=1; i<=MAXN; i++) { /* KOPIRAJ NEKI EKSTERNI NIZ OVDE */ a[i + MAXN - 1] = node_t(); } for (int i=MAXN-1; i>0; i--) { a[i] = a[2*i] + a[2*i+1]; } } void push(int i) { if (b[i]) { a[i] += b[i]; if (i < MAXN) { b[2*i] += b[i]; b[2*i+1] += b[i]; } b[i] = updater(); } } node_t get(int l, int r, int node=1, int nl=1, int nr=MAXN) { push(node); if (r < nl || nr < l) { return node_t(); } if (l <= nl && nr <= r) { return a[node]; } int nm = (nl + nr) >> 1; return get(l, r, 2*node, nl, nm) + get(l, r, 2*node+1, nm+1, nr); } void update(int l, int r, updater val, int node=1, int nl=1, int nr=MAXN) { push(node); if (r < nl || nr < l) { return; } if (l <= nl && nr <= r) { b[node] += val; push(node); return; } int nm = (nl + nr) >> 1; update(l, r, val, 2*node, nl, nm); update(l, r, val, 2*node+1, nm+1, nr); a[node] = a[2*node] + a[2*node+1]; } }; segtree_lazy<65536> drvo; struct triple { ll v, l, r; }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cerr.tie(nullptr); cin >> n; for (int i=1; i<=n; i++) { cin >> a[i]; } ll sol = 0; vector gcd_stack; vector max_stack; for (int i=1; i<=n; i++) { // primeni nzd na sve elemente niza for (auto& p : gcd_stack) { p.v = gcd(p.v, abs(a[i])); } // dodaj sebe gcd_stack.push_back({abs(a[i]), i, i}); // skupi vector tmp; for (auto& p : gcd_stack) { if (tmp.empty() || tmp.back().v != p.v) { tmp.push_back(p); } else if (tmp.back().v == p.v) { tmp.back().r = p.r; } } swap(tmp, gcd_stack); // povecavam sumu drvo.update(1, i, a[i]); // sredim maximum while (max_stack.size() && a[i] >= max_stack.back().v) { drvo.update(max_stack.back().l, max_stack.back().r, max_stack.back().v); max_stack.pop_back(); } int ls = max_stack.size() ? max_stack.back().r + 1 : 1; max_stack.push_back({a[i], ls, i}); drvo.update(ls, i, -a[i]); /* cerr << i << '\n'; for (auto g : max_stack) { cerr << "d " << g.l << ' ' << g.r << ' ' << g.v << '\n'; } */ for (auto& g : gcd_stack) { // cerr << "drvo get " << drvo.get(g.l, g.r).x << '\n'; sol = max(sol, g.v * drvo.get(g.l, g.r).x); } } cout << sol << '\n'; }