#include #define REP(i, n) for (int i = 0; (i) < int(n); ++ (i)) #define REP3(i, m, n) for (int i = (m); (i) < int(n); ++ (i)) #define REP_R(i, n) for (int i = (n) - 1; (i) >= 0; -- (i)) #define REP3R(i, m, n) for (int i = (n) - 1; (i) >= int(m); -- (i)) #define ALL(x) begin(x), end(x) #define dump(x) cerr << #x " = " << x << endl #define unittest_name_helper(counter) unittest_ ## counter #define unittest_name(counter) unittest_name_helper(counter) #define unittest __attribute__((constructor)) void unittest_name(__COUNTER__) () using ll = long long; using namespace std; template inline void chmax(T & a, T const & b) { a = max(a, b); } template inline void chmin(T & a, T const & b) { a = min(a, b); } template ostream & operator << (ostream & out, vector const & xs) { REP (i, int(xs.size()) - 1) out << xs[i] << ' '; if (not xs.empty()) out << xs.back(); return out; } const int dy[] = { -1, 1, 0, 0 }; const int dx[] = { 0, 0, 1, -1 }; bool is_on_field(int y, int x, int h, int w) { return 0 <= y and y < h and 0 <= x and x < w; } template struct segment_tree { typedef typename Monoid::underlying_type underlying_type; int n; vector a; Monoid mon; segment_tree() = default; segment_tree(int a_n, underlying_type initial_value = Monoid().unit(), Monoid const & a_mon = Monoid()) : mon(a_mon) { n = 1; while (n < a_n) n *= 2; a.resize(2 * n - 1, mon.unit()); fill(a.begin() + (n - 1), a.begin() + ((n - 1) + a_n), initial_value); // set initial values REP_R (i, n - 1) a[i] = mon.append(a[2 * i + 1], a[2 * i + 2]); // propagate initial values } void point_set(int i, underlying_type z) { // 0-based a[i + n - 1] = z; for (i = (i + n) / 2; i > 0; i /= 2) { // 1-based a[i - 1] = mon.append(a[2 * i - 1], a[2 * i]); } } underlying_type range_concat(int l, int r) { // 0-based, [l, r) underlying_type lacc = mon.unit(), racc = mon.unit(); for (l += n, r += n; l < r; l /= 2, r /= 2) { // 1-based loop, 2x faster than recursion if (l % 2 == 1) lacc = mon.append(lacc, a[(l ++) - 1]); if (r % 2 == 1) racc = mon.append(a[(-- r) - 1], racc); } return mon.append(lacc, racc); } }; struct max_monoid { typedef int underlying_type; int unit() const { return 0; } int append(int a, int b) const { return max(a, b); } }; vector max_transform(vector const & a) { int n = a.size(); segment_tree segtree(n); REP (i, n) segtree.point_set(i, a[i]); vector b; REP (k, n) { REP (i, n - k) { int j = i + k; b.push_back(segtree.range_concat(i, j + 1)); } } return b; } int main() { int n; scanf("%d", &n); vector a(n); REP (i, n) scanf("%d", &a[i]); // dump(a); // dump(max_transform(a)); // dump(max_transform(max_transform(a))); auto ssa = max_transform(max_transform(a)); ll result = accumulate(ALL(ssa), 0ll); printf("%lld\n", result); return 0; }