#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;
int A[DIM],B[DIM],dist[DIM],c[2*DIM];
int di[] = {-1,0,1,0};
int dj[] = {0, 1,0,-1};
int n,i,j,cod1,cod2,sursa,dest,total,poz,cost,m;
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=sursa;i<=dest;++i){
edges[i].clear();
dist[i] = INF;
}
int p = 1, u = 1;
c[p] = sursa;
dist[sursa] = 0;
while (p <= u){
int nod = c[p];
p++;
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[++u] = 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 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, m = n*n;
for (i=1;i<=m;++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<=m;++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 ((dir == 1 || dir == 2) && inmat(iv,jv)){
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
int flux = 0, sol = 0;
do{
bfs (sursa,dest);
flux = dfs (sursa,dest,INF);
sol += flux;
} while (flux);
fout<<total - sol;
return 0;
}