#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#define ll long long
#define lll __int128

using namespace std;

typedef struct {
  ll x, y;
  int i;
} point;

bool operator<(point a, point b) {
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
bool operator==(point a, point b) {
  return a.x == b.x && a.y == b.y;
}

ll proizv(point a, point b, point c) { // ccw
  // dy2*dx1-dy1*dx2 > 0
  // 2 = c-a
  // 1 = b-a
  return (c.y-a.y)*(b.x-a.x) - (b.y-a.y)*(c.x-a.x);
}

bool left(point a, point b, point c) { // ccw
  // dy2*dx1-dy1*dx2 > 0
  // 2 = c-a
  // 1 = b-a
  return (c.y-a.y)*(b.x-a.x) - (b.y-a.y)*(c.x-a.x) > 0;
}

vector<point> omot(vector<point>& A) {
  int n = A.size(), k = 0;
  if (n <= 3) return A;
  vector<point> ans(2 * n);
  sort(A.begin(), A.end());

  for (int i=0; i<n; i++) {
    while (k >= 2 && proizv(ans[k-2], ans[k-1], A[i]) <= 0) {
      k--;
    }
    ans[k++] = A[i];
  }

  
  for (size_t i=n-1, t=k+1; i>0; i--) {
    while (k >= t && proizv(ans[k-2], ans[k-1], A[i-1]) <= 0) {
      k--;
    }
    ans[k++] = A[i-1];
  }

  ans.resize(k - 1);
  return ans;
}

lll povrs(vector<point>& r) { // castovanje ???
  int n = r.size();
  lll area = 0;
  for (int i=0; i<n-1; i++) {
    area += r[i].x * r[i+1].y - r[i+1].x * r[i].y;
  }
  area += r[n-1].x * r[0].y - r[0].x * r[n-1].y;
  return abs(area)/2;
}


int main() {
  int n;
  scanf("%d", &n);
  vector<point> a(n);
  for (int i=0; i<n; i++) {
    scanf("%lld %lld", &a[i].x, &a[i].y);
    a[i].i = i;
  }
  
  vector<point> r = omot(a);
  int m = r.size();
  lll minP = povrs(r);

  map<int, int> rindex;
  for (int i=0; i<m; i++) {
     rindex[r[i].i] = i; // index u a -> index u r
  }

  // za ivicu omotaca spisak tacaka koje ako se ukloni trougao sa max povrsinom
  // mozda moraju da se dodaju u omotac
  vector<vector<int>> cudni(m);
  int next, prev;
  for (int i=0; i<m; i++) {
    if (i+1>=m) next = 0;
    else next = i+1;
    for (int j=0; j<n; j++) {
      if (rindex.count(a[j].i) == 1) continue; // ivica
      if (left(r[i], r[next], a[j])) cudni[i].push_back(j);
    }
  }

  for (int i=0; i<m; i++) {
    vector<point> temp; // bez i
    for (int j=0; j<m; j++) {
      if (j != i) temp.push_back(r[j]);
    }

    /*if (i-1<0) prev = m-1;
    else prev = i-1;*/
    for (auto el : cudni[(i-1<0)?m-1:i-1]) {
      temp.push_back(a[el]);
    }
    for (auto el : cudni[i]) {
      temp.push_back(a[el]);
    }
    
    sort(temp.begin(), temp.end());
    temp.erase(unique(temp.begin(), temp.end()), temp.end());

    vector<point> tempR = omot(temp);
    lll pp = povrs(tempR);
    if (pp < minP) {
      minP = pp;
    }
  }

  printf("%lld", (ll)minP);

  return 0;
}