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

const int inf = 1e8;
const ll llinf = 1e18;
const double PI = acos(-1);
#define yes "Yes"
#define no "No"
#define all(n) n.begin(), n.end()

using Graph = vector<vector<int>>;
vector<int> visited(false);
ll ans = 0;

void dfs(const Graph &G, int v) {
  visited[v] = true;
  for (auto next : G[v]) {
    if (visited[next]) continue;
    ans++;
    dfs(G, next);
  }
}

int main() {
  int n, m;
  cin >> n >> m;
  Graph g(n);
  rep(i, m) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    g[a].push_back(b);
  }

  rep(i, n) {
    visited.assign(n, 0);
    dfs(g, i);
  }

  cout << ans + n << endl;
  // cout << fixed << setprecision(9) << ans << endl;
}

#include <iostream>
#include <stdio.h>
#include <vector>
#include <queue>
#include <utility>
using namespace std;


typedef struct edge{
	int to;
	int cost;
}Edge;
typedef pair<int,int> P;

long long INF=250000010;
int V;
vector<Edge> G[1000000];
long long d[1000000];

void dijkstra(int s){
  priority_queue<P,vector<P>,greater<P>> que;
	fill(d,d+V,INF);
	d[s]=0;
	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(unsigned int i=0;i<G[v].size();i++){
		  Edge e=G[v][i];
			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;
  V=R*C*2;
  vector<vector<int>> A,B;
  for(int i=0;i<R;i++){
    vector<int>tmp(C-1);
    for(int j=0;j<C-1;j++)cin>>tmp.at(j);
    A.push_back(tmp);
  }
  for(int i=0;i<R-1;i++){
    vector<int>tmp(C);
    for(int j=0;j<C;j++)cin>>tmp.at(j);
    B.push_back(tmp);
  }
  int q=R*C;
  for(int i=0;i<R;i++){
    for(int j=0;j<C;j++){
      if(j<C-1){
        G[C*i+j].push_back({C*i+j+1,A.at(i).at(j)});
      }
      if(j>0){
        G[C*i+j].push_back({C*i+j-1,A.at(i).at(j-1)});
      }
      if(i<R-1){
        G[C*i+j].push_back({C*(i+1)+j,B.at(i).at(j)});
      }
      G[C*i+j].push_back({q+C*i+j,1});
      G[q+C*i+j].push_back({C*i+j,0});
      if(i>0){
        G[q+C*i+j].push_back({q+C*(i-1)+j,1});
      }
    }
  }
  dijkstra(0);
  printf("%d\n",d[R*C-1]);
  return 0;
}