#include <bits/stdc++.h>
using namespace std;
pair<pair<int, int>, pair<int, int> > ans;
int n, m, k, t;
vector<pair<int, int> > fire;
vector<pair<int, int> > sweep;
set<pair<int, int> > vSweep;
pair<pair<int, int>, pair<int, int> > range(pair<int, int> p) {
  return pair<pair<int, int>, pair<int, int> >(
      pair<int, int>(max(0, p.first - t), min(n, p.first + t + 1)),
      pair<int, int>(max(0, p.second - t), min(m, p.second + t + 1)));
}
void updx(int xx) {
  ans.first =
      pair<int, int>(min(ans.first.first, xx), max(ans.first.second, xx));
}
void updy(int yy) {
  ans.second =
      pair<int, int>(min(ans.second.first, yy), max(ans.second.second, yy));
}
bool check() {
  int i, j;
  for (i = 0; i < k; i++) {
    auto xRange = range(fire[i]).first;
    sweep[2 * i] = pair<int, int>(xRange.first, 2 * i);
    sweep[2 * i + 1] = pair<int, int>(xRange.second, 2 * i + 1);
  }
  sort(sweep.begin(), sweep.end());
  ans = pair<pair<int, int>, pair<int, int> >(pair<int, int>(n, 0),
                                              pair<int, int>(m, 0));
  if (0 < sweep[0].first) updx(0), updx(sweep[0].first), updy(0), updy(m);
  vSweep.clear();
  set<pair<int, int> >::iterator it, jt;
  for (i = 0; i < 2 * k; i = j) {
    for (j = i; j < 2 * k && sweep[i].first == sweep[j].first; j++) {
      auto ind = sweep[j].second;
      auto yRange = range(fire[ind / 2]).second;
      if (ind & 1) {
        vSweep.erase(pair<int, int>(yRange.first, ind - 1));
        vSweep.erase(pair<int, int>(yRange.second, ind));
      } else {
        vSweep.insert(pair<int, int>(yRange.first, ind));
        vSweep.insert(pair<int, int>(yRange.second, ind + 1));
      }
    }
    int lx = sweep[i].first;
    int rx = j == 2 * k ? n : sweep[j].first;
    if (rx <= lx) continue;
    if (vSweep.empty()) {
      updx(lx), updx(rx), updy(0), updy(m);
      continue;
    }
    if (0 < vSweep.begin()->first)
      updx(lx), updx(rx), updy(0), updy(vSweep.begin()->first);
    int cnt = 0;
    for (it = vSweep.begin(); it != vSweep.end(); it = jt) {
      for (jt = it; jt != vSweep.end() && it->first == jt->first; jt++) {
        if (jt->second & 1)
          cnt--;
        else
          cnt++;
      }
      if (cnt == 0) {
        int ly = it->first;
        int ry = jt == vSweep.end() ? m : jt->first;
        if (ly < ry) updx(lx), updx(rx), updy(ly), updy(ry);
      }
    }
  }
  ans.first.second--, ans.second.second--;
  if (ans.first.first > ans.first.second ||
      ans.second.first > ans.second.second)
    return true;
  return max(ans.first.second - ans.first.first,
             ans.second.second - ans.second.first) <= 2 * t;
}
int main() {
  int i, s, e;
  scanf("%d %d %d", &n, &m, &k);
  fire = vector<pair<int, int> >(k);
  sweep = vector<pair<int, int> >(2 * k);
  for (i = 0; i < k; i++) {
    int xx, yy;
    scanf("%d %d", &xx, &yy);
    fire[i] = pair<int, int>(xx - 1, yy - 1);
  }
  sort(fire.begin(), fire.end());
  for (s = 0, e = max(n, m); s < e;) {
    t = (s + e) / 2;
    if (check())
      e = t;
    else
      s = t + 1;
  }
  printf("%d\n", s);
}
