#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, m, k, blx[N], bly[N], q, fg[N], is[N], hx[N], t;
struct Q {
  int x, l, r, o;
  bool operator<(const Q &rhs) const { return x < rhs.x; }
} p[N];
void Modify(int x, int l, int r, int ql, int qr, int t) {
  if (l == ql && r == qr)
    return void(
        (fg[x] += t, is[x] = fg[x] ? 1 : is[(x << 1)] & is[(x << 1 | 1)]));
  int mid = (l + r) >> 1;
  if (qr <= mid)
    Modify((x << 1), l, mid, ql, qr, t);
  else if (ql > mid)
    Modify((x << 1 | 1), mid + 1, r, ql, qr, t);
  else
    Modify((x << 1), l, mid, ql, mid, t),
        Modify((x << 1 | 1), mid + 1, r, mid + 1, qr, t);
  is[x] = fg[x] ? 1 : is[(x << 1)] & is[(x << 1 | 1)];
}
int Solve(int n) {
  memset(is, 0, sizeof is);
  memset(fg, 0, sizeof fg);
  t = 0;
  for (int i = 1; i <= q; ++i) {
    hx[++t] = p[i].l, hx[++t] = p[i].r;
    if (p[i].l > 1) hx[++t] = p[i].l - 1;
    if (p[i].r > 1) hx[++t] = p[i].r - 1;
    if (p[i].l < n) hx[++t] = p[i].l + 1;
    if (p[i].r < n) hx[++t] = p[i].r + 1;
  }
  sort(hx + 1, hx + t + 1);
  t = unique(hx + 1, hx + t + 1) - hx - 1;
  for (int i = 1; i <= q; ++i) {
    p[i].l = lower_bound(hx + 1, hx + t + 1, p[i].l) - hx;
    p[i].r = lower_bound(hx + 1, hx + t + 1, p[i].r) - hx;
    Modify(1, 1, t, p[i].l, p[i].r, p[i].o);
    if ((i == q || p[i].x != p[i + 1].x) && !is[1]) return p[i].x;
  }
  return -1;
}
bool Judge(int d) {
  int left, right, up, down;
  q = 0;
  for (int i = 1, a, b; i < k; ++i) {
    a = max(1, bly[i] - d);
    b = min(m, bly[i] + d);
    p[++q] = Q{max(blx[i] - d, 1), a, b, 1};
    if (blx[i] + d + 1 <= n) p[++q] = Q{blx[i] + d + 1, a, b, -1};
  }
  sort(p + 1, p + q + 1);
  down = p[1].x == 1 ? Solve(m) : 1;
  if (down == -1) return 1;
  q = 0;
  for (int i = 1, a, b; i < k; ++i) {
    a = max(1, bly[i] - d);
    b = min(m, bly[i] + d);
    p[++q] = Q{min(n, blx[i] + d), a, b, 1};
    if (blx[i] - d - 1 > 0) p[++q] = Q{blx[i] - d - 1, a, b, -1};
  }
  sort(p + 1, p + q + 1);
  reverse(p + 1, p + q + 1);
  up = p[1].x == n ? Solve(m) : n;
  q = 0;
  for (int i = 1, a, b; i < k; ++i) {
    a = max(1, blx[i] - d);
    b = min(n, blx[i] + d);
    p[++q] = Q{max(bly[i] - d, 1), a, b, 1};
    if (bly[i] + d + 1 <= m) p[++q] = Q{bly[i] + d + 1, a, b, -1};
  }
  sort(p + 1, p + q + 1);
  left = p[1].x == 1 ? Solve(n) : 1;
  q = 0;
  for (int i = 1, a, b; i < k; ++i) {
    a = max(1, blx[i] - d);
    b = min(n, blx[i] + d);
    p[++q] = Q{min(bly[i] + d, m), a, b, 1};
    if (bly[i] - d - 1 > 0) p[++q] = Q{bly[i] - d - 1, a, b, -1};
  }
  sort(p + 1, p + q + 1);
  reverse(p + 1, p + q + 1);
  right = p[1].x == m ? Solve(n) : m;
  return right - left <= d * 2 && up - down <= d * 2;
}
void G(int &n) {
  static char a;
  for (a = getchar(); !isdigit(a); a = getchar())
    ;
  for (n = 0; isdigit(a); a = getchar()) n = (n << 3) + (n << 1) + a - '0';
}
int main() {
  G(n);
  G(m);
  G(k);
  ++k;
  for (int i = 1; i < k; ++i) G(blx[i]), G(bly[i]);
  int l = 0, r = max(n, m), mid;
  while (l <= r) {
    mid = (l + r) >> 1;
    if (Judge(mid))
      r = mid - 1;
    else
      l = mid + 1;
  }
  printf("%d\n", l);
  fclose(stdin);
  fclose(stdout);
  return 0;
}
