Problem: Iahub has drawn a set of n points in the cartesian plane which he calls "special points". A quadrilateral is a simple polygon without self-intersections with four sides (also called edges) and four vertices (also called corners). Please note that a quadrilateral doesn't have to be convex. A special quadrilateral is one which has all four vertices in the set of special points. Given the set of special points, please calculate the maximal area of a special quadrilateral. 

Input

The first line contains integer n (4 ≤ n ≤ 300). Each of the next n lines contains two integers: xi, yi ( - 1000 ≤ xi, yi ≤ 1000) — the cartesian coordinates of ith special point. It is guaranteed that no three points are on the same line. It is guaranteed that no two points coincide. 

Output

Output a single real number — the maximal area of a special quadrilateral. The answer will be considered correct if its absolute or relative error does't exceed 10 - 9.

Examples

Input

5
0 0
0 4
4 0
4 4
2 3


Output

16.000000

Note

In the test example we can choose first 4 points to be the vertices of the quadrilateral. They form a square by side 4, so the area is 4·4 = 16.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 305;
const long double INF = 9e18;
struct pt {
  long long x, y;
  pt() {}
  pt(long long xx, long long yy) : x(xx), y(yy) {}
  long long operator%(const pt &o) const { return x * o.y - y * o.x; }
  long long operator*(const pt &o) const { return x * o.x + y * o.y; }
  pt operator-(const pt &o) const { return pt(x - o.x, y - o.y); }
  pt operator+(const pt &o) const { return pt(x + o.x, y - o.y); }
  bool operator<(const pt &o) const {
    if (x == o.x) return y < o.y;
    return x < o.x;
  }
  bool operator==(const pt &o) const { return (x == o.x && y == o.y); }
  bool cw(const pt &a, const pt &b) { return (b - a) % (*this - a) > 0; }
};
vector<pt> chull(pt p[], int n) {
  sort(p, p + n);
  vector<pt> r;
  for (int i = 0; i < int(n); i++) {
    while ((int)r.size() >= 2 && r.back().cw(r[(int)r.size() - 2], p[i]))
      r.pop_back();
    r.push_back(p[i]);
  }
  r.pop_back();
  int k = r.size();
  for (int i = int(n) - 1; i >= 0; i--) {
    while ((int)r.size() >= k + 2 && r.back().cw(r[(int)r.size() - 2], p[i]))
      r.pop_back();
    r.push_back(p[i]);
  }
  r.pop_back();
  return r;
}
pt poly[MAXN];
long double getArea(vector<pt> &p) {
  long double r = 0;
  for (int i = 0; i < int(p.size()); i++) {
    int j = (i + 1) % ((int)p.size());
    r += ((p[j] - p[i]) % (pt(0, 0) - p[i])) / 2.0;
  }
  return abs(r);
}
pair<long double, long double> dp[MAXN][MAXN];
long double solve(vector<pt> &chull) {
  int n = chull.size();
  for (int i = 0; i < int(n); i++)
    for (int k = int(2); k < int(n); k++) {
      pair<long double, long double> tmp = {INF, -INF};
      for (int j = int(1); j < int(k); j++) {
        int i2 = (i + j) % ((int)chull.size());
        int i3 = (i + k) % ((int)chull.size());
        long double val =
            ((chull[i2] - chull[i]) % (pt(0, 0) - chull[i])) / 2.0 +
            ((chull[i3] - chull[i2]) % (pt(0, 0) - chull[i2])) / 2.0;
        tmp = {min(tmp.first, val), max(tmp.second, val)};
      }
      dp[i][(i + k) % n] = tmp;
    }
  for (int i = 0; i < int(MAXN); i++)
    for (int j = 0; j < int(MAXN); j++) {
      if (dp[i][j].first == INF) dp[i][j].first = 0;
      if (dp[i][j].second == -INF) dp[i][j].second = 0;
    }
  long double maxi = -1;
  for (int i = 0; i < int(n); i++)
    for (int j = int(i + 1); j < int(n); j++)
      for (int k = int(j + 1); k < int(n); k++) {
        long double acc =
            ((chull[j] - chull[i]) % (pt(0, 0) - chull[i])) / 2.0 +
            ((chull[k] - chull[j]) % (pt(0, 0) - chull[j])) / 2.0;
        maxi =
            max({maxi, abs(acc + dp[k][i].first), abs(acc + dp[k][i].second)});
      }
  return maxi;
}
long double edgeCase(vector<pt> &chull, pt a[], int n) {
  long double baseArea = getArea(chull);
  long double maxi = -1;
  for (int i = 0; i < int(n); i++) {
    bool repeat = false;
    for (auto &j : chull)
      if (j == a[i]) {
        repeat = true;
        break;
      }
    if (repeat) continue;
    for (int j = 0; j < int(chull.size()); j++) {
      int k = (j + 1) % ((int)chull.size());
      long double aux = ((a[i] - chull[j]) % (chull[k] - a[i])) / 2.0;
      aux = abs(aux);
      maxi = max(maxi, baseArea - aux);
    }
  }
  return maxi;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  ;
  for (int i = 0; i < int(MAXN); i++)
    for (int j = 0; j < int(MAXN); j++) dp[i][j] = {INF, -INF};
  int n;
  cin >> n;
  for (int i = 0; i < int(n); i++) cin >> poly[i].x >> poly[i].y;
  vector<pt> aux = chull(poly, n);
  cout << fixed << setprecision(15);
  if (aux.size() < 4) return cout << edgeCase(aux, poly, n), 0;
  cout << solve(aux);
  return 0;
}