// Slower C++ solution:
#define _USE_MATH_DEFINES

#include <array>

#include <cassert>

#include <cstdio>

#include <cstring>

#include <iostream>

#include <string>

#include <sstream>

#include <vector>

#include <queue>

#include <stack>

#include <list>

#include <set>

#include <map>

#include <unordered_set>

#include <unordered_map>

#include <algorithm>

#include <complex>

#include <cmath>

#include <numeric>

#include <bitset>

#include <functional>

#include <random>

#include <ctime>



using namespace std;



#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)

template <typename Arg1>

void __f(const char* name, Arg1&& arg1){

  cerr << name << ": " << arg1 << endl;

}

template <typename Arg1, typename... Args>

void __f(const char* names, Arg1&& arg1, Args&&... args){

  const char* comma = strchr(names + 1, ',');

  cerr.write(names, comma - names) << ": " << arg1 << " |";

  __f(comma + 1, args...);

}



typedef long long int64;

typedef pair<int, int> ii;

const int INF = 1 << 29;

const int MOD = 1e9 + 7;

mt19937 mrand(random_device{}());

int rnd(int x) { return mrand() % x; }



const int N = 80;

const int M = 12800 + 10;

bitset<M * 2> dp[N][N];



int main() {

  int n, m;

  scanf("%d%d", &n, &m);

  // n = m = 80;

  vector<vector<int>> a(n, vector<int>(m));

  vector<vector<int>> b(n, vector<int>(m));

  for (int i = 0; i < n; ++i) {

    for (int j = 0; j < m; ++j) {

      scanf("%d", &a[i][j]);

      // a[i][j] = rnd(81);

    }

  }

  for (int i = 0; i < n; ++i) {

    for (int j = 0; j < m; ++j) {

      scanf("%d", &b[i][j]);

      // b[i][j] = rnd(81);

    }

  }

  int x = a[0][0] - b[0][0];

  dp[0][0][M + x] = dp[0][0][M - x] = 1;

  for (int i = 0; i < n; ++i) {

    for (int j = 0; j < m; ++j) {

      if (i + j == 0) continue;

      int x = a[i][j] - b[i][j];

      if (i - 1 >= 0) {

        for (int k = -M; k < M; ++k) {

          if (dp[i - 1][j][M + k]) {

            dp[i][j][M + k + x] = dp[i][j][M + k - x] = 1;

          }

        }

      }

      if (j - 1 >= 0) {

        for (int k = -M; k < M; ++k) {

          if (dp[i][j - 1][M + k]) {

            dp[i][j][M + k + x] = dp[i][j][M + k - x] = 1;

          }

        }

      }

      // trace(i, j, dp[i][j].size());

    }

  }

  int best = INF;

  for (int k = -M; k < M; ++k) {

    if (dp[n - 1][m - 1][M + k]) {

      best = min(best, abs(k));

    }

  }

  printf("%d\n", best);

  return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.1038661188644359x):
#define _USE_MATH_DEFINES

#include <array>

#include <cassert>

#include <cstdio>

#include <cstring>

#include <iostream>

#include <string>

#include <sstream>

#include <vector>

#include <queue>

#include <stack>

#include <list>

#include <set>

#include <map>

#include <unordered_set>

#include <unordered_map>

#include <algorithm>

#include <complex>

#include <cmath>

#include <numeric>

#include <bitset>

#include <functional>

#include <random>

#include <ctime>



using namespace std;



#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)

template <typename Arg1>

void __f(const char* name, Arg1&& arg1){

  cerr << name << ": " << arg1 << endl;

}

template <typename Arg1, typename... Args>

void __f(const char* names, Arg1&& arg1, Args&&... args){

  const char* comma = strchr(names + 1, ',');

  cerr.write(names, comma - names) << ": " << arg1 << " |";

  __f(comma + 1, args...);

}



typedef long long int64;

typedef pair<int, int> ii;

const int INF = 1 << 29;

const int MOD = 1e9 + 7;

mt19937 mrand(random_device{}());

int rnd(int x) { return mrand() % x; }



const int N = 80;

const int M = 12800 + 10;

bitset<M * 2> dp[N][N];



int main() {

  int n, m;

  scanf("%d%d", &n, &m);

  // n = m = 80;

  vector<vector<int>> a(n, vector<int>(m));

  vector<vector<int>> b(n, vector<int>(m));

  for (int i = 0; i < n; ++i) {

    for (int j = 0; j < m; ++j) {

      scanf("%d", &a[i][j]);

      // a[i][j] = rnd(81);

    }

  }

  for (int i = 0; i < n; ++i) {

    for (int j = 0; j < m; ++j) {

      scanf("%d", &b[i][j]);

      // b[i][j] = rnd(81);

    }

  }

  int x = a[0][0] - b[0][0];

  dp[0][0][M + x] = dp[0][0][M - x] = 1;

  for (int i = 0; i < n; ++i) {

    for (int j = 0; j < m; ++j) {

      if (i + j == 0) continue;

      int x = abs(a[i][j] - b[i][j]);

      if (i - 1 >= 0) {

        dp[i][j] |= dp[i - 1][j] << x;

        dp[i][j] |= dp[i - 1][j] >> x;

      }

      if (j - 1 >= 0) {

        dp[i][j] |= dp[i][j - 1] << x;

        dp[i][j] |= dp[i][j - 1] >> x;

      }

      // trace(i, j, dp[i][j].size());

    }

  }

  int best = INF;

  for (int k = -M; k < M; ++k) {

    if (dp[n - 1][m - 1][M + k]) {

      best = min(best, abs(k));

    }

  }

  printf("%d\n", best);

  return 0;

}