#include using namespace std; using int64 = long long; const int mod = 1e9 + 7; // const int mod = 998244353; const int64 infll = (1LL << 62) - 1; const int inf = (1 << 30) - 1; struct IoSetup { IoSetup() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); cerr << fixed << setprecision(15); } } iosetup; template< typename T1, typename T2 > ostream &operator<<(ostream &os, const pair< T1, T2 > &p) { os << p.first << " " << p.second; return os; } template< typename T1, typename T2 > istream &operator>>(istream &is, pair< T1, T2 > &p) { is >> p.first >> p.second; return is; } template< typename T > ostream &operator<<(ostream &os, const vector< T > &v) { for(int i = 0; i < (int) v.size(); i++) { os << v[i] << (i + 1 != v.size() ? " " : ""); } return os; } template< typename T > istream &operator>>(istream &is, vector< T > &v) { for(T &in : v) is >> in; return is; } template< typename T1, typename T2 > inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); } template< typename T1, typename T2 > inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); } template< typename T = int64 > vector< T > make_v(size_t a) { return vector< T >(a); } template< typename T, typename... Ts > auto make_v(size_t a, Ts... ts) { return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...)); } template< typename T, typename V > typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) { t = v; } template< typename T, typename V > typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) { for(auto &e : t) fill_v(e, v); } template< typename F > struct FixPoint : F { FixPoint(F &&f) : F(forward< F >(f)) {} template< typename... Args > decltype(auto) operator()(Args &&... args) const { return F::operator()(*this, forward< Args >(args)...); } }; template< typename F > inline decltype(auto) MFP(F &&f) { return FixPoint< F >{forward< F >(f)}; } #define rep(i, n) for(int i = 0; i < (n); ++i) #define REP(i, b, n) for(int i = (b); i < (n); ++i) #define let(v, x) __typeof(x) v = (x) #define foreach(i, v) for(let(i, (v).begin());i!=(v).end();i++) struct DinicLC {//{{{ typedef int64 Cap; static const Cap INF = 1LL << 60; struct LCNode {//{{{ typedef LCNode *Ptr; Ptr ch[2], par, min_node; Cap val, min_val, lazy; int name; LCNode() : par(0), min_node(this), val(INF), min_val(INF), lazy(0) { ch[0] = ch[1] = 0; } inline void push() {//{{{ if(lazy == 0) return; val += lazy; min_val += lazy; rep(i, 2) if(ch[i]) ch[i]->lazy += lazy; lazy = 0; }//}}} inline void update() {//{{{ push(); if(ch[0]) { min_val = ch[0]->min_val + ch[0]->lazy; min_node = ch[0]->min_node; } if(!ch[0] || min_val > val) { min_val = val; min_node = this; } if(ch[1] && min_val > ch[1]->min_val + ch[1]->lazy) { min_val = ch[1]->min_val + ch[1]->lazy; min_node = ch[1]->min_node; } }//}}} inline void set_value(Cap v) { expose(); val = v; update(); } inline Cap get_value() { expose(); return val; } inline Ptr get_min_node_on_path() { expose(); return min_node; } inline void add_to_path(Cap c) { expose(); lazy += c; push(); } inline int state() {//{{{ if(par && par->ch[0] == this) return -1; if(par && par->ch[1] == this) return +1; return 0; }//}}} inline void rotate() {//{{{ Ptr p = par; p->push(); push(); bool lr = state() + 1; if(p->state()) p->par->ch[p->state() > 0] = this; par = p->par; p->ch[lr] = ch[!lr]; if(ch[!lr]) ch[!lr]->par = p; (p->par = this)->ch[!lr] = p; p->update(); update(); }//}}} inline void splay() {//{{{ while(state()) { int s = state() * par->state(); if(s) (s == 1 ? par : this)->rotate(); rotate(); } push(); }//}}} inline void expose() {//{{{ if(!par) return; for(Ptr p = this; p; p = p->par) p->splay(); for(Ptr p = this; p->par; p = p->par) p->par->ch[1] = p; splay(); }//}}} inline void cut() {//{{{ expose(); if(!ch[0]) return; ch[0]->par = 0; ch[0]->push(); ch[0] = 0; update(); }//}}} inline void link_to(Ptr p) {//{{{ expose(); par = p; }//}}} inline Ptr find_root() {//{{{ expose(); Ptr p = this; while(p->ch[0]) p = p->ch[0]; p->expose(); return p; }//}}} };//}}} struct E {//{{{ int dst; Cap cap; int rev; E(int dst, Cap cap, int rev) : dst(dst), cap(cap), rev(rev) {} };//}}} int n; vector< vector< E > > g; DinicLC(int n) : n(n), g(n) {} inline void add_edge(int src, int dst, Cap cap) {//{{{ if(src == dst) return; g[src].push_back(E(dst, cap, g[dst].size())); g[dst].push_back(E(src, 0, g[src].size() - 1)); }//}}} inline void add_undirected_edge(int src, int dst, Cap cap) {//{{{ if(src == dst) return; g[src].push_back(E(dst, cap, g[dst].size())); g[dst].push_back(E(src, cap, g[src].size() - 1)); }//}}} vector< int > level, active; vector< LCNode > lc; inline void unuse_edge(E &e) {//{{{ E &ee = g[e.dst][e.rev]; int u = ee.dst; Cap use = ee.cap - lc[u].get_value(); e.cap += use; ee.cap -= use; active[u] = false; lc[u].cut(); lc[u].set_value(INF); }//}}} inline void init() {//{{{ lc.resize(n); active.assign(n, false); rep(u, n) lc[u].name = u; }//}}} Cap dfs(const int &s, const int &t) {//{{{ vector< int > iter(n); rep(u, n) iter[u] = (int) (g[u].size()) - 1; Cap res = 0; while(true) { const int &u = lc[t].find_root()->name; if(u == s) { Cap f = lc[t].get_min_node_on_path()->get_value(); res += f; lc[t].add_to_path(-f); while(true) { int v = lc[t].get_min_node_on_path()->name; Cap f = lc[v].get_value(); if(f > 0) break; unuse_edge(g[v][iter[v]]); } } else { for(int &i = iter[u]; i >= 0; --i) { E &e = g[u][i], &ee = g[e.dst][e.rev]; int v = e.dst; if(level[u] - 1 != level[v] || ee.cap <= 0) continue; active[u] = true; lc[u].set_value(ee.cap); lc[u].link_to(&lc[v]); break; } if(active[u]) continue; if(u == t) break; level[u] = -1; foreach(e, g[u]) if(active[e->dst] && iter[e->dst] == e->rev) unuse_edge(g[e->dst][e->rev]); } } rep(u, n) if(active[u]) unuse_edge(g[u][iter[u]]); return res; }//}}} Cap run(int s, int t) {//{{{ init(); vector< int > q(n); for(Cap flow = 0;;) { level.assign(n, -1); int ql = 0, qr = 0; level[q[qr++] = s] = 0; while(ql != qr && level[t] == -1) { int u = q[ql++]; foreach(e, g[u]) if(e->cap > 0 && level[e->dst] == -1) level[q[qr++] = e->dst] = level[u] + 1; } if(level[t] == -1) return flow; flow += dfs(s, t); } }//}}} };//}}} int main() { int H, W; cin >> H >> W; vector< vector< int64 > > G(H, vector< int64 >(W)); for(int i = 0; i < H; i++) { for(int j = 0; j < W; j++) cin >> G[i][j]; } vector< int64 > R(H), C(W); for(int i = 0; i < H; i++) cin >> R[i]; for(int i = 0; i < W; i++) cin >> C[i]; int64 sum = accumulate(begin(R), end(R), 0LL) + accumulate(begin(C), end(C), 0LL); DinicLC flow(H * W + H + W + 2); int S = H * W + H + W; int T = S + 1; for(int i = 0; i < H; i++) { for(int j = 0; j < W; j++) { flow.add_edge(S, i * W + j, G[i][j]); flow.add_edge(i * W + j, H * W + i, flow.INF); flow.add_edge(i * W + j, H * W + H + j, flow.INF); } } for(int i = 0; i < H; i++) { flow.add_edge(H * W + i, T, R[i]); } for(int i = 0; i < W; i++) { flow.add_edge(H * W + H + i, T, C[i]); } cout << sum - flow.run(S, T) << endl; }