#include <bits/stdc++.h>
using namespace std;
#define int long long
const int dir[4][2] = {1, -1, -1, 1, -1, -1, 1, 1};
const int kN = 10010, kInf = 1e18, kNode = 1e5;
const int inf = kInf;
int node_cnt, n;
int id1[4], id2[4];
int x[kN], y[kN], w[kN];
 bool inq[kN];

namespace mcmf {
  typedef int FlowType, CostType;
  const int maxn = 1e5, maxm = 2e5;
  const FlowType inff = 1e18;
  const CostType infc = 1e18;

  int n, m, s, t;
  
  vector<int> g[maxn];

  struct Edge {
    int v;
    FlowType cap, flow;
    CostType cost;
  } edge[maxm << 1];

  CostType dist[maxn], h[maxn];
  void AddEdge(int u, int v, FlowType cap, CostType cost) {
	  g[u].push_back(m);
	  edge[m++] = (Edge){v, cap, 0, cost};
	  g[v].push_back(m);
	  edge[m++] = (Edge){u, 0, 0, -cost};
  }

  struct Node {
    int u;
    CostType d;
    bool operator < (const Node &rhs) const {
      return d > rhs.d;
    }
  };
 
  bool Dijkstra(void) {
    priority_queue<Node> q;
    q.push((Node){s, 0});
    fill(dist, dist + n, infc);
    dist[s] = 0;
    inq[s]=true;
    while (!q.empty()) {
      int u = q.top().u;
      inq[u]=false;
      CostType d = q.top().d;
      q.pop();
      //if (d != dist[u]) continue;
      for (int i = 0; i < g[u].size(); ++i) {
        Edge &e = edge[g[u][i]];
        if (e.flow < e.cap) {
          CostType t = dist[u] + h[u] - h[e.v] + e.cost;
          if (dist[e.v] > t) {
            dist[e.v] = t;
            if(inq[e.v]==false){
            q.push((Node){e.v, t});
              inq[e.v]=true;
            }
          }
        }
      }
      //inq[u]=false;
    }
    for (int i = 0; i < n; ++i) {
      h[i] = min(h[i] + dist[i], infc);
    }
    return h[t] != infc;
  }

  bool ins[maxn];
  int cur[maxn];

  FlowType Dfs(int u, FlowType f) {
    if (u == t) return f;
    ins[u] = true;
    FlowType sum = 0;
    for (int &i = cur[u]; i < g[u].size(); ++i) {
      Edge &e = edge[g[u][i]], &r = edge[g[u][i] ^ 1];
      if (e.flow < e.cap && e.cost + h[u] - h[e.v] == 0 && !ins[e.v]) {
        FlowType t = Dfs(e.v, min(f - sum, e.cap - e.flow));
        e.flow += t;
        r.flow -= t;
        sum += t;
        if (sum == f) break;
      }
    }
    ins[u] = false;
    return sum;
  }

  pair<FlowType, CostType> Solve(void) {
    pair<FlowType, CostType> ans(0, 0);
    fill(h, h + n, 0);
    fill(ins, ins + n, false);
    while (Dijkstra()) {
      fill(cur, cur + n, 0);
      FlowType f = Dfs(s, inff);
      ans.first += f;
      ans.second += f * h[t];
    }
    return ans;
  }
}

using mcmf::AddEdge;

signed main() {
	mcmf::s = ++mcmf::n;
	mcmf::t = ++mcmf::n;
	scanf("%lld", &n);
    fill(inq,inq+n,0);
	for (int i = 0; i < 4; ++i) {
		id1[i] = ++mcmf::n;
		id2[i] = ++mcmf::n;
	}
	for (int i = 1; i <= n * 2; ++i) {
		scanf("%lld%lld%lld", &x[i], &y[i], &w[i]);
		int p = ++mcmf::n;
		if (i <= n) AddEdge(1, p, w[i], 0);
		else AddEdge(p, 2, w[i], 0);
		for (int j = 0; j < 4; ++j) {
			int w = x[i] * dir[j][0] + y[i] * dir[j][1];
			if (i <= n) AddEdge(p, id1[j], inf, -w);
			else AddEdge(id2[j], p, inf, -w);
		}
	}
	for (int i = 0; i < 4; ++i)
		AddEdge(id1[i], id2[i ^ 1], inf, 0);
	++mcmf::n;
	printf("%lld", -mcmf::Solve().second);
}


Measured memory_bytes: 5632