#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mp make_pair
#define pb push_back
#define F first
#define S second
#define debug(x) std::cout << #x << ": " << x << "\n"
#define all(v) v.begin(), v.end()
#define li(i,a,b) for (int (i) = (a); (i) < (b); (i)++)
#define endl '\n'
#define mem(name,val) memset(name,val,sizeof(name))
#define min(a,b) (a<=b ? a : b)
#define max(a,b) (a>=b ? a : b)
//using u64 = uint64_t;
//using u128 = __uint128_t;

struct pt {
    ll x, y;
    bool operator == (pt const& t) const {
        return x == t.x && y == t.y;
    }
};

struct KDNode {
    pt point;     
    KDNode* left;    
    KDNode* right;   

    KDNode(const pt& pt) : point(pt), left(nullptr), right(nullptr) {}
};

bool comparePoints(const pt& a, const pt& b, int depth) {
    if (depth % 2 == 0)
        return a.x < b.x; 
    else
        return a.y < b.y;  
}

KDNode* buildKDTree(std::vector<pt>::iterator begin, std::vector<pt>::iterator end, int depth) {
    if (begin >= end)
        return nullptr;

    std::sort(begin, end, [depth](const pt& a, const pt& b) {
        return comparePoints(a, b, depth);
    });

    auto mid = begin + (end - begin) / 2;
    KDNode* node = new KDNode(*mid);

    node->left = buildKDTree(begin, mid, depth + 1);
    node->right = buildKDTree(mid + 1, end, depth + 1);

    return node;
}

void rangeQuery(KDNode* node, ll x_min, ll x_max, ll y_min, ll y_max, ll depth, std::vector<pt>& result) {
    if (!node)
        return;

    ll x = node->point.x;
    ll y = node->point.y;

    if (x_min <= x && x <= x_max && y_min <= y && y <= y_max)
        result.push_back(node->point);

    if (depth % 2 == 0) {  
        if (x_min <= x)
            rangeQuery(node->left, x_min, x_max, y_min, y_max, depth + 1, result);
        if (x <= x_max)
            rangeQuery(node->right, x_min, x_max, y_min, y_max, depth + 1, result);
    } else {  
        if (y_min <= y)
            rangeQuery(node->left, x_min, x_max, y_min, y_max, depth + 1, result);
        if (y <= y_max)
            rangeQuery(node->right, x_min, x_max, y_min, y_max, depth + 1, result);
    }
}

int orientation(pt a, pt b, pt c) {
    double v = a.x*(b.y-c.y)+b.x*(c.y-a.y)+c.x*(a.y-b.y);
    if (v < 0) return -1; // clockwise
    if (v > 0) return +1; // counter-clockwise
    return 0;
}

bool cw(pt a, pt b, pt c) {
    int o = orientation(a, b, c);
    return o < 0;
}

vector<pt> convex_hull(vector<pt>& a) {
    pt p0 = *min_element(a.begin(), a.end(), [](pt a, pt b) {
        return make_pair(a.y, a.x) < make_pair(b.y, b.x);
    });
    sort(a.begin(), a.end(), [&p0](const pt& a, const pt& b) {
        int o = orientation(p0, a, b);
        if (o == 0)
            return (p0.x-a.x)*(p0.x-a.x) + (p0.y-a.y)*(p0.y-a.y)
                < (p0.x-b.x)*(p0.x-b.x) + (p0.y-b.y)*(p0.y-b.y);
        return o < 0;
    });

    vector<pt> st;
    for (int i = 0; i < (int)a.size(); i++) {
        while (st.size() > 1 && !cw(st[st.size()-2], st.back(), a[i]))
            st.pop_back();
        st.push_back(a[i]);
    }

    return st;
}

ll polygonArea(const vector<pt>& points) {
    ll area = 0;
    int n = points.size();

    for (int i = 0; i < n; i++) {
        ll x1 = points[i].x;
        ll y1 = points[i].y;
        ll x2 = points[(i + 1) % n].x;
        ll y2 = points[(i + 1) % n].y;

        area += (x1 * y2) - (x2 * y1);
    }

    return (ll)((area > 0 ? area : -area) / 2);
}

bool inTriangle(const pt& A, const pt& B, const pt& C, const pt& P) {
    int o1 = orientation(A, B, P);
    int o2 = orientation(B, C, P);
    int o3 = orientation(C, A, P);

    if (o1 == 0 || o2 == 0 || o3 == 0)
        return true;

    bool has_neg = (o1 < 0) || (o2 < 0) || (o3 < 0);
    bool has_pos = (o1 > 0) || (o2 > 0) || (o3 > 0);

    return !(has_neg && has_pos);
}

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);    

    int n;
    cin>>n;
    vector<pt> points(n); 
    li(i,0,n){
        cin>>points[i].x>>points[i].y;
    }

    KDNode* root = buildKDTree(points.begin(), points.end(), 0);
    vector<pt> hull = convex_hull(points);

    ll area = polygonArea(hull);
    ll minarea = area;

    int hs = hull.size();
    for(int i = 0; i<hs; i++){
        ll tarea = polygonArea({hull[(i-1+hs)%hs], hull[i], hull[(i+1)%hs]});

        pt p1 = hull[(i-1+hs)%hs], p2 = hull[(i+1)%hs];

        int x_min = min(p1.x, p2.x), x_max = max(p1.x, p2.x), y_min = min(p1.y, p2.y), y_max = max(p1.y, p2.y);
        vector<pt> raw;
        rangeQuery(root, x_min, x_max, y_min, y_max, 0, raw);

        vector<pt> valid; 
        for(pt p : raw){
            if(p == hull[i]) continue; 
            if(inTriangle(p1, hull[i], p2, p)){
                valid.pb(p);
            }
        }

        if(hs == 3 and valid.size() == 2){
            continue;
        }

        if(valid.size() == 2){
            minarea = min(minarea, area - tarea);
        }
        else{
            vector<pt> new_hull = convex_hull(valid);
            ll new_area = polygonArea(new_hull);

            minarea = min(minarea, area-tarea+new_area);
        }
    }
    
    cout<<minarea;

    return 0;
}