#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <iomanip>
#include <bitset>
#include <unordered_map>
#include <stack>
#include <memory.h>
#include <list>
#include <numeric>
#include <functional>
#include <complex>
#include <cassert>
#include <regex>
#include <random>
#include <sstream>

#define ll long long
#define ld long double
#define ull unsigned ll
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define pii pair<int,int> 
#define vi vector<int>
#define vll vector<ll>
#define vpii vector<pii>
#define vvi vector<vector<int>>
#define forn(it,from,to) for(int (it)=from; (it)<to; (it)++)
ll LINF = (ll)4e18;
ll mod = 998244353;
using namespace std;
const int INF = 1000 * 1000 * 1000;

struct rib {
	int b, u, c, f;
	size_t back;
};

void add_rib(vector < vector<rib> > & g, int a, int b, int u, int c) {
	rib r1 = { b, u, c, 0, g[b].size() };
	rib r2 = { a, 0, -c, 0, g[a].size() };
	g[a].push_back(r1);
	g[b].push_back(r2);
}
int n, m;

pair<vector < vector<rib> >, ll> get_flow(vi& v, int maxH, vvi& h, int cap) {
	int sz = n + m + 2;
	vector < vector<rib> > g(sz);
	forn(i, 0, n) {
		forn(j, 0, m) {
			add_rib(g, i + 1, n + 1 + j, 1e9, -h[i][j]);
		}
	}
	forn(i, 0, n) {
		add_rib(g, 0, i + 1, v[i], 0);
	}
	forn(j, 0, m) {
		add_rib(g, n + 1 + j, n + m + 1, cap, 0);
	}
	int flow = 0, cost = 0;
	int s = 0, t = n + m + 1;
	int k = maxH;
	while (flow < k) {
		vector<int> id(sz, 0);
		vector<int> d(sz, INF);
		vector<int> q(sz);
		vector<int> p(sz);
		vector<size_t> p_rib(sz);
		int qh = 0, qt = 0;
		q[qt++] = s;
		d[s] = 0;
		while (qh != qt) {
			int v = q[qh++];
			id[v] = 2;
			if (qh == sz)  qh = 0;
			for (size_t i = 0; i < g[v].size(); ++i) {
				rib& r = g[v][i];
				if (r.f < r.u && d[v] + r.c < d[r.b]) {
					d[r.b] = d[v] + r.c;
					if (id[r.b] == 0) {
						q[qt++] = r.b;
						if (qt == sz)  qt = 0;
					}
					else if (id[r.b] == 2) {
						if (--qh == -1)  qh = sz - 1;
						q[qh] = r.b;
					}
					id[r.b] = 1;
					p[r.b] = v;
					p_rib[r.b] = i;
				}
			}
		}
		if (d[t] == INF)  break;
		int addflow = k - flow;
		for (int v = t; v != s; v = p[v]) {
			int pv = p[v];  size_t pr = p_rib[v];
			addflow = min(addflow, g[pv][pr].u - g[pv][pr].f);
		}
		for (int v = t; v != s; v = p[v]) {
			int pv = p[v];  size_t pr = p_rib[v], r = g[pv][pr].back;
			g[pv][pr].f += addflow;
			g[v][r].f -= addflow;
			cost += g[pv][pr].c * addflow;
		}
		flow += addflow;
	}
	return { g, -cost };
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#else
	//freopen("sum.in", "r", stdin);
	//freopen("sum.out", "w", stdout);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cout.setf(ios::fixed);
	cin >> n >> m;
	vi v(n);
	forn(i, 0, n) cin >> v[i];
	vvi h(n, vi(m));
	int maxH = 0;
	forn(i, 0, n) {
		int mx = -1;
		forn(j, 0, m) {
			cin >> h[i][j];
			mx = max(mx, h[i][j]);
		}
		maxH += mx * v[i];
	}

	int l = 1, r = 1e6;

	while (l < r) {
		int mid = (l + r) >> 1;
		pair<vector < vector<rib> >, ll> res = get_flow(v, maxH, h, mid);
		int cost = res.second;
		if (cost != maxH) l = mid + 1;
		else r = mid;
	}

	pair<vector < vector<rib> >, ll> res = get_flow(v, maxH, h, l);
	vector < vector<rib> > g = res.first;
	vi w(m);
	forn(j, n + 1, n + m + 1) {
		for (auto& to : g[j]) {
			if (to.b == n + m + 1) {
				w[j - (n + 1)] = to.f;
				break;
			}
		}
	}
	vvi vals(n, vi(m));

	forn(i, 1, n + 1) {
		for (auto& to : g[i]) {
			if (to.b != 0) {
				vals[i - 1][to.b - (n + 1)] = to.f;
			}
		}
	}

	cout << maxH << '\n';
	forn(i, 0, m) cout << w[i] << ' ';
	cout << '\n';
	forn(i, 0, n) {
		forn(j, 0, m) {
			cout << vals[i][j] << ' ';
		}
		cout << '\n';
	}
	return 0;
}