#include<bits/stdc++.h> usingnamespace std; using i64 = longlong; #define int i64 constint K = 260, N = K * K, M = N << 4; constint inf = 1E9, INF = 1E15; int n, m; structflow { int head[N], nex[M << 1], tot = 1, cur[N], dep[N]; int SN, S, T; structE {int to, nxt, flow;} edge[M << 1]; voidad(int x, int y, int w){ edge[++tot] = (E) {x, y, w}; nex[tot] = head[x]; head[x] = tot; } voidadd(int x, int y, int w){ ad(x, y, w); ad(y, x, 0); } boolbfs(){ fill(dep + 1, dep + 1 + SN, 0); queue <int> q; q.emplace(S); dep[S] = 1; while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; i; i = nex[i]) { int v = edge[i].nxt, w = edge[i].flow; if (w > 0 && !dep[v]) { dep[v] = dep[u] + 1; q.emplace(v); } } } return dep[T]; } intdfs(int u, int flow){ if (u == T || !flow) return flow; int res = 0; for (int i = cur[u]; i && res < flow; i = nex[i]) { cur[u] = i; int v = edge[i].nxt, w = edge[i].flow; if (w > 0 && dep[v] == dep[u] + 1) { int k = dfs(v, min(flow - res, w)); if (!k) dep[v] = 0; else { edge[i].flow -= k; edge[i ^ 1].flow += k; res += k; } } } return res; } intdinic(){ int ans = 0; while (bfs()) { copy(head + 1, head + 1 + SN, cur + 1); ans += dfs(S, INF); } return ans; } } dc; int a[K][K], c[K][K], b[K]; intid(int i, int j){return (i - 1) * n + j;} intin(int i, int j){returnid(i, j);} intout(int i, int j){returnin(i, j) + m;} signedmain(void){ ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n; m = n * n; dc.S = m * 2 + 1, dc.T = dc.SN = dc.S + 1; for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) cin >> a[i][j]; for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) cin >> c[i][j]; for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) dc.add(in(i, j), out(i, j), inf - c[i][j]); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) b[a[i][j]] = j; dc.add(dc.S, in(i, b[1]), INF); for (int j = 1; j < n; ++j) dc.add(out(i, b[j]), in(i, b[j + 1]), INF); dc.add(out(i, b[n]), dc.T, INF); } for (int j = 1; j <= n; ++j) { for (int i = 1; i <= n; ++i) b[a[i][j]] = i; dc.add(dc.S, in(b[1], j), INF); for (int i = 1; i < n; ++i) dc.add(out(b[i], j), in(b[i + 1], j), INF); dc.add(out(b[n], j), dc.T, INF); } int ans = dc.dinic(); cout << inf * n - ans << '\n'; return0; }