#include <bits/stdc++.h>
using namespace std;
namespace io {
const int SI = 1 << 21 | 1;
char IB[SI], *IS, *IT, OB[SI], *OS = OB, *OT = OS + SI - 1, c, ch[100];
int f, t;
inline void flush() { fwrite(OB, 1, OS - OB, stdout), OS = OB; }
inline void pc(char x) {
  *OS++ = x;
  if (OS == OT) flush();
}
template <class I>
inline void rd(I &x) {
  for (f = 1, c = (IS == IT ? (IT = (IS = IB) + fread(IB, 1, SI, stdin),
                              IS == IT ? EOF : *IS++)
                            : *IS++);
       c < '0' || c > '9';
       c = (IS == IT ? (IT = (IS = IB) + fread(IB, 1, SI, stdin),
                       IS == IT ? EOF : *IS++)
                     : *IS++))
    if (c == '-') f = -1;
  for (x = 0; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + (c & 15),
      c = (IS == IT ? (IT = (IS = IB) + fread(IB, 1, SI, stdin),
                      IS == IT ? EOF : *IS++)
                    : *IS++))
    ;
  x *= f;
}
template <class I>
inline void print(I x, char k = '\n') {
  if (!x) pc('0');
  if (x < 0) pc('-'), x = -x;
  while (x) ch[++t] = x % 10 + '0', x /= 10;
  while (t) pc(ch[t--]);
  pc(k);
}
struct Flush {
  ~Flush() { flush(); }
} flusher;
}  // namespace io
using io::print;
using io::rd;
template <class I>
inline I Min(I x, I y) {
  return x < y ? x : y;
}
template <class I>
inline I Max(I x, I y) {
  return x > y ? x : y;
}
template <class I>
inline void Swap(I &x, I &y) {
  x ^= y ^= x ^= y;
}
template <class I>
inline I Abs(I x) {
  return x >= 0 ? x : -x;
}
const int N = 16, M = 1e4, inf = 0x3f3f3f3f;
int n, m, a[N][M], d1[N][N], d2[N][N], f[N][N], s[1 << N][N], ans;
inline void Hamilton(int x) {
  memset(s, 0, sizeof(s));
  s[1 << x][x] = inf;
  for (int i = 1; i < (1 << n); ++i)
    for (int j = 0; j < n; ++j)
      if ((i >> j) & 1)
        for (int k = 0; k < n; ++k)
          if (((i ^ (1 << j)) >> k) & 1)
            s[i][j] = Max(s[i][j], Min(s[i ^ (1 << j)][k], d1[k][j]));
}
int main() {
  rd(n), rd(m);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) rd(a[i][j]);
  memset(d1, 0x3f, sizeof(d1));
  memset(d2, 0x3f, sizeof(d2));
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j) {
      for (int k = 0; k < m; ++k)
        d1[i][j] = Min(d1[i][j], Abs(a[i][k] - a[j][k]));
      for (int k = 1; k < m; ++k)
        d2[i][j] = Min(d2[i][j], Abs(a[i][k - 1] - a[j][k]));
    }
  for (int i = 0; i < n; ++i) {
    Hamilton(i);
    for (int j = 0; j < n; ++j)
      ans = Max(ans, Min(s[(1 << n) - 1][j], d2[j][i]));
  }
  print(ans);
  return 0;
}
