#include <bits/stdc++.h>
using namespace std;
int arr[16][10005];
bool g[16][16];
bool g2[16][16];
int Min[16][16];
int Min2[16][16];
int n, m;
void get_min() {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      Min[i][j] = INT_MAX;
      Min2[i][j] = INT_MAX;
      for (int z = 0; z < m; z++) {
        Min[i][j] = min(Min[i][j], abs(arr[i][z] - arr[j][z]));
      }
      for (int z = 0; z < m - 1; z++) {
        Min2[i][j] = min(Min2[i][j], abs(arr[j][z] - arr[i][z + 1]));
      }
    }
  }
}
void get_connections(int k) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (Min[i][j] >= k)
        g[i][j] = 1;
      else
        g[i][j] = 0;
      if (Min2[i][j] >= k)
        g2[i][j] = 1;
      else
        g2[i][j] = 0;
    }
  }
}
int dp[16][16][(1 << 16)];
int solve(int prev, int first, int mask) {
  if (mask == (1 << n) - 1) {
    return g2[first][prev];
  }
  int &ans = dp[prev][first][mask];
  if (~ans) return ans;
  ans = 0;
  for (int i = 0; i < n; i++) {
    if (!(mask & (1 << i)) && g[prev][i]) {
      if (solve(i, first, mask | (1 << i))) return ans = 1;
    }
  }
  return ans = 0;
}
bool valid(int k) {
  get_connections(k);
  memset(dp, -1, sizeof dp);
  for (int i = 0; i < n; i++) {
    if (solve(i, i, (1 << i))) {
      return true;
    }
  }
  return false;
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> arr[i][j];
    }
  }
  if (n == 1) {
    int ans = INT_MAX;
    for (int i = 1; i < m; i++) {
      ans = min(ans, abs(arr[0][i] - arr[0][i - 1]));
    }
    cout << ans;
    return 0;
  }
  get_min();
  int st = 0, en = 1e9, ans = -1;
  while (st <= en) {
    int mid = (st + en) / 2;
    if (valid(mid)) {
      ans = mid;
      st = mid + 1;
    } else {
      en = mid - 1;
    }
  }
  cout << ans;
  return 0;
}
