#include <bits/stdc++.h>

using namespace std;

typedef pair<long long, long long> pll;

typedef pair<long long, pll> plp;

priority_queue<plp, vector<plp>, greater<plp> > q;

long long n, m, a[507][507], b[507][507], vis[507][507], dist[507][507], v, x, y;

void check(long long x, long long y, long long d)
{
    if(x==0 || y==0 || x>n || y>m) return;
    if(dist[x][y]<=d) return;
    dist[x][y]=d;
    q.push({d, {x, y}});
    return;
}

int main()
{
    cin>>n>>m;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m-1; j++)
        {
            dist[i][j]=1000000000000000;
            cin>>a[i][j];
        }
    }
    for(int i=1; i<=n-1; i++)
    {
        for(int j=1; j<=m; j++)
        {
            dist[i][j]=100000000000000;
            cin>>b[i][j];
        }
    }
    dist[1][1]=0;
    dist[n][m]=100000000000000000;
    q.push({0, {1, 1}});
    while(!q.empty())
    {
        v=q.top().first;
        x=q.top().second.first;
        y=q.top().second.second;
        q.pop();
        if(vis[x][y]==1) continue;
        vis[x][y]=1;
        check(x, y+1, a[x][y]+v);
        check(x, y-1, a[x][y-1]+v);
        check(x+1, y, b[x][y]+v);
        for(int i=1; i<x; i++)
        {
            check(x-i, y, 1+i+v);
        }
    }
    cout<<dist[n][m];
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

using TIII = tuple<int, int, int>;

template<class T> inline bool chmin(T& a, T b) {
  return (a > b) ? (a = b, true) : false;
}

const int INF = 1 << 30;

int main(void)
{
  int R, C; cin >> R >> C;
  vector<vector<int>> A(R, vector<int>(C-1)), B(R-1, vector<int>(C));
  rep(i, R) rep(j, C-1) cin >> A.at(i).at(j);
  rep(i, R-1) rep(j, C) cin >> B.at(i).at(j);
  vector<vector<int>> D(R, vector<int>(C, INF));
  D.at(0).at(0) = 0;
  priority_queue<TIII, vector<TIII>, greater<TIII>> candidate;
  candidate.push(make_tuple(0, 0, 0));
  while (!candidate.empty()) {
    TIII t = candidate.top(); candidate.pop();
    int tD = get<0>(t);
    int p1 = get<1>(t);
    int p2 = get<2>(t);
    if (tD > D.at(p1).at(p2)) continue;
    if (p1 == R - 1 && p2 == C - 1) {
      cout << tD << endl; return 0;
    }
    if (p2 < C - 1 && chmin(D.at(p1).at(p2 + 1), tD + A.at(p1).at(p2))) {
      candidate.push(make_tuple(tD + A.at(p1).at(p2), p1, p2 + 1));
    }
    if (p2 > 0 && chmin(D.at(p1).at(p2 - 1), tD + A.at(p1).at(p2 - 1))) {
      candidate.push(make_tuple(tD + A.at(p1).at(p2 - 1), p1, p2 - 1));
    }
    if (p1 < R - 1 && chmin(D.at(p1 + 1).at(p2), tD + B.at(p1).at(p2))) {
      candidate.push(make_tuple(tD + B.at(p1).at(p2), p1 + 1, p2));
    }
    for (int i = 1; i <= p1; i++) {
      if (chmin(D.at(p1 - i).at(p2), tD + 1 + i)) {
        candidate.push(make_tuple(tD + 1 + i, p1 - i, p2));
      }
    }
  }
}