# include <bits/stdc++.h>
 
/*
// ordered_set 
# include <ext/pb_ds/assoc_container.hpp>
# include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
# define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 
*/
 
using namespace std;
 
typedef long long                                        ll;
typedef long double                                      ld;
typedef pair <int, int>                                  pii;
typedef pair <pii, int>                                  ppi;
typedef pair <int, pii>                                  pip;
typedef pair <pii, pii>                                  ppp;
typedef pair <ll, ll>                                    pll;
 
# define A                                               first
# define B                                               second
# define endl                                            '\n'
# define sep                                             ' '
# define all(x)                                          x.begin(), x.end()
# define kill(x)                                         return cout << x << endl, 0
# define SZ(x)                                           int(x.size())
# define Sort(x)                                         sort(all(x))
# define InTheNameOfGod                                  ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);
 
ll power(ll a, ll b, ll md) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2, md) % md : power(a * a % md, b / 2, md) % md));}
 
const int xn = 5e3 + 10;
const int xm = 2e2 + 10;
const int SQ = 320;
const int sq = 320 + 10;
const int inf = 1e9 + 10;
const ll INF = 1e18 + 10;
const int MOD = 1e9 + 7;
const int TM = 3;
const int BASE = 257;

int n, m, a[xn], b[xn][xm], res[xm];
pii nxt[xn][xm], last;
ll ans, part[xn], seg[xn << 2], lazy[xn << 2];
stack <int> st;
vector <int> vec[xn][xm];

void build(int id, int l, int r){
	if (r - l == 1){
		seg[id] = - part[l];
		return;
	}
	int mid = l + r >> 1;
	build(id << 1, l, mid);
	build(id << 1 | 1, mid, r);
	seg[id] = max(seg[id << 1], seg[id << 1 | 1]);
}
void shift(int id, int l, int r){
	if (!lazy[id]) return;
	seg[id] += lazy[id];
	if (r - l > 1){
		lazy[id << 1] += lazy[id];
		lazy[id << 1 | 1] += lazy[id];
	}
	lazy[id] = 0;
}
void update(int id, int l, int r, int ql, int qr, ll val){
	shift(id, l, r);
	if (qr <= l || r <= ql) return;
	if (ql <= l && r <= qr){
		lazy[id] += val;
		shift(id, l, r);
		return;
	}
	int mid = l + r >> 1;
	update(id << 1, l, mid, ql, qr, val);
	update(id << 1 | 1, mid, r, ql, qr, val);
	seg[id] = max(seg[id << 1], seg[id << 1 | 1]);
}

int main(){
    InTheNameOfGod;
    
    cin >> n >> m;
    for (int i = 2; i <= n; ++ i){
    	cin >> a[i];
    	part[i] = part[i - 1] + a[i];
	}
    for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= m; ++ j)
			cin >> b[i][j];
    for (int j = 1; j <= m; ++ j){
    	while (st.size()) st.pop();
    	for (int i = 1; i <= n; ++ i){
    		while (st.size() && b[st.top()][j] <= b[i][j]) st.pop();
    		if (st.size()) nxt[i][j].A = st.top();
    		st.push(i);
		}
		while (st.size()) st.pop();
		for (int i = n; i >= 1; -- i){
			while (st.size() && b[st.top()][j] <= b[i][j]) st.pop();
			if (st.size()) nxt[i][j].B = st.top();
			else nxt[i][j].B = n + 1;
			st.push(i);
		}
	}
	for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= m; ++ j)
			vec[nxt[i][j].A][j].push_back(i);
	build(1, 1, n + 1);
	for (int i = 1; i <= n; ++ i){
		for (int j = 1; j <= m; ++ j){
			res[j] = max(res[j], b[i][j]);
			update(1, 1, n + 1, i, i + 1, res[j]);
		}
	}
	ans = max(ans, seg[1]);
	for (int L = 2; L <= n; ++ L){
		for (int j = 1; j <= m; ++ j){
			last = {L - 1, b[L - 1][j]};
			for (int i : vec[L - 1][j]){
				update(1, 1, n + 1, last.A, i, last.B - b[L - 1][j]);
				last = {i, b[i][j]};
			}
			update(1, 1, n + 1, last.A, nxt[L - 1][j].B, last.B - b[L - 1][j]);
		}
		update(1, 1, n + 1, L, n + 1, a[L]);
		ans = max(ans, seg[1]);
	}
	cout << ans << endl;
    
    return 0;
}


Measured memory_bytes: 57104