#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
const int INF = 1LL<<30;
struct edge{int to, cost;};
typedef pair<int,int> P;
struct graph{
  int V;
  vector<vector<edge> > G;
  vector<int> d;

  graph(int n){
    init(n);
  }

  void init(int n){
    V = n;
    G.resize(V);
    d.resize(V);
    rep(i,V){
      d[i] = INF;
    }
  }

  void add_edge(int s, int t, int cost){
    edge e;
    e.to = t, e.cost = cost;
    G[s].push_back(e);
  }
  void add_edges(int s, int t, int cost){
    add_edge(s,t,cost);
    add_edge(t,s,cost);
  }

  void dijkstra(int s){
    rep(i,V){
      d[i] = INF;
    }
    d[s] = 0;
    priority_queue<P,vector<P>, greater<P> > que;
    que.push(P(0,s));
    while(!que.empty()){
      P p = que.top(); que.pop();
      int v = p.second;
      if(d[v]<p.first) continue;
      for(auto e : G[v]){
        if(d[e.to]>d[v]+e.cost){
          d[e.to] = d[v]+e.cost;
          que.push(P(d[e.to],e.to));
        }
      }
    }
  }
};
int main(){
  int R,C;cin>>R>>C;
  graph G(R*C);
  
  rep(i,R){
    rep(j,C-1){
      int A;cin>>A;
      G.add_edges(i*C+j,i*C+j+1,A);
    }
  }
  rep(i,R-1){
    rep(j,C){
      int A;cin>>A;
      G.add_edge(i*C+j,(i+1)*C+j,A);
    }
  }
  rep(j,C){
    rep(i,R){
      rep(k,i){
        G.add_edge(i*C+j,k*C+j,i-k+1);
      }
    }
  }
  G.dijkstra(0);
  cout<<G.d[(R*C)-1];  
}
/*                                بِسْمِ اللَّـهِ الرَّحْمَـٰنِ الرَّحِيمِ

                                    ( إِنِ الْحُكْمُ إِلَّا لِلَّهِ )

*/
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<pair<int,int> > vpii;
typedef unsigned long long ull;
typedef long double ld;
const long double pi=acos(-1);
#define x           first
#define y           second
#define read(n,a)   for(int i=0;i<n;i++)cin>>a[i];
#define rep(i,z,n)  for(ll i=z;i<n;i++)
#define rrep(i,z,n) for(ll i=z-1;i>=n;i--)
#define all(v)      v.begin(),v.end()
#define clr(v,d)    memset(v,d,sizeof(v));


int  a[502][502];
int  b[502][502];

//int dx[] = {0, 0, 1,1, 1,-1,-1,-1};
//int dy[] = {1,-1, 0,1,-1, 0,1 ,-1};
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};

string s, ss;

ll n,m,k,w;
ll  ans ,ans1;
ll mod = 1e9 +7;


vector< vector<int> > ad[2][502][502]; //layer n m
int  an[2][502][502];
int main()
{
    cin.tie(0);
    cin.sync_with_stdio(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int t=1;
    //cin>>t;
    while(t--)
    {
        cin>>n>>m;
        rep(i,1,n+1)rep(j,1,m)cin>>a[i][j];
        rep(i,1,n)rep(j,1,m+1)cin>>b[i][j];
        rep(i,1,n+1)
        {
            rep(j,1,m+1)
            {
                if(j<m)ad[0][i][j].push_back( {0,i,j+1,a[i][j]} );
                if(j>1)ad[0][i][j].push_back( {0,i,j-1,a[i][j-1]} );
                if(i<n)ad[0][i][j].push_back( {0,i+1,j,b[i][j]} );
                ad[0][i][j].push_back( {1,i,j,1} );
                if(i>1)ad[1][i][j].push_back( {1,i-1,j,1} );
                ad[1][i][j].push_back( {0,i,j,0} );
            }
        }
        clr(an,-1);
        priority_queue<vector<int> , vector<vector<int> > , greater<vector<int> > >q; //co , la ,i , j
        q.push({0,0,1,1});
        while(!q.empty())
        {
            int la = q.top()[1];
            int cost = q.top()[0];
            int i = q.top()[2];
            int j = q.top()[3];
            q.pop();
            if(~an[la][i][j])continue;
            an[la][i][j]=cost;
            for(vector<int> p : ad[la][i][j])if(an[p[0]][p[1]][p[2]] == -1)
            {
                q.push( { cost+p[3] , p[0] , p[1] , p[2] });
            }
        }
        cout<<an[0][n][m];
    }
    return 0;
}
