#include <bits/stdc++.h>
using namespace std;
int tableau[1005][1005];
vector<int> access[1005];
int nbOn[1005];
int rows;
int cols;
bool canGetTo(int limit) {
  for (int i = 0; i <= cols; i++) {
    access[i].clear();
  }
  for (int i = 0; i < rows; i++) {
    fill_n(nbOn, i, 0);
    for (int j = 0; j < cols; j++) {
      if (tableau[i][j] < limit) continue;
      for (int& val : access[j]) {
        if (nbOn[val] != 0) {
          return true;
        }
        nbOn[val]++;
      }
      access[j].push_back(i);
    }
  }
  return false;
}
int getBest(int start, int end) {
  if (start == end) {
    return start;
  }
  int mid = (start + end + 1) / 2;
  if (canGetTo(mid)) {
    return getBest(mid, end);
  } else {
    return getBest(start, mid - 1);
  }
}
int main() {
  scanf("%d%d", &rows, &cols);
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      scanf("%d", &tableau[i][j]);
    }
  }
  int res = getBest(0, 1 << 30);
  printf("%d\n", res);
  return 0;
}
