#include <bits/stdc++.h>

using namespace std;

const int max_n = 2022, inf = 1000111222;

namespace min_cost_max_flow {

const int max_v = 5 * max_n;
const long long infLL = 1LL * inf * inf;

struct edge {
    int v, residual_capacity, cost;

    edge(int v, int residual_capacity, int cost): v(v), residual_capacity(residual_capacity), cost(cost) {
    }
};

vector<edge> edges;
vector<int> g[max_v];

void add_edge(int u, int v, int f, int c) {
    g[u].push_back(edges.size());
    edges.push_back({v, f, c});
    g[v].push_back(edges.size());
    edges.push_back({u, 0, -c});
}

int parent[max_v];
long long phi[max_v], dist[max_v];

bool dijkstra(int s, int t) {
    for (int i = 0; i <= t; ++i) {
        dist[i] = infLL;
    }
    dist[s] = 0;
    priority_queue<pair<int, int>> q;
    q.push({0, s});
    while (!q.empty()) {
        pair<int, int> p = q.top();
        q.pop();
        const int v = p.second;
        if (-p.first != dist[v]) {
            continue;
        }
        //cout << v << ": " << dist[v] << ", phi = " << phi[v] << endl;
        for (int id : g[v]) {
            if (edges[id].residual_capacity == 0) {
                continue;
            }
            const int to = edges[id].v;
            if (dist[v] + phi[v] - phi[to] + edges[id].cost < dist[to]) {
                dist[to] = dist[v] + phi[v] - phi[to] + edges[id].cost;
                q.push({-dist[to], to});
                parent[to] = id;
            }
        }
    }
    for (int i = 0; i <= t; ++i) {
        dist[i] = min(infLL, dist[i] + phi[i]);
        phi[i] = dist[i];
    }
    return dist[t] != infLL;
}

char used[max_v];
int start[max_v];

int dfs(int v, int t, int f) {
    if (v == t) {
        return f;
    }
    used[v] = 1;
    for (int &i = start[v]; i < g[v].size(); ++i) {
        const int id = g[v][i];
        if (edges[id].residual_capacity && dist[v] + edges[id].cost == dist[edges[id].v] && !used[edges[id].v]) {
            int res = dfs(edges[id].v, t, min(f, edges[id].residual_capacity));
            if (res) {
                edges[id].residual_capacity -= res;
                edges[id ^ 1].residual_capacity += res;
                used[v] = 0;
                return res;
            }
        }
    }
    used[v] = 0;
    return 0;
}

long long min_cost_max_flow(int s, int t) {
    long long res = 0;
    int it = 0;
    while (dijkstra(s, t)) {
        memset(start, 0, sizeof(int) * (t + 1));
        while (int x = dfs(s, t, inf)) {
            res += 1LL * x * dist[t];
        }
    }
    return res;
}

}

struct ball {
    int x, y, cnt, id;

    ball() {
    }

    ball(int x, int y, int id): x(x), y(y), id(id) {
    }

    void read() {
        scanf("%d%d%d", &x, &y, &cnt);
    }

    bool operator < (const ball &b) const {
        return x < b.x || (x == b.x && y < b.y);
    }
};

const int zx[4] = {-1, -1, 1, 1};
const int zy[4] = {-1, 1, -1, 1};

int n;
ball b[max_n];

int dist(const ball &a, const ball &b) {
    return abs(a.x - b.x) + abs(a.y - b.y);
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d", &n);
    for (int i = 0; i < 2 * n; ++i) {
        b[i].read();
        b[i].id = i;
    }
    int s = 10 * n + 4;
    int t = s + 1;
    for (int i = 0; i < n; ++i) {
        min_cost_max_flow::add_edge(s, i, b[i].cnt, 0);
        min_cost_max_flow::add_edge(9 * n + i, t, b[n + i].cnt, 0);
        for (int j = 0; j < 4; ++j) {
            min_cost_max_flow::add_edge(i, n + i * 4 + j, inf, zx[j] * b[i].x + zy[j] * b[i].y);
            min_cost_max_flow::add_edge(n + i * 4 + j, 10 * n + j, inf, 0);
            min_cost_max_flow::add_edge(10 * n + j, 5 * n + i * 4 + j, inf, 0);
            min_cost_max_flow::add_edge(5 * n + i * 4 + j, 9 * n + i, inf, -zx[j] * b[n + i].x + -zy[j] * b[n + i].y);
        }
    }
    printf("%lld\n", -min_cost_max_flow::min_cost_max_flow(s, t));
    return 0;
}


Measured memory_bytes: 1848