#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <set>
#include <span>
#include <utility>
#include <vector>

struct Line {
  mutable int64_t k, m, p;
  bool operator<(const Line& o) const { return k < o.k; }
  bool operator<(int64_t x) const { return p < x; }
};

struct LineContainer : std::multiset<Line, std::less<>> {
  static const int64_t inf = LLONG_MAX;
  int64_t div(int64_t a, int64_t b) { // floored division
    return a / b - ((a ^ b) < 0 && a % b); }
  bool isect(iterator x, iterator y) {
    if (y == end()) return x->p = inf, 0;
    if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
    else x->p = div(y->m - x->m, x->k - y->k);
    return x->p >= y->p;
  }
  void add(int64_t k, int64_t m) {
    auto z = insert({k, m, 0}), y = z++, x = y;
    while (isect(y, z)) z = erase(z);
    if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
    while ((y = x) != begin() && (--x)->p >= y->p)
      isect(x, erase(y));
  }
  int64_t query(int64_t x) {
    assert(!empty());
    auto l = *lower_bound(x);
    return l.k * x + l.m;
  }
};

int64_t solve_line(std::span<const std::array<int64_t, 2>> a) {
  int32_t n = a.size();
  std::vector<int64_t> dp(n + 1, 0);

  std::array<LineContainer, 2> lc;
  lc[0].add(0, 0);
  lc[1].add(0, 0);

  for (int32_t i = 0; i < n; ++i) {
    dp[i + 1] = std::max({dp[i] + a[i][0] * a[i][1], lc[0].query(a[i][0]), lc[1].query(a[i][1])});
    lc[0].add(a[i][1], dp[i]);
    lc[1].add(a[i][0], dp[i]);
  }

  return dp[n];
}

long long solve(std::vector<int> H, std::vector<int> W) {
    int32_t n = (int32_t)H.size();
    std::vector<std::array<int64_t, 2>> a(n);
    for (int32_t i = 0; i < n; i++) {
      a[i] = {H[i], W[i]};
    }

    int64_t ans = 0;
    for (int32_t flip = 0; flip < 2; ++flip) {
      auto it = std::max_element(a.begin(), a.end());
      std::rotate(a.begin(), it, a.end());
      ans = std::max(ans, solve_line(a));
      std::rotate(a.begin(), a.begin() + 1, a.end());
      ans = std::max(ans, solve_line(a));
      for (auto& [w, h] : a) {
        std::swap(w, h);
      }
    }

    return ans;
}
