/*POJ 2836状态压缩dp
只有15个点,每个点用二进制中的一位来表示
预处理,枚举n*(n-1)/2个矩形,每个矩形的有自己的状态(覆盖的点)和面积
状态转移方程
 for(i,0,rectanglenum)             
    for(st,0,(1<<n))
        if(第i个矩形覆盖的点未全部加进集合) 
             dp[nst]=min(dp[nst],dp[st]+area[i];
其中nst为点加进集合后的新状态 
*/ 
#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;//矩形的数量 
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)//已经加进集合 
                    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;
}