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