#include <bits/stdc++.h>
using namespace std;
#define MAXN 10010
#define MAXM 100010
#define INF 0x3f3f3f3f
struct Edge {
int to, nxt, cap, flow, cost;
Edge() {}
Edge(int to, int nxt, int cap, int flow, int cost) : to(to), nxt(nxt), cap(cap), flow(flow), cost(cost) {}
} edge[MAXM];
int head[MAXN], tot;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int N;
void Init(int n) {
N = n;
tot = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int cap, int cost) {
edge[tot] = Edge(v, head[u], cap, 0, cost);
head[u] = tot++;
edge[tot] = Edge(u, head[v], 0, 0, -cost);
head[v] = tot++;
}
bool SPFA(int s, int t) {
queue<int> q;
for (int i = 0; i < N; ++i) {
dis[i] = INF;
vis[i] = false;
pre[i] = -1;
}
vis[s] = true;
dis[s] = 0;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for (int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].to;
if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost) {
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if (!vis[v]) {
vis[v] = true;
q.push(v);
}
}
}
}
return pre[t] != -1;
}
int minCostMaxflow(int s, int t, int &cost) {
int flow = 0;
cost = 0;
while (SPFA(s, t)) {
int Min = INF;
for (int i = pre[t]; ~i; i = pre[edge[i ^ 1].to]) {
Min = min(Min, edge[i].cap - edge[i].flow);
}
for (int i = pre[t]; ~i; i = pre[edge[i ^ 1].to]) {
edge[i].flow += Min;
edge[i ^ 1].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
}
int n, m;
int arr[110], brr[110], crr[110][110];
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", arr + i);
}
for (int i = 1; i <= m; ++i) {
scanf("%d", brr + i);
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
scanf("%d", &crr[i][j]);
}
}
int S = 0, T = n + m + 1;
int cost, flow;
Init(T + 1);
for (int i = 1; i <= n; ++i) {
addedge(S, i, arr[i], 0);
}
for (int i = 1; i <= m; ++i) {
addedge(i + n, T, brr[i], 0);
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
addedge(i, j + n, INF, crr[i][j]);
}
}
flow = minCostMaxflow(S, T, cost);
printf("%d\n", cost);
Init(T + 1);
for (int i = 1; i <= n; ++i) {
addedge(S, i, arr[i], 0);
}
for (int i = 1; i <= m; ++i) {
addedge(i + n, T, brr[i], 0);
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
addedge(i, j + n, INF, -crr[i][j]);
}
}
flow = minCostMaxflow(S, T, cost);
printf("%d\n", -cost);
return 0;
}