#include <bits/stdc++.h>
using namespace std;
struct Eins {
  vector<pair<int, int>> mn;
  vector<pair<int, int>> mx;
  vector<int> lazy;
  int n;
  Eins(int n) : n(n) {
    mn.resize(n << 2 | 1);
    mx.resize(n << 2 | 1);
    lazy.resize(n << 2 | 1);
    build(1, 1, n);
  }
  void build(int id, int l, int r) {
    mn[id] = {0, l};
    mx[id] = {0, -r};
    if (l == r) return;
    int mid = l + r >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, r);
  }
  void update(int id, int val) {
    mn[id].first += val;
    mx[id].first += val;
    lazy[id] += val;
  }
  void down(int id) {
    if (!lazy[id]) return;
    update(id << 1, lazy[id]);
    update(id << 1 | 1, lazy[id]);
    lazy[id] = 0;
  }
  void update(int id, int l, int r, int L, int R, int val) {
    if (l > R || r < L) return;
    if (L <= l && r <= R) {
      update(id, val);
      return;
    }
    down(id);
    int mid = l + r >> 1;
    update(id << 1, l, mid, L, R, val);
    update(id << 1 | 1, mid + 1, r, L, R, val);
    mn[id] = min(mn[id << 1], mn[id << 1 | 1]);
    mx[id] = min(mx[id << 1], mx[id << 1 | 1]);
  }
  void update(int l, int r, int val) { update(1, 1, n, l, r, val); }
};
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m, k;
  cin >> n >> m >> k;
  vector<pair<int, int>> a(k);
  for (int i = 0; i < k; i++) cin >> a[i].first >> a[i].second;
  int l = 0, r = max(n, m);
  auto can = [&](int d) {
    vector<tuple<int, int, int, int>> fire;
    vector<int> X, Y;
    X.emplace_back(1);
    Y.emplace_back(1);
    X.emplace_back(n);
    Y.emplace_back(m);
    for (auto& x : a) {
      int lx = max(1, x.first - d);
      int ly = max(1, x.second - d);
      int rx = min(n, x.first + d);
      int ry = min(m, x.second + d);
      fire.emplace_back(lx, rx, ly, ry);
      X.emplace_back(lx);
      X.emplace_back(rx);
      X.emplace_back(max(1, lx - 1));
      X.emplace_back(min(n, rx + 1));
      Y.emplace_back(ly);
      Y.emplace_back(ry);
      Y.emplace_back(max(1, ly - 1));
      Y.emplace_back(min(m, ry + 1));
    }
    sort(X.begin(), X.end());
    sort(Y.begin(), Y.end());
    X.resize(unique(X.begin(), X.end()) - X.begin());
    Y.resize(unique(Y.begin(), Y.end()) - Y.begin());
    vector<vector<pair<int, int>>> pos((int)X.size());
    for (auto& x : fire) {
      int lx = lower_bound(X.begin(), X.end(), get<0>(x)) - X.begin();
      int rx = lower_bound(X.begin(), X.end(), get<1>(x)) - X.begin();
      int ly = lower_bound(Y.begin(), Y.end(), get<2>(x)) - Y.begin() + 1;
      int ry = lower_bound(Y.begin(), Y.end(), get<3>(x)) - Y.begin() + 1;
      pos[lx].emplace_back(ly, ry);
      if (X[rx] != X.back()) pos[rx + 1].emplace_back(-ly, ry);
    }
    Eins Tree((int)Y.size());
    int u, v, x, y;
    x = y = 0;
    u = (int)X.size();
    v = (int)Y.size();
    for (int i = 0; i < (int)X.size(); i++) {
      for (auto& x : pos[i])
        Tree.update(abs(x.first), x.second, x.first > 0 ? 1 : -1);
      pair<int, int> mn = Tree.mn[1], mx = Tree.mx[1];
      assert(mx.first == mn.first);
      if (!mn.first) {
        x = i;
        u = min(u, i);
        y = max(y, -mx.second);
        v = min(v, mn.second);
      }
    }
    if (u == (int)X.size()) return true;
    assert(u <= x && v <= y);
    return X[u] + d >= X[x] - d && Y[--v] + d >= Y[--y] - d;
  };
  while (l <= r) {
    int mid = l + r >> 1;
    if (can(mid))
      r = mid - 1;
    else
      l = mid + 1;
  }
  cout << l;
}
