#include #include using namespace std; using ll = long long; #define REP(i, n) for(ll i=0; i<(n);i++) class MaxFlow { public: struct edge { ll to, cap, rev; }; MaxFlow(ll n) { point = n; edges.resize(n); used.resize(n); } void addEdge(ll from, ll to, ll cap, ll rev = 0) { edge eF = { to,cap - rev,edges[to].size() }; edges[from].push_back(eF); edge eT = { from,rev,edges[from].size() - 1 }; edges[to].push_back(eT); } ll dfs(ll v, ll t, ll f) { if (v == t)return f; used[v] = true; for (ll i = 0; i < edges[v].size(); i++) { edge& e = edges[v][i]; if (!used[e.to] && e.cap > 0) { ll d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; edges[e.to][e.rev].cap += d; return d; } } } return 0; } ll getMaxFlow(ll s, ll g) { ll flow = 0; for (;;) { used.assign(point, 0); ll f = dfs(s, g, 3e18); if (f == 0)break; flow += f; } return flow; } ll point; vector> edges; vector used; }; int main() { ll n, s, t; cin >> n >> s >> t; vector a(s), b(t); vector c(n, vector(n)); REP(i, s) cin >> a[i]; REP(i, t) cin >> b[i]; REP(i, n) REP(j, n) cin >> c[i][j]; MaxFlow mf(n + 2); ll start = n; ll goal = n + 1; ll in = 1e16; REP(i, s) mf.addEdge(start, a[i] - 1, in); REP(i, t) mf.addEdge(b[i] - 1, goal, in); REP(i, n) { REP(j, n) { if (i == j) continue; mf.addEdge(i, j, c[i][j]); } } cout << mf.getMaxFlow(start, goal); return 0; }