	
 #include <bits/stdc++.h>
 
 #define FIXED_FLOAT(x)  std::fixed <<std::setprecision(20) << (x)
 #define all(v) (v).begin(), (v).end()
 using namespace  std;
 #define forn(i,n) for (int i = 0; i < (n); ++i)
 using ll = long long;
 int mod = (ll)1e9 + 7;
 #define PI acos(-1)
 typedef pair<int, int> pairs;
 
 const int INF = 1e9 + 1;
 const int N = 2e5 + 100;
 const double eps = 1e-3;
 
 template <typename XPAX>
 void ckma(XPAX &x, XPAX y) {
     x = (x < y ? y : x);
 }
 template <typename XPAX>
 void ckmi(XPAX &x, XPAX y) {
     x = (x > y ? y : x);
 }
 
 void solve() {
 
 
 	int h, w;
 	cin >> h >> w;
 	vector<vector<int>> a(h, vector<int>(w - 1));
 	forn(i, h) forn(j, w - 1) cin >> a[i][j];

 	vector<vector<int>> b(h - 1, vector<int>(w));
 	forn(i, h - 1) forn(j, w) cin >> b[i][j];
 
 	using P = tuple<int, int, int>;

 	auto myid = [&](P p) {
 		int r, c , f;
 		tie(r, c, f) = p;
 		return f * (h * w) + r * w + c;
 	};
 	using Q = pair<int, P>;

 	vector<int> dist(2 * h * w + 1, INF);
 	priority_queue<Q, vector<Q>, greater<Q>>q;
 	auto push = [&](P p, int D){
 		if(dist[myid(p)] <= D)return;
 		dist[myid(p)] = D;
 		q.push({D, p});
 	};
 	push(P{0, 0, 0}, 0);
 	auto get = [&](P p, int &r, int &c, int &f ) {
 		tie(r, c, f) = p;
 	};

 	
 	while(q.size()) {
 		Q s = q.top();
 		q.pop();
 		int D = s.first;
 		int r, c, f;
 		get(s.second, r, c, f);
 		if(r == h - 1 && c == w - 1) {
 			cout << D << endl;
 			return;
 		}
 		if(f == 0) {
 			push(P{r, c, 1}, D + 1);
 			if(c)
 				push(P{r, c - 1, f},D + a[r][c - 1]);
 			if(c + 1 < w) {
				push(P{r, c + 1, f},D + a[r][c]);
			}
			if(r + 1 < h)
				push(P{r + 1, c, f}, D + b[r][c]);

		}
		else {
			if(r) push(P{r - 1, c, f}, D + 1);

			push(P{r, c, 0}, D);
		}
	}

	

 
 }
 void test_case() {
     int t;
     cin >> t;
     forn(p, t) {
 
         //cout << "Case #" << p + 1 << ": ";
         solve();
     }
 }
 int main() {
 
     ios::sync_with_stdio(false);
     cin.tie(nullptr);
     cout.tie(nullptr);
 
     solve();
 
 }
  

#include <bits/stdc++.h>
using namespace std;

using lli = long long int;
using ii = pair<int, int>;

const int MAXN = 500;

int r, c;
int a[MAXN+1][MAXN];
int b[MAXN][MAXN+1];

int cost[MAXN+1][MAXN+1];

int dijkstra() {
    memset(cost, -1, sizeof(cost));
    priority_queue<pair<int, ii>, vector<pair<int, ii>>, greater<pair<int, ii>>> pq;

    cost[1][1] = 0;
    pq.push({0, {1, 1}});

    while(!pq.empty()) {
        pair<int, ii> u = pq.top(); pq.pop();
        int curCost = u.first;
        ii pos = u.second;
        // printf("%d %d %d\n", curCost, pos.first, pos.second);

        if(pos.first == r and pos.second == c) {
            return curCost;
        }
        if(curCost > cost[pos.first][pos.second]) {
            continue;
        }

        if(pos.first < r and
        (cost[pos.first+1][pos.second] == -1 or
        curCost+b[pos.first][pos.second] < cost[pos.first+1][pos.second])) {
            cost[pos.first+1][pos.second] = curCost+b[pos.first][pos.second];
            pq.push({cost[pos.first+1][pos.second], {pos.first+1, pos.second}});
        }
        if(pos.second > 1 and
        (cost[pos.first][pos.second-1] == -1 or
        curCost+a[pos.first][pos.second-1] < cost[pos.first][pos.second-1])) {
            cost[pos.first][pos.second-1] = curCost+a[pos.first][pos.second-1];
            pq.push({cost[pos.first][pos.second-1], {pos.first, pos.second-1}});
        }
        if(pos.second < c and
        (cost[pos.first][pos.second+1] == -1 or
        curCost+a[pos.first][pos.second] < cost[pos.first][pos.second+1])) {
            cost[pos.first][pos.second+1] = curCost+a[pos.first][pos.second];
            pq.push({cost[pos.first][pos.second+1], {pos.first, pos.second+1}});
        }
        for(int i=1; i<pos.first; i++) {
            if(cost[pos.first-i][pos.second] == -1 or
            curCost+i+1 < cost[pos.first-i][pos.second]) {
                cost[pos.first-i][pos.second] = curCost+i+1;
                pq.push({cost[pos.first-i][pos.second], {pos.first-i, pos.second}});
            }
            else if(curCost+i+1 == cost[pos.first-i][pos.second]) {
                continue;
            }
            else {
                break;
            }
        }
    }
}

int main() {
    scanf("%d %d", &r, &c);
    for(int i=1; i<=r; i++) {
        for(int j=1; j<c; j++) {
            scanf("%d", &a[i][j]);
        }
    }
    for(int i=1; i<r; i++) {
        for(int j=1; j<=c; j++) {
            scanf("%d", &b[i][j]);
        }
    }

    printf("%d\n", dijkstra());
}
