// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <map>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <vector>

#include <queue>

#include <cmath>



// output

#define SPBR(w, n) std::cout<<(w + 1 == n ? '\n' : ' ');

#define YES cout << "YES" << endl

#define Yes cout << "Yes" << endl

#define NO cout << "NO" << endl

#define No cout << "No" << endl

// utility

#define ALL(i) (i).begin(), (i).end()

#define FOR(i, a, n) for(int i=(a);i<(n);++i)

#define RFOR(i, a, n) for(int i=(n)-1;i>=(a);--i)

#define REP(i, n) for(int i=0;i<int(n);++i)

#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)

#define IN(a, x, b) (a<=x && x<b)

#define OUT(a, x, b) (x<a || b<=x)

template<class T> inline T chmax(T & a, const T b) { return a = (a < b) ? b : a; }

template<class T> inline T chmin(T& a, const T b) { return a = (a > b) ? b : a; }



// type/const

#define int ll

using ll = long long;

using ull = unsigned long long;

using ld = long double;

const int MOD = 1000000007;

const int INF = 1e18;



using namespace std;





signed main() {

  int H, W;

  cin >> H >> W;



  vector<vector<int>> C(H, vector<int>(W));

  REP(i, H) REP(j, W) cin >> C[i][j];

  int b;

  REP(i, H) REP(j, W){

    cin >> b;

    C[i][j] -= b;

    C[i][j] = abs(C[i][j]);

  }



  vector<vector<vector<int>>> vec(H, vector<vector<int>>(W, vector<int>(12800, 0)));

  vec[0][0][C[0][0]] = 1;

  REP(i, H){

    REP(j, W){

      REP(k, 12800){

        if(vec[i][j][k] == 0) continue;



        if(j+1 < W){

          vec[i][j+1][abs(C[i][j+1]-k)] = 1;

          vec[i][j+1][C[i][j+1]+k] = 1;

        }

        if(i+1 < H){

          vec[i+1][j][abs(C[i+1][j]-k)] = 1;

          vec[i+1][j][C[i+1][j]+k] = 1;

        }

      }

    }

  }



  REP(i, 12800){

    if(vec[H-1][W-1][i]){

      cout << i << endl;

      return 0;

    }

  }





  return 0;

}

// Faster C++ solution for the same problem (measured speedup: 2.190096109259363x):
#include <iostream>

#include <algorithm>

#include <map>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <vector>

#include <queue>

#include <cmath>



// output

#define SPBR(w, n) std::cout<<(w + 1 == n ? '\n' : ' ');

#define YES cout << "YES" << endl

#define Yes cout << "Yes" << endl

#define NO cout << "NO" << endl

#define No cout << "No" << endl

// utility

#define ALL(i) (i).begin(), (i).end()

#define FOR(i, a, n) for(int i=(a);i<(n);++i)

#define RFOR(i, a, n) for(int i=(n)-1;i>=(a);--i)

#define REP(i, n) for(int i=0;i<int(n);++i)

#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)

#define IN(a, x, b) (a<=x && x<b)

#define OUT(a, x, b) (x<a || b<=x)

template<class T> inline T chmax(T & a, const T b) { return a = (a < b) ? b : a; }

template<class T> inline T chmin(T& a, const T b) { return a = (a > b) ? b : a; }



// type/const

#define int ll

using ll = long long;

using ull = unsigned long long;

using ld = long double;

const int MOD = 1000000007;

const int INF = 1e18;



using namespace std;





signed main() {

  int H, W;

  cin >> H >> W;



  vector<vector<int>> C(H, vector<int>(W));

  REP(i, H) REP(j, W) cin >> C[i][j];

  int b;

  REP(i, H) REP(j, W){

    cin >> b;

    C[i][j] -= b;

    C[i][j] = abs(C[i][j]);

  }



  vector<vector<vector<bool>>> vec(H, vector<vector<bool>>(W, vector<bool>(12800, false)));

  vec[0][0][C[0][0]] = true;

  REP(i, H){

    REP(j, W){

      REP(k, 12800){

        if(vec[i][j][k] == false) continue;



        if(j+1 < W){

          vec[i][j+1][abs(C[i][j+1]-k)] = true;

          vec[i][j+1][C[i][j+1]+k] = true;

        }

        if(i+1 < H){

          vec[i+1][j][abs(C[i+1][j]-k)] = true;

          vec[i+1][j][C[i+1][j]+k] = true;

        }

      }

    }

  }



  REP(i, 12800){

    if(vec[H-1][W-1][i]){

      cout << i << endl;

      return 0;

    }

  }





  return 0;

}