#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:124777216")
using namespace std;
int a[1010][1010];
vector<int> b;
int masks[1010][40];
int main() {
  srand(time(NULL));
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = (0); i < (n); ++i)
    for (int j = (0); j < (m); ++j) {
      scanf("%d", &a[i][j]);
      b.push_back(a[i][j]);
    }
  sort(b.begin(), b.end());
  b.resize(unique(b.begin(), b.end()) - b.begin());
  int l = 0, r = (int)b.size() - 1;
  int res = -1;
  while (l <= r) {
    int mid = (l + r) / 2;
    for (int i = (0); i < (n); ++i) {
      int num = 0;
      int now = 0;
      masks[i][0] = 0;
      for (int j = (0); j < (m); ++j) {
        if ((a[i][j] >= b[mid])) {
          masks[i][now] |= (1 << num);
        }
        num++;
        if (num == 30) {
          num = 0;
          now++;
          masks[i][now] = 0;
        }
      }
    }
    int tot = (m + 29) / 30;
    bool f = false;
    for (int i = (0); i < (n); ++i) {
      if (f) break;
      for (int j = (i + 1); j < (n); ++j) {
        if (f) break;
        int cnt = 0;
        for (int k = (0); k < (tot); ++k) {
          int v = (masks[i][k] & masks[j][k]);
          if (v)
            for (int q = (0); q < (30); ++q) {
              if ((v >> q) & 1) {
                cnt++;
              }
              if (cnt >= 2) break;
            }
          if (cnt >= 2) {
            f = true;
            break;
          }
        }
      }
    }
    if (f) {
      res = b[mid];
      l = mid + 1;
    } else
      r = mid - 1;
  }
  cout << res << endl;
  return 0;
}
