#include #include #include

using namespace std;

struct edge { int t, c; edge *next, *rv; };

const int maxn = 255009; const int maxe = 2000009; const int maxa = 509; const int inf = 0x3f3f3f3f;

int n, st, te, tnid, rid[maxa], ans; int tvis, vis[maxn], d[maxn]; edge ebuf_arr[maxe], *ebuf(ebuf_arr), *head[maxn];

inline edge* allocEdge(int u, int v, int c) { ebuf-> t = v; ebuf-> c = c; ebuf-> next = head[u]; return head[u] = ebuf ++; } inline void addEdge(int u, int v, int c) { edge* a(allocEdge(u, v, c)); edge* b(allocEdge(v, u, 0)); a-> rv = b; b-> rv = a; }

bool bfsBuild() { static int q[maxn]; int hd(0), tl(1); q[0] = st; vis[st] = ++ tvis; d[st] = 1; while (hd < tl && vis[te] < tvis) { int p(q[hd ++]); for (edge* e = head[p]; e; e = e-> next) if (e-> c && vis[e-> t] < tvis) { d[e-> t] = d[p] + 1; vis[e-> t] = tvis; q[tl ++] = e-> t; } } return vis[te] == tvis; } int dfsFind(int p, int c) { if (p == te) return c; int s(0); edge* e; for (e = head[p]; e && c; e = e-> next) if (e-> c && d[e-> t] == d[p] + 1 && vis[e-> t] == tvis) { int x(dfsFind(e-> t, min(c, e-> c))); c -= x, s += x; e-> c -= x, e-> rv-> c += x; } if (!e) d[p] = 0; return s; }

int main() { #ifndef ONLINE_JUDGE freopen(".in", “r”, stdin); #endif

tnid = 0;
st = ++ tnid, te = ++ tnid;
scanf("%d", &n);
for (int i = 1; i <= n; ++ i)
	rid[i] = ++ tnid;
ans = 0;
for (int i = 1; i <= n; ++ i)
	for (int j = 1; j <= n; ++ j) {
		int x;
		scanf("%d", &x);
		ans += x;
		if (i != j) {
			++ tnid;
			addEdge(rid[i], tnid, inf);
			addEdge(rid[j], tnid, inf);
			addEdge(tnid, te, x);
		}
		else
			addEdge(rid[i], te, x);
	}
for (int i = 1; i <= n; ++ i) {
	int c;
	scanf("%d", &c);
	addEdge(st, rid[i], c);
}
memset(vis, 0, sizeof(vis));
tvis = 0;
while (bfsBuild())
	ans -= dfsFind(st, inf);
printf("%d\n", ans);

}