#include <bits/stdc++.h>
using namespace std;
template <class T>
void PV(T &x) {
  for (__typeof__((x).begin()) i = (x).begin(); i != (x).end(); i++)
    cout << *i << " ";
  cout << endl;
}
template <class T>
void PA(T x[], int n) {
  for (int i = 0; i < n; i++) cout << x[i] << " ";
  cout << endl;
}
template <class T>
inline void gmin(T &a, T b) {
  if (b < a) a = b;
}
template <class T>
inline void gmax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline T sqr(T x) {
  return x * x;
}
const int M = 100000 + 10, N = 6, B = 1 << N;
const long long INF = 1ll << 60;
int n, m;
long long xcon[M][N], ycon[M][N];
inline int two(int x) { return 1 << x; }
void myin() {
  cin >> n >> m;
  for (int i = 0; i < m - 1; i++)
    for (int j = 0; j < n; j++) scanf("%lld", xcon[i] + j);
  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++) scanf("%lld", ycon[i] + j);
}
int boundary[B];
long long dp[M][B], xsum[B], ysum[B];
void work() {
  memset(boundary, 0, sizeof(boundary));
  for (int i = 0; i < two(n); i++)
    for (int j = 0; j < n; j++) {
      bool t1 = two(j) & i, t2 = two((j + 1) % n) & i;
      if (t1 ^ t2) boundary[i] |= two(j);
    }
  fill(dp[0], dp[0] + two(n), INF);
  dp[0][two(n) - 1] = 0;
  for (int lv = 1; lv < m; lv++) {
    memset(xsum, 0, sizeof(xsum));
    for (int i = 0; i < two(n); i++)
      for (int j = 0; j < n; j++)
        if (two(j) & i) xsum[i] += xcon[lv - 1][j];
    memset(ysum, 0, sizeof(ysum));
    for (int i = 0; i < two(n); i++)
      for (int j = 0; j < n; j++)
        if (two(j) & boundary[i]) ysum[i] += ycon[lv][j];
    fill(dp[lv], dp[lv] + two(n), INF);
    for (int i = 0; i < two(n); i++)
      for (int j = 0; j < two(n); j++)
        gmin(dp[lv][j], dp[lv - 1][i] + xsum[i ^ j] + ysum[j]);
  }
  cout << dp[m - 1][0];
}
int main() {
  myin();
  work();
  return 0;
}
