#include <bits/stdc++.h>
using namespace std;
int n, m, k;
vector<pair<int, int>> coords;
struct LazySegmentTree {
  int s, e;
  long long val = 0, lazy = 0;
  LazySegmentTree *lChild, *rChild;
  LazySegmentTree(int sz) {
    this->s = 0;
    this->e = sz;
    lChild = NULL, rChild = NULL;
  }
  LazySegmentTree(int s, int e) {
    this->s = s;
    this->e = e;
    lChild = NULL, rChild = NULL;
  }
  void update(int l, int r, long long v) {
    if (l == s && r == e) {
      val += v;
      lazy += v;
      return;
    }
    int mid = (s + e) >> 1;
    if (lazy != 0) {
      if (lChild == NULL) lChild = new LazySegmentTree(s, mid);
      if (rChild == NULL) rChild = new LazySegmentTree(mid, e);
      lChild->val += lazy;
      rChild->val += lazy;
      lChild->lazy += lazy;
      rChild->lazy += lazy;
      lazy = 0;
    }
    if (l < mid) {
      if (lChild == NULL) lChild = new LazySegmentTree(s, mid);
      lChild->update(l, min(r, mid), v);
    }
    if (r > mid) {
      if (rChild == NULL) rChild = new LazySegmentTree(mid, e);
      rChild->update(max(l, mid), r, v);
    }
    if (lChild != NULL && rChild != NULL)
      val = min(lChild->val, rChild->val);
    else
      val = 0;
  }
  long long query(int l, int r) {
    if (l == s && r == e) return val;
    int mid = (s + e) >> 1;
    if (lazy != 0) {
      if (lChild == NULL) lChild = new LazySegmentTree(s, mid);
      if (rChild == NULL) rChild = new LazySegmentTree(mid, e);
      lChild->val += lazy;
      rChild->val += lazy;
      lChild->lazy += lazy;
      rChild->lazy += lazy;
      lazy = 0;
    }
    long long leftVal = -1, rightVal = -1;
    if (l < mid) {
      if (lChild != NULL)
        leftVal = lChild->query(l, min(mid, r));
      else
        leftVal = 0;
    }
    if (r > mid) {
      if (rChild != NULL)
        rightVal = rChild->query(max(mid, l), r);
      else
        rightVal = 0;
    }
    if (r <= mid) return leftVal;
    if (l >= mid) return rightVal;
    return min(leftVal, rightVal);
  }
};
pair<int, int> getBounds(int t) {
  pair<int, int> res = make_pair(n, -1);
  set<int> yVals;
  yVals.insert(0);
  yVals.insert(m - 1);
  vector<tuple<int, int, int, int>> toProccess;
  toProccess.push_back(make_tuple(0, 0, 0, 0));
  toProccess.push_back(make_tuple(n - 1, 0, 0, 0));
  for (int i = 0; i < (k); i++) {
    int frontEnd = max(0, coords[i].first - t);
    int backEnd = min(n - 1, coords[i].first + t);
    int bottomEnd = max(0, coords[i].second - t);
    int topEnd = min(m - 1, coords[i].second + t);
    yVals.insert(bottomEnd);
    yVals.insert(topEnd);
    if (topEnd < m - 1) yVals.insert(topEnd + 1);
    if (bottomEnd > 0) yVals.insert(bottomEnd - 1);
    toProccess.push_back(make_tuple(frontEnd, 1, bottomEnd, topEnd));
    if (frontEnd > 0)
      toProccess.push_back(make_tuple(frontEnd - 1, 0, bottomEnd, topEnd));
    if (backEnd < n - 1)
      toProccess.push_back(make_tuple(backEnd + 1, -1, bottomEnd, topEnd));
  }
  unordered_map<int, int> compY;
  int currCompY = 0;
  for (const int i : yVals) compY[i] = currCompY++;
  LazySegmentTree st(currCompY);
  sort(toProccess.begin(), toProccess.end());
  int i = 0;
  while (i < toProccess.size()) {
    int x = get<0>(toProccess[i]);
    while (i < toProccess.size() && get<0>(toProccess[i]) == x) {
      int change = get<1>(toProccess[i]);
      int loY = compY[get<2>(toProccess[i])];
      int hiY = compY[get<3>(toProccess[i])];
      st.update(loY, hiY + 1, change);
      i++;
    }
    if (st.query(0, currCompY) == 0) {
      res.first = min(res.first, x);
      res.second = max(res.second, x);
    }
  }
  return res;
}
bool works(int t) {
  pair<int, int> lr = getBounds(t);
  for (int i = 0; i < (coords.size()); i++)
    swap(coords[i].first, coords[i].second);
  swap(n, m);
  pair<int, int> ud = getBounds(t);
  for (int i = 0; i < (coords.size()); i++)
    swap(coords[i].first, coords[i].second);
  swap(n, m);
  return (lr.second - lr.first <= 2 * t) && (ud.second - ud.first <= 2 * t);
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m >> k;
  for (int i = 0; i < (k); i++) {
    int x, y;
    cin >> x >> y;
    coords.push_back(make_pair(--x, --y));
  }
  int lo = 0;
  int hi = 1000000000;
  while (lo < hi) {
    int mid = (lo + hi) >> 1;
    if (works(mid))
      hi = mid;
    else
      lo = mid + 1;
  }
  cout << lo << endl;
  return 0;
}
