#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int inf=0x3f3f3f;
struct node{
	int nxt,to,weigh,flow;
}edge[200100];
int pre[10010],maxflow,mincost;
int m,n,S,T,R,cnt=1,head[10010];
int dis[10010],flow[10010],Find[10010],last[10010];
std::queue<int>qu;
void addedge(int x,int y,int z,int w){
	edge[++cnt].nxt=head[x];
	edge[cnt].to=y;
	edge[cnt].flow=z;
	edge[cnt].weigh=w;
	head[x]=cnt;
	edge[++cnt].nxt=head[y];
	edge[cnt].to=x;
	edge[cnt].flow=0;
	edge[cnt].weigh=-w;
	head[y]=cnt;
}
bool SPFA(){
	memset(dis,0x3f,sizeof(dis));
	memset(flow,0x3f,sizeof(flow));
	memset(Find,false,sizeof(Find));
	dis[S]=0;
	Find[S]=true;
	pre[T]=-1;
	qu.push(S);
	while(!qu.empty()){
		int u=qu.front();
		qu.pop();
		Find[u]=0;
		for(int i=head[u];i;i=edge[i].nxt){
			int upup=edge[i].to;
			if(edge[i].flow>0 && dis[u]+edge[i].weigh<dis[upup]){
				dis[upup]=dis[u]+edge[i].weigh;
				pre[upup]=u;
				last[upup]=i;
				flow[upup]=min(flow[u],edge[i].flow);
				if(!Find[upup]){
					Find[upup]=1;
					qu.push(upup);
				}
			}
		Find[u]=false;
		}
	}
	return pre[T]!=-1;
}
void MCMF(){
	maxflow=0;
	while(SPFA()){
		maxflow+=flow[T];
		mincost+=flow[T]*dis[T];
		int now=T;
		while(now!=S){
			edge[last[now]].flow-=flow[T];
			edge[last[now]^1].flow+=flow[T];
			now=pre[now];
		}
	}
}
signed main(){
    scanf("%lld",&n);
    int x,y,z;
    S=0,T=2*n+5;
    for(int i=1;i<=n;i++){
    	scanf("%lld%lld%lld",&x,&y,&z);
    	addedge(S,i,z,0);
    	addedge(i,2*n+1,z,x+y);
    	addedge(i,2*n+2,z,x-y);
    	addedge(i,2*n+3,z,-x+y);
    	addedge(i,2*n+4,z,-x-y);
    }
    for(int i=n+1;i<=2*n;i++){
    	scanf("%lld%lld%lld",&x,&y,&z);
    	addedge(2*n+4,i,z,x+y);
    	addedge(2*n+3,i,z,x-y);
    	addedge(2*n+2,i,z,-x+y);
    	addedge(2*n+1,i,z,-x-y);
    	addedge(i,T,z,0);
    }  
    MCMF();
    printf("%lld\n",-mincost);
    return 0;
}