#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
#include <iomanip>
struct state {
double minA, minB;
int len;
};
struct line {
double a, b;
int id;
};
double intersectX(const line &l1, const line &l2) {
return (l1.b - l2.b) / (l2.a - l1.a);
}
bool bad(const line &l1, const line &l2, const line &l3) {
double x12 = intersectX(l1, l2);
double x23 = intersectX(l2, l3);
return x23 <= x12;
}
double evalLine(const line &l, double x) {
return l.a * x + l.b;
}
struct hull {
std::deque <line> dq;
void clear() {
dq.clear();
}
void addLine(double a, double b, int id) {
line l;
l.a = a;
l.b = b;
l.id = id;
if (dq.empty() == false && dq.back().a == l.a) {
if (dq.back().b >= l.b) {
return;
}
else {
dq.pop_back();
}
}
while ((int) dq.size() >= 2 && bad(dq[(int) dq.size() - 2], dq.back(), l) == true) {
dq.pop_back();
}
dq.push_back(l);
}
void popExpired(int minId) {
while (dq.empty() == false && dq.front().id < minId) {
dq.pop_front();
}
}
bool empty() const {
return dq.empty();
}
double query(double x, int minId) {
popExpired(minId);
while ((int) dq.size() >= 2) {
popExpired(minId);
if ((int) dq.size() < 2) {
break;
}
double v0 = evalLine(dq[0], x);
double v1 = evalLine(dq[1], x);
if (v1 >= v0) {
dq.pop_front();
}
else {
break;
}
}
if (dq.empty() == true) {
return 0.0;
}
return evalLine(dq.front(), x);
}
};
std::vector <double> a, b;
void buildLeft(int l, int mid, std::vector <state> &left) {
left.clear();
double curA = 1e100, curB = 1e100;
for (int i = mid; i >= l; i--) {
curA = std::min(curA, a[i]);
curB = std::min(curB, b[i]);
int len = mid - i + 1;
if (left.empty() == true || left.back().minA != curA || left.back().minB != curB) {
state st;
st.minA = curA;
st.minB = curB;
st.len = len;
left.push_back(st);
}
else {
left.back().len = len;
}
}
}
void buildRight(int mid, int r, std::vector <state> &right) {
right.clear();
double curA = 1e100, curB = 1e100;
for (int j = mid + 1; j <= r; j++) {
curA = std::min(curA, a[j]);
curB = std::min(curB, b[j]);
int len = j - mid;
if (right.empty() == true || right.back().minA != curA || right.back().minB != curB) {
state st;
st.minA = curA;
st.minB = curB;
st.len = len;
right.push_back(st);
}
else {
right.back().len = len;
}
}
}
double crossSolve(int l, int mid, int r) {
std::vector <state> left, right;
buildLeft(l, mid, left);
buildRight(mid, r, right);
double ans = 0.0;
int szL = (int) left.size(), szR = (int) right.size();
if (szL == 0 || szR == 0) {
return ans;
}
int pr = -1;
for (int i = 0; i < szL; i++) {
while (pr + 1 < szR && right[pr + 1].minA >= left[i].minA && right[pr + 1].minB >= left[i].minB) {
pr++;
}
if (pr >= 0) {
double v = left[i].minA * left[i].minB * (double) (left[i].len + right[pr].len);
ans = std::max(ans, v);
}
}
int pl = -1;
for (int j = 0; j < szR; j++) {
while (pl + 1 < szL && left[pl + 1].minA > right[j].minA && left[pl + 1].minB > right[j].minB) {
pl++;
}
if (pl >= 0) {
double v = right[j].minA * right[j].minB * (double) (left[pl].len + right[j].len);
ans = std::max(ans, v);
}
}
hull hullA;
int hi = -1, lo = 0, add = 0;
hullA.clear();
for (int j = 0; j < szR; j++) {
while (hi + 1 < szL && left[hi + 1].minB > right[j].minB) {
hi++;
}
while (lo < szL && left[lo].minA > right[j].minA) {
lo++;
}
while (add <= hi) {
double slope = left[add].minA, inter = left[add].minA * (double) left[add].len;
hullA.addLine(slope, inter, add);
add++;
}
if (lo <= hi && hullA.empty() == false) {
double best = hullA.query((double) right[j].len, lo);
double v = best * right[j].minB;
ans = std::max(ans, v);
}
}
hull hullB;
hi = -1;
lo = 0;
add = 0;
hullB.clear();
for (int j = 0; j < szR; j++) {
while (hi + 1 < szL && left[hi + 1].minA > right[j].minA) {
hi++;
}
while (lo < szL && left[lo].minB > right[j].minB) {
lo++;
}
while (add <= hi) {
double slope = left[add].minB, inter = left[add].minB * (double) left[add].len;
hullB.addLine(slope, inter, add);
add++;
}
if (lo <= hi && hullB.empty() == false) {
double best = hullB.query((double) right[j].len, lo);
double v = best * right[j].minA;
ans = std::max(ans, v);
}
}
return ans;
}
double solve(int l, int r) {
if (l == r) {
return a[l] * b[l];
}
int mid = (l + r) / 2;
double ans = 0.0;
ans = std::max(ans, solve(l, mid));
ans = std::max(ans, solve(mid + 1, r));
ans = std::max(ans, crossSolve(l, mid, r));
return ans;
}
int main() {
int n;
std::cin >> n;
a.resize(n + 1);
b.resize(n + 1);
for (int i = 1; i <= n; i++) {
std::cin >> a[i] >> b[i];
}
std::cout << solve(1, n);
return 0;
}