/*POJ 2836狀態(tài)壓縮dp
只有15個點,每個點用二進制中的一位來表示
預處理,枚舉n*(n-1)/2個矩形,每個矩形的有自己的狀態(tài)(覆蓋的點)和面積
狀態(tài)轉(zhuǎn)移方程
 for(i,0,rectanglenum)             
    for(st,0,(1<<n))
        if(第i個矩形覆蓋的點未全部加進集合) 
             dp[nst]=min(dp[nst],dp[st]+area[i];
其中nst為點加進集合后的新狀態(tài) 
*/ 
#include
<iostream>
#include
<algorithm>
#include
<cmath>
#define REP(i,n) for(int i=0;i<n;i++)
#define FOR(i,L,R) for(int i=L;i<=R;i++)
#define INF 10000000
using namespace std;
struct point{
    
int x,y;
}pt[
15];
struct node{
    
int state,area;
}rec[
200];
int rnum=0;//矩形的數(shù)量 
int dp[(1<<15)];
int n;
int main()
{
    
while(scanf("%d",&n)!=EOF&&n)
    {
        rnum
=0;
        REP(i,n)
            scanf(
"%d %d",&pt[i].x,&pt[i].y);
        REP(i,n)
        {
            FOR(j,i
+1,n-1)
            {
                
int st=(1<<i)+(1<<j);
                REP(k,n)
                    
if((pt[k].x-pt[i].x)*(pt[k].x-pt[j].x)<=0&&(pt[k].y-pt[i].y)*(pt[k].y-pt[j].y)<=0)
                        st
|=(1<<k);
                rec[rnum].state
=st;
                
if(pt[i].x==pt[j].x)
                    rec[rnum
++].area=abs(pt[j].y-pt[i].y);
                
else if(pt[i].y==pt[j].y)
                    rec[rnum
++].area=abs(pt[j].x-pt[i].x);
                
else rec[rnum++].area=abs(pt[j].x-pt[i].x)*abs(pt[j].y-pt[i].y);
            }
        }
        fill_n(dp,(
1<<15),INF); 
        dp[
0]=0;
        REP(i,rnum)
        {
            REP(st,(
1<<n)-1)
            {
                
if(dp[st]==INF)
                    
continue;
                
if((st|(rec[i].state))==st)//已經(jīng)加進集合 
                    continue;
                dp[st
|(rec[i].state)]=min(dp[st|(rec[i].state)],dp[st]+rec[i].area);
            }
        }
        printf(
"%d\n",dp[(1<<n)-1]);
    }
    
return 0;
}