// Original C++ solution (slower):
#include <bits/stdc++.h>

//#define fastIO cin.tie(0);ios_base::sync_with_stdio(false)

#define N 10010

#define ll long long

#define INF 1000000000000000000

//min-cost flow problem

using namespace std;



struct edge {

  ll from, to, cap, flow, cost;

};



ll n, d[2 * N + 5], pre[2 * N + 5], Maxflow = 0, COST = 0;

bool inqueue[2 * N + 5];

vector<edge> Edge;     // store edges

vector<ll> G[2 * N + 10];



inline void addEdge( ll from, ll to, ll cap, ll cost )

{

    Edge.push_back( edge{from, to, cap, 0, cost} );

    Edge.push_back( edge{to, from, 0, 0, -cost} );



    G[from].push_back( Edge.size() - 2 );

    G[to].push_back( Edge.size() - 1 );

}



inline bool bfs( ll s, ll t )

{

    for ( int i = 0; i < 2 * N + 5; ++i )

        d[i] = INF;

    memset( inqueue, 0, sizeof( inqueue ) );



    queue<ll> q;

    q.push( s );



    d[s] = 0, inqueue[s] = true;



    ll now;

    while ( q.empty() == false ) {

        now = q.front();

        q.pop();

        inqueue[now] = false;

        for ( ll i = 0; i < G[now].size(); ++i ) {

            edge& tmp = Edge[G[now][i]];

            if ( tmp.cap > tmp.flow && d[now] + tmp.cost < d[tmp.to] ) {

                d[tmp.to] = d[now] + tmp.cost;

                pre[tmp.to] = G[now][i];



                if ( inqueue[tmp.to] == false && tmp.to != t ) {

                    inqueue[tmp.to] = true;

                    q.push( tmp.to );

                }

            }

        }

    }



    return d[t] != INF;

    /*

    if(d[t]==-INF)

        return false;

    else

        return true;

    */

}



inline void calc( ll s, ll t )

{

    ll minflow = INF;

    ll tmpu = t;

    while ( s != tmpu ) { //find minflow

        minflow = min( minflow, Edge[pre[tmpu]].cap - Edge[pre[tmpu]].flow );

        tmpu = Edge[pre[tmpu]].from;

    }



    Maxflow += minflow;

    COST += minflow * d[t];



    while ( s != t ) {

        Edge[pre[t]].flow += minflow;

        Edge[pre[t] ^ 1].flow -= minflow;

        t = Edge[pre[t]].from;

    }

}



inline void init()

{

    cin >> n;



    ll a, b, c;

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

        cin >> a >> b >> c;

        addEdge( 0, i, c, 0 );

        addEdge( i, 2 * n + 1, c, -a - b );

        addEdge( i, 2 * n + 2, c, a - b );

        addEdge( i, 2 * n + 3, c, -a + b );

        addEdge( i, 2 * n + 4, c, a + b );

    }

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

        cin >> a >> b >> c;

        addEdge( i + n, 2 * n + 5, c, 0 );

        addEdge( 2 * n + 1, i + n, c, a + b );

        addEdge( 2 * n + 2, i + n, c, -a + b );

        addEdge( 2 * n + 3, i + n, c, a - b );

        addEdge( 2 * n + 4, i + n, c, -a - b );

    }

}



inline void solve()

{

    ll s = 0, t = 2 * n + 5;



    while ( bfs( s, t ) == true ) {

        calc( s, t );  //update cost && Maxflow

    }

    cout << -COST << endl;

}



int main()

{

    init();

    solve();

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

const int MAXQ = 1e7 + 5;

const int MAXN = 1e3 + 5;

const int MAXP = 5e3 + 5;

const int INF = 1e9;

const long long INFLL = 1e18;

typedef long long ll;

typedef long double ld;

typedef unsigned long long ull;

template < typename T > void chkmax( T& x, T y ) { x = max( x, y ); }

template < typename T > void chkmin( T& x, T y ) { x = min( x, y ); }

template < typename T > void read( T& x )

{

    x = 0;

    int f = 1;

    char c = getchar();

    for ( ; !isdigit( c ); c = getchar() ) if ( c == '-' ) f = -f;

    for ( ; isdigit( c ); c = getchar() ) x = x * 10 + c - '0';

    x *= f;

}

template < typename T > void write( T x )

{

    if ( x < 0 ) x = -x, putchar( '-' );

    if ( x > 9 ) write( x / 10 );

    putchar( x % 10 + '0' );

}

template < typename T > void writeln( T x )

{

    write( x );

    puts( "" );

}

struct edge { int dest, flow, pos, cost; };

vector<edge> a[MAXP];

int s, t, tot, flow;

ll cost;

ll dist[MAXP];

int path[MAXP], home[MAXP];

void FlowPath()

{

    int p = t, ans = INF;

    while ( p != s ) {

        ans = min( ans, a[path[p]][home[p]].flow );

        p = path[p];

    }

    flow += ans;

    cost += ans * dist[t];

    p = t;

    while ( p != s ) {

        a[path[p]][home[p]].flow -= ans;

        a[p][a[path[p]][home[p]].pos].flow += ans;

        p = path[p];

    }

}

bool spfa()

{

    static int q[MAXQ];

    static bool inq[MAXP];

    static int l = 0, r = 0;

    for ( int i = 0; i <= r; i++ )

        dist[q[i]] = -INFLL;

    dist[t] = -INFLL;

    q[l = r = 0] = s, dist[s] = 0, inq[s] = true;

    while ( l <= r ) {

        int tmp = q[l];

        for ( unsigned i = 0; i < a[tmp].size(); i++ )

            if ( a[tmp][i].flow != 0 && dist[tmp] + a[tmp][i].cost > dist[a[tmp][i].dest] ) {

                dist[a[tmp][i].dest] = dist[tmp] + a[tmp][i].cost;

                path[a[tmp][i].dest] = tmp;

                home[a[tmp][i].dest] = i;

                if ( !inq[a[tmp][i].dest] && a[tmp][i].dest != t ) {

                    q[++r] = a[tmp][i].dest;

                    inq[q[r]] = true;

                }

            }

        l++, inq[tmp] = false;

    }

    return dist[t] != -INFLL;

}

void addedge( int x, int y, int z, int c )

{

    a[x].push_back( (edge) {y, z, a[y].size(), c} );

    a[y].push_back( (edge) {x, 0, a[x].size() - 1, -c} );

}

int n, mid[4], cntx[MAXN], cnty[MAXN];

pair<int, int> posx[MAXN], posy[MAXN];

int main()

{

    read( n ), tot = 2 * n;

    s = ++tot, t = ++tot;

    for ( int i = 0; i <= 3; i++ )

        mid[i] = ++tot;

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

        read( posx[i].first ), read( posx[i].second ), read( cntx[i] );

        addedge( s, i, cntx[i], 0 );

        addedge( i, mid[0], INF, -posx[i].first - posx[i].second );

        addedge( i, mid[1], INF, posx[i].first - posx[i].second );

        addedge( i, mid[2], INF, -posx[i].first + posx[i].second );

        addedge( i, mid[3], INF, posx[i].first + posx[i].second );

    }

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

        read( posy[i].first ), read( posy[i].second ), read( cnty[i] );

        addedge( n + i, t, cnty[i], 0 );

        addedge( mid[0], n + i, INF, posy[i].first + posy[i].second );

        addedge( mid[1], n + i, INF, -posy[i].first + posy[i].second );

        addedge( mid[2], n + i, INF, posy[i].first - posy[i].second );

        addedge( mid[3], n + i, INF, -posy[i].first - posy[i].second );

    }

    for ( int i = 1; i <= tot; i++ )

        dist[i] = -INFLL;

    while ( spfa() ) FlowPath();

    writeln( cost );

    return 0;

}


// Fastest known solution for this problem: