#include <fstream>
#include <vector>
#include <deque>
#define DIM 10010
#define INF 2000000000
using namespace std;
ifstream fin ("pixels.in");
ofstream fout ("pixels.out");
struct muchie{
int x,y,capacitate;
};
vector < pair<int,int> > L[DIM],edges[DIM];
vector <muchie> mch;
deque <int> c;
int A[DIM],B[DIM],dist[DIM];
int di[] = {-1,0,1,0};
int dj[] = {0, 1,0,-1};
int n,i,j,cod1,cod2,sursa,dest,total,poz,cost;
inline int get_cod (int i, int j){
return (i-1)*n+j;
}
inline int inmat (int i, int j){
if (i >= 1 && i <= n && j >= 1 && j <= n)
return 1;
return 0;
}
void bfs (int sursa, int dest){
for (int i=0;i<=n*n+1;i++){
edges[i].clear();
dist[i] = INF;
}
c.clear();
c.push_back(sursa);
dist[sursa] = 0;
while (!c.empty()){
int nod = c.front();
c.pop_front();
if (nod == dest)
break;
for (int i=0;i<L[nod].size();i++){
int vecin = L[nod][i].first;
int poz = L[nod][i].second;
if (!mch[poz].capacitate)
continue;
if (dist[vecin] == INF){
dist[vecin] = 1+dist[nod];
c.push_back(vecin);
}
if (dist[vecin] == 1+dist[nod])
edges[nod].push_back(make_pair(vecin,poz));
}}}
int dfs (int nod, int dest, int max_flow){
if (nod == dest)
return max_flow;
if (!max_flow)
return 0;
int flow = 0;
for (int i=0;i<edges[nod].size();i++){
int vecin = edges[nod][i].first;
int poz = edges[nod][i].second;
if (!mch[poz].capacitate)
continue;
int val = dfs (vecin,dest,min(mch[poz].capacitate,max_flow-flow));
mch[poz].capacitate -= val;
mch[poz^1].capacitate += val; /// muchia inversa
flow += val;
}
return flow;
}
int get_max_flow (int sursa, int dest){
int flux = 0, sol = 0;
do{
bfs (sursa,dest);
flux = dfs (sursa,dest,INF);
sol += flux;
} while (flux);
return sol;
}
int main (){
fin>>n;
/// pun muchie intre sursa si toate nodurile de capacitate a[i][j]
/// si intre toate nodurile si destinatie
sursa = 0, dest = n*n+1;
for (i=1;i<=n*n;i++){
fin>>A[i];
/// muchie de la sursa la i
mch.push_back({sursa,i,A[i]});
poz = mch.size()-1;
L[sursa].push_back(make_pair(i,poz)); /// mai retin si pozitia in vectorul de muchii
mch.push_back({i,sursa,0}); /// muchia inversa de capacitate 0
L[i].push_back(make_pair(sursa,poz+1));
total += A[i];
}
for (i=1;i<=n*n;i++){
fin>>B[i];
mch.push_back({i,dest,B[i]});
poz = mch.size()-1;
L[i].push_back(make_pair(dest,poz));
mch.push_back({dest,i,0});
L[dest].push_back(make_pair(i,poz+1));
total += B[i];
}
/// pun muchii intre noduri si capaciatate pijk
for (i=1;i<=n;i++)
for (j=1;j<=n;j++){
cod1 = get_cod (i,j);
for (int dir=0;dir<=3;dir++){
fin>>cost;
int iv = i+di[dir];
int jv = j+dj[dir];
if (inmat(iv,jv) && (dir == 1 || dir == 2)){
/// o sa il pe i,j doar de doua ca sa nu pun mai multe muchii de doua ori
cod2 = get_cod (iv,jv);
/// aici am muchie orientata
mch.push_back({cod1,cod2,cost});
poz = mch.size()-1;
L[cod1].push_back(make_pair(cod2,poz));
mch.push_back({cod2,cod1,cost});
L[cod2].push_back(make_pair(cod1,poz+1));
}}}
/// sum aij + sum bij - sum pij => trb sa minimizez pij => taietura
fout<<total - get_max_flow(sursa,dest);
return 0;
}