#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
const int M = 1e4 + 5;
int n, m;
int a[16][M];
bool ok_same[16][16];
bool ok_shift[16][16];
bool dp[1 << 16][16];
bool check(int k) {
// ok_same[x][y] = Với mọi i < m, |a[x][i] - a[y][i]| >= k
// ok_shift[x][y] = Với mọi i < m - 1, |a[x][i + 1] - a[y][i]| >= k
for (int x = 0; x < n; x++) {
for (int y = 0; y < n; y++) {
ok_same[x][y] = true;
ok_shift[x][y] = true;
for (int i = 0; i < m; i++) {
ok_same[x][y] &= (abs(a[x][i] - a[y][i]) >= k);
if (i + 1 < m) ok_shift[x][y] &= (abs(a[x][i + 1] - a[y][i]) >= k);
}
}
}
for (int first_row = 0; first_row < n; first_row++) {
// dp[mask][y] = 1 nếu tồn tại cách sắp xếp các hàng trong mask thoả ok_same
// cho mọi cặp hàng được xếp kề nhau,
// với hàng đầu tiên = first_row và hàng cuối cùng = y
for (int mask = 0; mask < (1 << n); mask++) {
for (int y = 0; y < n; y++) {
bool& cur = dp[mask][y];
if (mask == (1 << y) && y == first_row) {
cur = 1;
continue;
}
cur = 0;
if (!(mask & (1 << first_row))) continue;
if (!(mask & (1 << y))) continue;
for (int x = 0; x < n; x++) {
if (ok_same[x][y]) {
int prev_mask = mask ^ (1 << y);
cur |= dp[prev_mask][x];
}
}
}
}
for (int last_row = 0; last_row < n; last_row++) {
if (dp[(1 << n) - 1][last_row] && ok_shift[first_row][last_row]) return true;
}
}
return false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) cin >> a[i][j];
}
int l = 0, r = 1e9, ans = -1;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) {
ans = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
cout << ans << '\n';
}