#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define si(x) int(x.size())
const int mod=1000000007,MAX=200005,INF=1<<30;

template<typename T>
struct SegmentTree{
    using F=function<T(T,T)>;
    
    int n;
    vector<T> dat;
    F f;
    T ti;
    
    SegmentTree(int n_ ,F f ,T ti) :f(f),ti(ti){
        n=1;
        while(n<n_) n*=2;
        dat.assign(2*n-1,ti);
    }
    
    SegmentTree(int n_ ,vector<T> &v ,F f,T ti) :f(f),ti(ti){
        n=1;
        while(n<n_) n*=2;
        dat.assign(2*n-1,ti);
        
        for(int i=n-1;i-(n-1)<v.size();i++) dat[i]=v[i-(n-1)];
        
        for(int i=n-2;i>=0;i--) dat[i]=f(dat[i*2+1],dat[i*2+2]);
    }
    
    void update(int k,T x){
        k+=n-1;
        dat[k]=x;
        
        while(k){
            k=(k-1)/2;
            dat[k]=f(dat[k*2+1],dat[k*2+2]);
        }
    }
    
    void set(int k,T x){
        dat[n-1+k]=x;
    }
    
    void built(){
        for(int i=n-2;i>=0;i--) dat[i]=f(dat[i*2+1],dat[i*2+2]);
    }
    
    T query_(int a,int b,int k,int l,int r){
        if(r<=a||b<=l) return ti;
        if(a<=l&&r<=b) return dat[k];
        else{
            T vl=query_(a,b,2*k+1,l,(l+r)/2);
            T vr=query_(a,b,2*k+2,(l+r)/2,r);
            return f(vl,vr);
        }
    }
    
    T query(int a,int b){
        return query_(a,b,0,0,n);
    }
    
    T get(int k){
        return dat[k+n-1];
    }
    
    template<typename C>
    int findright(int st,C &check,T &acc,int k,int l,int r){
        if(l+1==r){
            acc=f(acc,dat[k]);
            return check(acc)?k-(n-1):-1;
        }
        int m=(l+r)/2;
        if(m<=st) return findright(st,check,acc,2*k+2,m,r);
        if(st<=l&&!check(f(acc,dat[k]))){
            acc=f(acc,dat[k]);
            return -1;
        }
        int vl=findright(st,check,acc,2*k+1,l,m);
        if(~vl) return vl;
        return findright(st,check,acc,2*k+2,m,r);
    }
    
    template<typename C>
    int findright(int st,C &check){
        T acc=ti;
        return findright(st,check,acc,0,0,n);
    }//条件を満たす最小のidxを返す
    
    template<typename C>
    int findleft(int st,C &check,T &acc,int k,int l,int r){
        if(l+1==r){
            acc=f(acc,dat[k]);
            return check(acc)?k-(n-1):INF;
        }
        int m=(l+r)/2;
        if(m>=st) return findleft(st,check,acc,2*k+1,l,m);
        if(st>=r&&!check(f(acc,dat[k]))){
            acc=f(acc,dat[k]);
            return INF;
        }
        int vr=findleft(st,check,acc,2*k+2,m,r);
        if(vr!=INF) return vr;
        return findleft(st,check,acc,2*k+1,l,m);
    }
    
    template<typename C>
    int findleft(int st,C &check){
        T acc=ti;
        return findleft(st,check,acc,0,0,n);
    }//条件を満たす最大のidxを返す
    
};

void f(int l,int r,SegmentTree<pair<int,int>> &seg,vector<vector<ll>> &sum){
    if(l>=r) return;
    
    pair<int,int> c=seg.query(l,r);
    
    sum[l][c.se]+=c.fi;
    sum[l][r]-=c.fi;
    sum[c.se+1][c.se]-=c.fi;
    sum[c.se+1][r]+=c.fi;
    
    f(l,c.se,seg,sum);
    f(c.se+1,r,seg,sum);
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N,M;cin>>N>>M;
    vector<ll> cost(N);
    for(int i=1;i<N;i++){
        cin>>cost[i];
        cost[i]+=cost[i-1];
    }
    vector<vector<ll>> def(M,vector<ll>(N)),sum(N+1,vector<ll>(N+1));
    for(int i=0;i<N;i++){
        for(int j=0;j<M;j++){
            cin>>def[j][i];
        }
    }
    vector<SegmentTree<pair<int,int>>> seg(M,SegmentTree<pair<int,int>>{
        N,
        [](auto a,auto b){return max(a,b);},
        make_pair(0,0)
    });
    
    for(int i=0;i<M;i++){
        for(int j=0;j<N;j++){
            seg[i].set(j,{def[i][j],j});
        }
        seg[i].built();
    }
    
    for(int q=0;q<M;q++){
        f(0,N,seg[q],sum);
    }
    
    for(int i=0;i<=N;i++){
        for(int j=1;j<=N;j++){
            sum[i][j]+=sum[i][j-1];
        }
    }
    
    for(int i=1;i<=N;i++){
        for(int j=0;j<=N;j++){
            sum[i][j]+=sum[i-1][j];
        }
    }
    
    ll ans=0;
    
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            if(i>j) continue;
            chmax(ans,sum[i][j]-(cost[j]-cost[i]));
        }
    }
    
    cout<<ans<<endl;
    
}



Measured memory_bytes: 230272