#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<queue>
#include<stack>
#include<bitset>
#include<functional>
#include<map>
#include <iomanip>
#include <limits>
#include<unordered_set> 
#include<cmath>
using namespace std;
//long long p = 998244353;
long long p = 1000000007;
#define int long long
#define vel vector<long long>
#define vvel vector<vel>
#define rep(i,n) for(int i=0;i<n;i++)
#define sor(v) sort(v.begin(),v.end())
#define mmax(a,b) a=max(a,b)
#define mmin(a,b) a=min(a,b)
#define mkp make_pair
#define pin pair<int,int>
#define qin pair<int,pin>
#define V vector
#define Endl endl
#define veb vector<bool>
#define fcout cout << fixed << setprecision(15)
#define rev(s) reverse(s.begin(),s.end())
#define lower(h,val) lower_bound(h.begin(),h.end(),val)-h.begin()
#define upper(h,val) upper_bound(h.begin(),h.end(),val)-h.begin()
int max_kai = 150000;
vel kai(max_kai, 1);
vel inv_kai;
int rui(int a, int n) {
    if (n == 0) { return 1; }
    int x = rui(a, n / 2);
    x *= x; x %= p;
    if (n % 2 == 1) { x *= a; x %= p; }
    return x;
}
int inv(int a) { return rui(a, p - 2); }
void make_kai() {
    for (int i = 1; i < max_kai; i++) { kai[i] = kai[i - 1] * i; kai[i] %= p; }
    inv_kai = kai;
    rep(i, max_kai) { inv_kai[i] = inv(kai[i]); }
}
int nCr(int n, int r) {
    if (n < 0 || r<0 || r>n) { return 0; }
    int a = kai[n] * inv_kai[r]; a %= p;
    a *= inv_kai[n - r]; a %= p;
    return a;
}
vel pa;
int root(int x) {
    if (pa[x] == -1) { return x; }
    int ans = root(pa[x]); pa[x] = ans;
    return ans;
}
void marge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) { pa[x] = y; }
}
int gcd(int x, int y) {
    if (x < y) { return gcd(y, x); }
    if (y == 0) { return x; }
    return gcd(y, x % y);
}
vel ans;
vel ind;
#define pd pair<int,double>
#define ved vector<double>
void sol1(vel& sum, vvel& b, int i) {//O(nm)
    int n = ans.size();
    int m = b[0].size();
    vel mb(m,-1);//[i,i)
    for (int j = i; j < n; j++) {
        int qans = sum[i] - sum[j];
        rep(ind, m) {
            mmax(mb[ind], b[j][ind]);
            qans += mb[ind];
        }//mb=[i,j]
        if (qans > ans[i]) {
            ans[i] = qans;
            ind[i] = j;
        }
    }
}
void sol_ran(vel& sum, vvel& b, int st,int to) {//O(nm+(y-x)(to-st)m)
    int x = ind[st];
    int y = ind[to];
    int m = b[0].size();
    vel stb(m, -1);
    if (x > to) {
        for (int i = to; i < x; i++) {
            rep(j, m) { mmax(stb[j], b[i][j]); }
        }//stb=[to,x)
        for (int i = to - 1; i > st; i--) {
            rep(j, m) { mmax(stb[j], b[i][j]); }
            vel mb = stb;//mb=[i,x)
            for (int j =x; j <= y; j++) {
                int qans = sum[i] - sum[j];
                rep(ind, m) {
                    mmax(mb[ind], b[j][ind]);
                    qans += mb[ind];
                }//mb=[i,j]
                if (qans > ans[i]) { ans[i] = qans; }
            }
        }
    }
    else {
        for (int i = st + 1; i < to - 1; i++) {
            vel mb(m, -1);
            for (int j = i; j < y; j++) {
                int qans = sum[i] - sum[j];
                rep(ind, m) {
                    mmax(mb[ind], b[j][ind]);
                    qans += mb[ind];
                }//mb=[i,j]
                if (qans > ans[i]) {ans[i] = qans;}
            }
        }
    }
}
signed main() {
    int n, m; cin >> n >> m;
    ans = vel(n,-1);
    ind = vel(n);
    vel sum(n, 0);
    rep(i, n - 1) { int a; cin >> a; sum[i + 1] = sum[i] + a; }
    vvel b(n, vel(m));
    rep(i, n) {rep(j, m) { cin >> b[i][j]; }}
    int k = 70;
    int i = 0;
    while (i < n - 1) {
        sol1(sum, b, i);
        if (i >= k) {sol_ran(sum, b, i - k, i);}
        i += k;
    }
    sol1(sum, b, n - 1);
    sol_ran(sum, b, i - k, n - 1);
    int ret = 0;
    rep(i, n) { mmax(ret, ans[i]); }
    cout << ret << endl;
    return 0;
}


Measured memory_bytes: 9728