/*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;
}