/*
author: madhav_1999 aka orthodoxparadox
02-Jun-2019
23:15:10
*/

#include <bits/stdc++.h>
#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define dbl long double
#define int ll
#define ll long long
#define sz(x) ((long long) x.size())
#define pii pair<int, int>
#define fup(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define len(x) sz(x)
#define fnu for(ll i = 0; i < n; i++)
#define trav(x, v) for(auto &x : v)
#define rev(Y) reverse(all(Y))
#define oiint ostream_iterator<int>(cout, " ") 
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(a) a.begin(), a.end()
#define initialise(a, x) memset(a, x, sizeof(a))
#define onlyunique(v) v.erase(unique(all(v)), v.end()); //only for sorted vector
#define inf 2e18
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS
#ifdef __APPLE__
#define dbg(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){cerr << name << " : " << arg1 << endl;}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');
	cerr.write(names, comma - names) << " : " << arg1 << "  ";
	__f(comma + 1, args...);}
#else
#define dbg(...)
#endif
template <typename X> ostream& operator << (ostream& x,const vector<X>& v){for(int i=0;i<v.size();++i) x<<v[i]<<" ";return x;} 
template <typename X> ostream& operator << (ostream& x,const set<X>& v){for(auto it:v) x<<it<<" ";return x;} 
template <typename X, typename Y> ostream& operator << (ostream& x, const pair<X,Y>& v) {x<<v.ff<<" "<<v.ss;return x;} 
typedef tree <int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
struct pair_hash {inline std::size_t operator()(const std::pair<int, int> & v) const {return v.first*31+v.second;}};
const int mod = 1e9 + 7;

int takemod(int a){a%=mod;if(a<0)a+=mod;return a;}

int fast_exp(int base, int expo) {
	int res=1;
	while(expo>0) {
		if(expo&1) res=(res*base)%mod;
		base=(base*base)%mod;
		expo>>=1;}
	return res;}

int modinv(int a){return takemod(fast_exp(takemod(a), mod-2));}




typedef int Flow;
typedef int Cost;

struct MinCostFlow {
	struct Edge {
		int t;
		Flow f;
		Cost c;
		Edge*next, *rev;
		Edge(int _t, Flow _f, Cost _c, Edge*_next) :
				t(_t), f(_f), c(_c), next(_next) {
		}
	};

	vector<Edge*> E;

	int addV() {
		E.push_back((Edge*) 0);
		return E.size() - 1;
	}

	Edge* makeEdge(int s, int t, Flow f, Cost c) {
		return E[s] = new Edge(t, f, c, E[s]);
	}

	void addEdge(int s, int t, Flow f, Cost c) {
		Edge*e1 = makeEdge(s, t, f, c), *e2 = makeEdge(t, s, 0, -c);
		e1->rev = e2, e2->rev = e1;
	}

	pair<Flow, Cost> minCostFlow(int vs, int vt, bool maxFlow) { //flow,cost
		int n = E.size();
		Flow flow = 0;
		Cost cost = 0;
//		const Cost MAX_COST = numeric_limits<Cost>::max();
//		const Flow MAX_FLOW = numeric_limits<Flow>::max();
		const Cost MAX_COST = inf;
		const Flow MAX_FLOW = inf;
		for (;;) {
			vector<Cost> dist(n, MAX_COST);
			vector<Flow> am(n, 0);
			vector<Edge*> prev(n);
			vector<bool> inQ(n, false);
			queue<int> que;

			dist[vs] = 0;
			am[vs] = MAX_FLOW;
			que.push(vs);
			inQ[vs] = true;

			while (!que.empty()) {
				int u = que.front();
				Cost c = dist[u];
				que.pop();
				inQ[u] = false;
				for (Edge*e = E[u]; e; e = e->next)
					if (e->f > 0) {
						Cost nc = c + e->c;
						if (nc < dist[e->t]) {
							dist[e->t] = nc;
							prev[e->t] = e;
							am[e->t] = min(am[u], e->f);
							if (!inQ[e->t]) {
								que.push(e->t);
								inQ[e->t] = true;
							}
						}
					}
			}

			if (maxFlow) {
				if (dist[vt] == MAX_COST)
				{
					// //FOR RETRACING FLOW
					// for(int i = 1; i <= nx; i++)
					// {
					// 	for(Edge*e = E[i]; e; e = e->next)
					// 	{
					// 		//e->rev->f will give flow between i and e->t
					// 	}
					// }
					break;
				}
			} else {
				if (dist[vt] >= 0)
					break;
			}

			Flow by = am[vt];
			int u = vt;
			flow += by;
			cost += by * dist[vt];
			while (u != vs) {
				Edge*e = prev[u];
				e->f -= by;
				e->rev->f += by;
				u = e->rev->t;
			}
		}

		return make_pair(flow, cost);
	}
};

void solve()
{
	MinCostFlow sys;
	int source = sys.addV();
	int sink = sys.addV();
	int n;
	cin >> n;
	int type[4];
	int red[n], blue[n];
	for(int i = 0; i < 4; i++){
		type[i] = sys.addV();
	}
	for(int i = 0; i < n; i++)
	{
		red[i] = sys.addV();
		int x, y, c;
		cin >> x >> y >> c;
		sys.addEdge(source, red[i], c, 0);
		sys.addEdge(red[i], type[0], inf, -(x + y));
		sys.addEdge(red[i], type[1], inf, -(-x + y));
		sys.addEdge(red[i], type[2], inf, -(x - y));
		sys.addEdge(red[i], type[3], inf, -(-x - y));
	}
	for(int i = 0; i < n; i++)
	{
		blue[i] = sys.addV();
		int x, y, c;
		cin >> x >> y >> c;
		sys.addEdge(blue[i], sink, c, 0);
		sys.addEdge(type[0], blue[i], inf, -(-x - y));
		sys.addEdge(type[1], blue[i], inf, -(x - y));
		sys.addEdge(type[2], blue[i], inf, -(-x + y));
		sys.addEdge(type[3], blue[i], inf, -(x + y));
	}
	pii ret = sys.minCostFlow(source, sink, true);
	cout << -ret.ss;
}

signed main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	#ifdef __APPLE__
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	freopen("error.txt", "w", stderr);
	#endif
	clock_t t1, t2;
	t1 = clock();

	int t = 1;
	// cin >> t;
	while(t--)
	{
		solve();
	}
	t2 = clock(); cerr << "time taken: " << (t2-t1)/(dbl)CLOCKS_PER_SEC;
	return 0;
}

Measured memory_bytes: 1280