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;
inline long double minOf(long double x, long double y) {
  return (x < y ? x : y);
}
inline long long maxOf(long long x, long long y) { return (x > y ? x : y); }
struct Point {
  long double x;
  long double y;
} p[305];
bool isLeft(Point a, Point b, Point c) {
  return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) > 0;
}
long double area(Point a, Point b, Point c) {
  long double ret =
      ((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) / 2.0;
  if (ret < 0.0) ret = -ret;
  return ret;
}
long double wastage[305][305];
long double nextmem[305][305][5];
bool visited[305][305][5];
vector<int> hull;
long double F(int start, int cur, int vnum) {
  if (visited[hull[start]][hull[cur]][vnum]) {
    return nextmem[hull[start]][hull[cur]][vnum];
  }
  visited[hull[start]][hull[cur]][vnum] = true;
  if (start == cur && vnum != 1) {
    nextmem[hull[start]][hull[cur]][vnum] = 900000000ULL;
    return 900000000ULL;
  }
  if (vnum == 4) {
    nextmem[hull[start]][hull[cur]][vnum] = wastage[hull[cur]][hull[start]];
    return wastage[hull[cur]][hull[start]];
  }
  nextmem[hull[start]][hull[cur]][vnum] = 900000000ULL;
  long double retVal;
  for (int i = (cur + 1) % hull.size(); i != start;) {
    retVal = (F(start, i, vnum + 1) + wastage[hull[cur]][hull[i]]);
    if (retVal < nextmem[hull[start]][hull[cur]][vnum]) {
      nextmem[hull[start]][hull[cur]][vnum] = retVal;
    }
    i = (i + 1) % hull.size();
  }
  return nextmem[hull[start]][hull[cur]][vnum];
}
long double trap(Point a, Point b) { return (0.5 * (b.x - a.x) * (b.y + a.y)); }
int main() {
  ios_base::sync_with_stdio(false);
  long long n;
  cin >> n;
  int leftMost = 0;
  for (int i = 0; i < n; i++) {
    cin >> p[i].x;
    cin >> p[i].y;
    if (p[i].x < p[leftMost].x) leftMost = i;
  }
  int cur = leftMost;
  long double totalArea = 0.0;
  long double minArea = 900000000ULL;
  hull.push_back(leftMost);
  bool allRight;
  do {
    for (int i = 0; i < n; i++) {
      allRight = true;
      if (i == cur) continue;
      for (int j = 0; j < n; j++) {
        if (j == i || j == cur) continue;
        if (isLeft(p[cur], p[i], p[j])) {
          allRight = false;
          break;
        }
      }
      if (allRight) {
        if (i != leftMost) hull.push_back(i);
        cur = i;
        break;
      }
    }
  } while (cur != leftMost);
  if (hull.size() < 4) {
    minArea = 0;
    bool found = false;
    for (int i = 0; i < n; i++) {
      totalArea = 0.0;
      found = false;
      for (int j = 0; j < hull.size(); j++) {
        if (i == hull[j]) {
          found = true;
          break;
        }
      }
      if (found) continue;
      hull.push_back(i);
      for (int i = 0; i < hull.size(); i++)
        totalArea += trap(p[hull[i]], p[hull[(i + 1) % hull.size()]]);
      if (totalArea < 0) totalArea = -totalArea;
      if (totalArea > minArea) minArea = totalArea;
      hull.pop_back();
    }
    cout << setprecision(9) << minArea << "\n";
    return 0;
  }
  for (int i = 0; i < hull.size(); i++)
    totalArea += trap(p[hull[i]], p[hull[(i + 1) % hull.size()]]);
  if (totalArea < 0) totalArea = -totalArea;
  memset(wastage, 0, sizeof(wastage));
  long double loss;
  int k;
  for (int i = 0; i < hull.size(); i++) {
    loss = 0.0;
    k = (i + 1) % hull.size();
    wastage[hull[i]][hull[k]] = 0;
    for (int j = (i + 2) % hull.size(); j != i;
         k = (k + 1) % hull.size(), j = (j + 1) % hull.size()) {
      wastage[hull[k]][hull[j]] = 0;
      wastage[hull[i]][hull[j]] =
          area(p[hull[i]], p[hull[k]], p[hull[j]]) + loss;
      loss = wastage[hull[i]][hull[j]];
    }
  }
  memset(visited, 0, sizeof(visited));
  for (int i = 0; i < hull.size(); i++) minArea = minOf(minArea, F(i, i, 1));
  totalArea -= minArea;
  cout << setprecision(9) << totalArea << "\n";
  return 0;
}