Problem:
Score : 1200 points

Problem Statement

Snuke is playing with red and blue balls, placing them on a two-dimensional plane.

First, he performed N operations to place red balls. In the i-th of these operations, he placed RC_i red balls at coordinates (RX_i,RY_i).
Then, he performed another N operations to place blue balls. In the i-th of these operations, he placed BC_i blue balls at coordinates (BX_i,BY_i).
The total number of red balls placed and the total number of blue balls placed are equal, that is, \sum_{i=1}^{N} RC_i = \sum_{i=1}^{N} BC_i. Let this value be S.

Snuke will now form S pairs of red and blue balls so that every ball belongs to exactly one pair.
Let us define the score of a pair of a red ball at coordinates (rx, ry) and a blue ball at coordinates (bx, by) as |rx-bx| + |ry-by|.

Snuke wants to maximize the sum of the scores of the pairs.
Help him by finding the maximum possible sum of the scores of the pairs.

Constraints

1 \leq N \leq 1000

0 \leq RX_i,RY_i,BX_i,BY_i \leq 10^9

1 \leq RC_i,BC_i \leq 10

\sum_{i=1}^{N} RC_i = \sum_{i=1}^{N} BC_i

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
RX_1 RY_1 RC_1
RX_2 RY_2 RC_2
\vdots
RX_N RY_N RC_N
BX_1 BY_1 BC_1
BX_2 BY_2 BC_2
\vdots
BX_N BY_N BC_N

Output

Print the maximum possible sum of the scores of the pairs.

Sample Input 1

2
0 0 1
3 2 1
2 2 1
5 0 1

Sample Output 1

8

If we pair the red ball at coordinates (0,0) and the blue ball at coordinates (2,2), the score of this pair is |0-2| + |0-2|=4.
Then, if we pair the red ball at coordinates (3,2) and the blue ball at coordinates (5,0), the score of this pair is |3-5| + |2-0|=4.
Making these two pairs results in the total score of 8, which is the maximum result.

Sample Input 2

3
0 0 1
2 2 1
0 0 2
1 1 1
1 1 1
3 3 2

Sample Output 2

16

Snuke may have performed multiple operations at the same coordinates.

Sample Input 3

10
582463373 690528069 8
621230322 318051944 4
356524296 974059503 6
372751381 111542460 9
392867214 581476334 6
606955458 513028121 5
882201596 791660614 9
250465517 91918758 3
618624774 406956634 6
426294747 736401096 5
974896051 888765942 5
726682138 336960821 3
715144179 82444709 6
599055841 501257806 6
390484433 962747856 4
912334580 219343832 8
570458984 648862300 6
638017635 572157978 10
435958984 585073520 7
445612658 234265014 6

Sample Output 3

45152033546

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#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;
}