#pragma GCC optimize ("O2")
#pragma GCC target ("avx")
//#include<bits/stdc++.h>
//#include<atcoder/all>
//using namespace atcoder;
#include<iostream>
#include<queue>
#include<cstring>

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

short A[501][501], B[501][501];
int D[1 << 18];

const int CM = 1 << 17, CL = 12;
char cn[CM + CL], * ci = cn + CM + CL, * owa = cn + CM, ct;
const int ma0 = 269488144;
const int ma1 = 252645135;
const int ma2 = 16711935;
const int ma3 = 65535;
inline int tiisaikazu() {
	if (ci - owa > 0) {
		memcpy(cn, owa, CL);
		ci -= CM;
		fread(cn + CL, 1, CM, stdin);
	}
	int tmp = *(int*)ci;
	int dig = 36 - __builtin_ctzll((tmp & ma0) ^ ma0);
	tmp = tmp << dig & ma1;
	tmp = tmp * 10 + (tmp >> 8) & ma2;
	tmp = tmp * 100 + (tmp >> 16) & ma3;
	ci += 40 - dig >> 3;
	return tmp;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int H = tiisaikazu(), W = tiisaikazu();
	rep(i, H) rep(j, W - 1) A[i][j] = tiisaikazu() << 1;
	rep(i, H - 1) rep(j, W) B[i][j] = tiisaikazu() << 1;

	priority_queue<ll, vector<ll>, greater<ll>> q;
	D[0] = -2e9 + 1;
	q.push((ll)D[0] << 32);
	int owa = (H - 1) << 9 | W - 1;

	while (q.size()) {
		auto tmp = q.top();
		q.pop();
		int d0 = tmp >> 32;
		int hwp = tmp & (1 << 20) - 1;
		if (D[hwp] != d0) continue;

		int h = hwp >> 9;
		int w = hwp & 511;
		int p = (d0 & 1) << 1 | 1;
		d0 |= 1;

		if (hwp == owa) break;

		if (w > 0) if (D[hwp - 1] > d0 + A[h][w - 1]) {
			D[hwp - 1] = d0 + A[h][w - 1];
			q.push((ll)(d0 + A[h][w - 1]) << 32 | hwp - 1);
		}
		if (w < W - 1) if (D[hwp + 1] > d0 + A[h][w]) {
			D[hwp + 1] = d0 + A[h][w];
			q.push((ll)(d0 + A[h][w]) << 32 | hwp + 1);
		}
		if (h > 0) if (D[hwp - 512] > d0 + p) {
			D[hwp - 512] = d0 + p;
			q.push((ll)(d0 + p) << 32 | hwp - 512);
		}
		if (h < H - 1) if (D[hwp + 512] > d0 + B[h][w]) {
			D[hwp + 512] = d0 + B[h][w];
			q.push((ll)(d0 + B[h][w]) << 32 | hwp + 512);
		}
	}

	co(D[owa] - D[0] >> 1);

	Would you please return 0;
}
#include<bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define PI acos(-1)
#define pb push_back
// #define int long long
#define ld long double
#define sp fixed<<setprecision
#define bp __builtin_popcountll
#define all(x) x.begin(),x.end()
#define pii pair<long long,long long>
#define FAST ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);

const int M = (1e9)+7;
const int N = 1000005;
const int INF = 1e9;

signed main()
{
  FAST
  int tc=1;
//   cin>>tc;
  for(int ti=1;ti<=tc;ti++)
  {
      int r,c;
      cin>>r>>c;
      int a[r+1][c+1], b[r+1][c+1];
      for(int i=1;i<=r;i++) for(int j=1;j<c;j++) cin>>a[i][j];
      for(int i=1;i<r;i++) for(int j=1;j<=c;j++) 
      {
          cin>>b[i][j];
          if(i > 1) b[i][j] += b[i-1][j];
      }
      set<pair<int, pii>> dist;
      int val[r+1][c+1], vis[r+1][c+1];
      for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) dist.insert({INF, {i,j}}), val[i][j] = INF, vis[i][j] = 0;
      dist.erase({INF, {1,1}});
      dist.insert({0, {1,1}});
      val[1][1] = 0;
      vis[1][1] = 1;
      int ans = INF;
      while(true)
      {
          auto it = *dist.begin();
          int d = it.ff;
          pii curr = it.ss;
          int x = curr.ff, y = curr.ss;
          if(x == r && y == c)
          {
              ans = d;
              break;
          }
          vis[x][y] = 1;
          dist.erase(it);
          for(int i=1;i<x;i++)
          {
              if(!vis[i][y])
              {
                  int new_val = d + x-i+1;
                  if(new_val < val[i][y])
                  {
                      dist.erase({val[i][y], {i,y}});
                      val[i][y] = new_val;
                      dist.insert({val[i][y], {i,y}});
                  }
              }
          }
          if(x < r && !vis[x+1][y])
          {
              int new_val = d + b[x][y] - (x-1 > 0 ? b[x-1][y] : 0);
              if(new_val < val[x+1][y])
              {
                  dist.erase({val[x+1][y], {x+1,y}});
                  val[x+1][y] = new_val;
                  dist.insert({val[x+1][y], {x+1,y}});
              }
          }
          if(y > 1 && !vis[x][y-1])
          {
              int new_val = d + a[x][y-1];
              if(new_val < val[x][y-1])
              {
                  dist.erase({val[x][y-1], {x,y-1}});
                  val[x][y-1] = new_val;
                  dist.insert({val[x][y-1], {x,y-1}});
              }
          }
          if(y < c && !vis[x][y+1])
          {
              int new_val = d + a[x][y];
              if(new_val < val[x][y+1])
              {
                  dist.erase({val[x][y+1], {x,y+1}});
                  val[x][y+1] = new_val;
                  dist.insert({val[x][y+1], {x,y+1}});
              }
          }
      }
      cout<<ans<<endl;
  }
  return 0;
}