#include<bits/stdc++.h>
using namespace std;

#define ll long long
struct Tacka
{
    ll x, y;
};


//ispod vrha mi treba
Tacka nextToTop(stack<Tacka>& S)
{
    Tacka p = S.top();
    S.pop();
    Tacka res = S.top();
    S.push(p);
    return res;
}

//za dve tacke izmena
void zameniTacke(Tacka& p1, Tacka& p2)
{
    Tacka temp = p1;
    p1 = p2;
    p2 = temp;
}


ll distSq(Tacka p1, Tacka p2)
{
    return (p1.x - p2.x) * (p1.x - p2.x) +
        (p1.y - p2.y) * (p1.y - p2.y);
}

ll orjentacija(Tacka p, Tacka q, Tacka r)
{
    ll val = (q.y - p.y) * (r.x - q.x) -
        (q.x - p.x) * (r.y - q.y);

    if (val == 0) return 0;  // kolinearne iako tvrde da nece budu xdd
    return (val > 0) ? 1 : 2; // clock i kontraclock
}

Tacka p0;
int cmp(const void* vp1, const void* vp2)
{
    Tacka* p1 = (Tacka*)vp1;
    Tacka* p2 = (Tacka*)vp2;

    int o = orjentacija(p0, *p1, *p2);
    if (o == 0)
        return (distSq(p0, *p2) >= distSq(p0, *p1)) ? -1 : 1;

    return (o == 2) ? -1 : 1;
}

void convexHull(Tacka tackice[], ll n, vector<Tacka>& tackePoligona)
{
    //u ovaj algoritam se umesto x koristi y kao orjentir pa trazim prvo
    ll ymin = tackice[0].y, min = 0;
    for (int i = 1; i < n; i++)
    {
        ll y = tackice[i].y;

    //ovo ako je nereseno
        if ((y < ymin) || (ymin == y &&
            tackice[i].x < tackice[min].x))
            ymin = tackice[i].y, min = i;
    }

    //prva je najmanja ok
    zameniTacke(tackice[0], tackice[min]);


    //ovde kad citam nekad opet da ovaj compare iz nekog razloga mi je trazio da bude int a ne ll
    p0 = tackice[0];
    qsort(&tackice[1], n - 1, sizeof(Tacka), cmp);

    
    ll m = 1;
    for (ll i = 1; i < n; i++)
    {

        while (i < n - 1 && orjentacija(p0, tackice[i],
            tackice[i + 1]) == 0)
            i++;


        tackice[m] = tackice[i];
        m++;
    }

    //ovo tvrde da se nece desi al ok opet
    if (m < 3) return;



    stack<Tacka> stek;
    stek.push(tackice[0]);
    stek.push(tackice[1]);
    stek.push(tackice[2]);

    for (ll i = 3; i < m; i++)
    {
        while (stek.size() > 1 && orjentacija(nextToTop(stek), stek.top(), tackice[i]) != 2)
            stek.pop();

        stek.push(tackice[i]);
    }

    while (!stek.empty())
    {
        Tacka p = stek.top();
        tackePoligona.push_back(p);
        stek.pop();
    }
}

ll povrsinaPoligona(vector<Tacka>& tackePoligona, ll n)
{
    ll povrsina = 0;

    //ovo je sad na dalje za ovu sholecovu formulu implementacija verujemo xdd dokazali ljudi
    ll j = n - 1;
    for (ll i = 0; i < n; i++)
    {
        povrsina += (tackePoligona[j].x + tackePoligona[i].x) * (tackePoligona[j].y - tackePoligona[i].y);
        j = i;
    }

    return abs(povrsina / 2);
}

int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    ll n;
    cin >> n;
    Tacka tacke[10005];
    Tacka bezi[10000];
    for (ll i = 0; i < n; i++)
    {
        cin >> tacke[i].x >> tacke[i].y;
    }

    ll povrsina = LLONG_MAX;
    for (int i = 0; i < n; i++)
    {
        ll k = 0;
        ll l = 0;
        while (l < n - 1)
        {
            if (k == i)
            {
                k++;
            }
            bezi[l++] = tacke[k++];
        }
        vector<Tacka> tackePoligona;
        convexHull(bezi, n - 1, tackePoligona);
        //sad povrsinu za tacke poligona;
        povrsina = min(povrsina, povrsinaPoligona(tackePoligona, tackePoligona.size()));
        tackePoligona.clear();
    }

    cout << povrsina << endl;
    return 0;
}