// Original C++ solution (slower):
#include <cstdio>

#include <iostream>

#include <algorithm>

#include <cstring>

#include <vector>

#include <queue>

#define PII pair<int,int>

#define MP make_pair

#define fir first

#define sec second

#define PB push_back

#define db long double

#define ll long long

using namespace std;

template <class T>

inline void rd(T &x) {

	x=0; char c=getchar(); int f=1;

	while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); }

	while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f;

}

const int N=1010,inf=1e9;

inline int Abs(int x) { return x>0?x:-x; }

int S,T;

namespace Flow {

	const int N=5010;

	int head[N],cur[N],vis[N];

	ll dis[N];

	struct ed { int to,next,f; ll w; };

	vector<ed> e;

	void init() { e.clear(); memset(head,-1,sizeof(head)); }

	void ad(int x,int y,int f,ll w) {

		e.PB((ed){y,head[x],f,w}); head[x]=e.size()-1;

		e.PB((ed){x,head[y],0,-w}); head[y]=e.size()-1;

	}

	queue<int> q;

	bool bfs() {

		memset(dis,-0x3f,sizeof(dis));

		memcpy(cur,head,sizeof(cur));

		dis[S]=0,q.push(S),vis[S]=1;

		while(!q.empty()) {

			int u=q.front(); q.pop(),vis[u]=0;

			for(int k=head[u];~k;k=e[k].next) if(e[k].f) {

				int v=e[k].to;

				if(dis[v]<dis[u]+e[k].w) {

					dis[v]=dis[u]+e[k].w;

					if(!vis[v]) q.push(v),vis[v]=1;

				}

			}

		}

		return dis[T]>-1e16;

	}

	int dfs(int u,int f) {

		if(u==T||!f) return f; int ret=0,tmp;

		vis[u]=1;

		for(int &k=cur[u];~k;k=e[k].next) if(e[k].f) {

			int v=e[k].to;

			if(dis[v]==dis[u]+e[k].w&&!vis[v]&&(tmp=dfs(v,min(f,e[k].f)))) {

				f-=tmp,ret+=tmp;

				e[k].f-=tmp,e[k^1].f+=tmp;

				if(!f) break;

			}

		}

		vis[u]=0;

		return ret;

	}

	ll work() { ll ans=0; while(bfs()) ans+=dis[T]*dfs(S,1e9); return ans; }

}

int rx[N],ry[N],rc[N];

int bx[N],by[N],bc[N];

int n;

int main() {

	rd(n);

	for(int i=1;i<=n;++i) rd(rx[i]),rd(ry[i]),rd(rc[i]);

	for(int i=1;i<=n;++i) rd(bx[i]),rd(by[i]),rd(bc[i]);

	S=2*n+1,T=2*n+2;

	int p[4];

	for(int i=0;i<4;++i) p[i]=2*n+3+i;

	Flow::init();

	for(int i=1;i<=n;++i) {

		Flow::ad(S,i,rc[i],0);

		Flow::ad(i+n,T,bc[i],0);

	}

	for(int i=1;i<=n;++i) {

		Flow::ad(i,p[0],inf,rx[i]+ry[i]);

		Flow::ad(i,p[1],inf,rx[i]-ry[i]);

		Flow::ad(i,p[2],inf,-rx[i]+ry[i]);

		Flow::ad(i,p[3],inf,-rx[i]-ry[i]);

		

		Flow::ad(p[0],i+n,inf,-bx[i]-by[i]);

		Flow::ad(p[1],i+n,inf,-bx[i]+by[i]);

		Flow::ad(p[2],i+n,inf,bx[i]-by[i]);

		Flow::ad(p[3],i+n,inf,bx[i]+by[i]);

	}

	printf("%lld",Flow::work());

	return 0;

}


// Optimized solution to the same problem (faster):
#include<set>

#include<map>

#include<queue>

#include<cmath>

#include<string>

#include<cstdio>

#include<vector>

#include<cstring>

#include<iomanip>

#include<iostream>

#include<algorithm>

#define rep(i,a,b) for (int i=a; i<=b; i++)

#define per(i,a,b) for (int i=a; i>=b; i--)

using namespace std;



const int maxn=3010, maxm=2022000;

const long long inf=9999999999;

typedef long long LL;



struct Edge{

	Edge(){};

	Edge(int a,int b,LL c,int d){v=a;f=b;w=c;nxt=d;};

	int v,f,nxt;

	LL w;

};



int n,lmt;

int g[maxn+10];

Edge e[maxm+10];

int nume;

int src,sink;



void addedge(int u,int v,int c,LL w){

	e[++nume]=Edge(v,c,w,g[u]);

	g[u]=nume;

	e[++nume]=Edge(u,0,-w,g[v]);

	g[v]=nume;

}



queue<int> que;

bool inQue[maxn+10];

LL dist[maxn+10];

int pren[maxn+10];

int pree[maxn+10];



bool findPath(){

	while(!que.empty())que.pop();

	que.push(src);

	memset(dist,0x3f,sizeof(dist));

	dist[src]=0;inQue[src]=true;

	while(!que.empty()){

		int u=que.front();

		//cout<<u<<endl;

		que.pop();

		for(int i=g[u];i;i=e[i].nxt){

			if((e[i].f>0) && (dist[u]+e[i].w<dist[e[i].v])){

				dist[e[i].v]=dist[u]+e[i].w;

				pren[e[i].v]=u;pree[e[i].v]=i;

				if(!inQue[e[i].v]){

					inQue[e[i].v]=true;

					que.push(e[i].v);

				}

			}

		}

		inQue[u]=false;

	}

	if(dist[sink]<dist[3001])return true;

	return false;

}



LL augment(){

	int u=sink;

	LL delta=inf;

	while(u!=src){

		if(e[pree[u]].f<delta)delta=e[pree[u]].f;

		u=pren[u];

	}

	u=sink;

	while(u!=src){

		e[pree[u]].f-=delta;

		e[pree[u]^1].f+=delta;

		u=pren[u];

	}

	return dist[sink]*delta;

}



LL mincostflow(){

	LL cur=0;

	while(findPath()){

		cur+=augment();

		//rep(i,1,2*n+1)cout<<i<<" "<<dist[i]<<endl;

	}

	return cur;

}



LL RX[1010],RY[1010],BX[1010],BY[1010];

int RC[1010],BC[1010];

int A,B,C,D;

int main() {

	std::ios::sync_with_stdio(false);

	//freopen("ttt.txt","r",stdin);

	cin>>n;

	rep(i,1,n)cin>>RX[i]>>RY[i]>>RC[i];

	rep(i,1,n)cin>>BX[i]>>BY[i]>>BC[i];

	sink=1;src=0;nume=1;



	memset(g,0,sizeof(g));

	rep(i,1,n)addedge(0,i+1,RC[i],0);

	rep(i,1,n)addedge(i+n+1,1,BC[i],0);

	A=2*n+2;B=A+1;C=B+1;D=C+1;

	rep(i,1,n){

		addedge(i+1,A,10,RX[i]+RY[i]);

		addedge(i+1,B,10,RX[i]-RY[i]);

		addedge(i+1,C,10,-RX[i]+RY[i]);

		addedge(i+1,D,10,-RX[i]-RY[i]);

	}

	rep(i,1,n){

		addedge(A,i+n+1,10,-BX[i]-BY[i]);

		addedge(B,i+n+1,10,-BX[i]+BY[i]);

		addedge(C,i+n+1,10,BX[i]-BY[i]);

		addedge(D,i+n+1,10,BX[i]+BY[i]);

	}

	

	//cout<<"prep"<<endl;

	cout<<-mincostflow()<<endl;

	return 0;

}

// Fastest known solution for this problem: