#include <bits/stdc++.h>
using namespace std;
template <typename T>
void mymax(T &_a, T _b) {
  if (_a < _b) _a = _b;
}
template <typename T>
void mymin(T &_a, T _b) {
  if (_a > _b) _a = _b;
}
void print(int _x) { printf("%d\n", _x); }
template <typename T>
void print(T _data[], int _size) {
  for (int i = 1; i <= _size; i++) cout << _data[i] << " ";
  cout << endl;
}
int n, m, k;
pair<int, int> dot[510];
struct Seg {
  int l, r, h, dir;
  Seg() {}
  Seg(int li, int ri, int hi, int diri) {
    l = li;
    r = ri;
    h = hi;
    dir = diri;
  }
};
bool operator<(Seg s1, Seg s2) { return s1.h < s2.h; }
vector<int> useful;
vector<Seg> seg;
int add[2010];
bool check(int r) {
  int d = r << 1 | 1;
  bool err = 0;
  for (int dir = 0; dir <= 1; dir++) {
    seg.clear();
    useful.clear();
    useful.push_back(1);
    useful.push_back(m);
    for (int i = 1; i <= k; i++) {
      int leftmost, rightmost, upper, lower;
      leftmost = max(1, dot[i].first - r);
      rightmost = min(m, dot[i].first + r);
      upper = min(n + 1, dot[i].second + r + 1);
      lower = max(1, dot[i].second - r);
      useful.push_back(leftmost);
      useful.push_back(rightmost);
      if (leftmost - 1 >= 1) useful.push_back(leftmost - 1);
      if (rightmost + 1 <= m) useful.push_back(rightmost + 1);
      seg.push_back(Seg(leftmost, rightmost, upper, -1));
      seg.push_back(Seg(leftmost, rightmost, lower, 1));
    }
    sort(useful.begin(), useful.end());
    useful.resize(unique(useful.begin(), useful.end()) - useful.begin());
    int usecnt = useful.size();
    for (int i = 0; i < (k << 1); i++) {
      seg[i].l =
          lower_bound(useful.begin(), useful.end(), seg[i].l) - useful.begin();
      seg[i].r =
          lower_bound(useful.begin(), useful.end(), seg[i].r) - useful.begin();
    }
    sort(seg.begin(), seg.end());
    memset(add, 0, sizeof(add));
    int maxx = useful[0];
    int minx = useful[usecnt - 1];
    pair<int, int> nowsel;
    nowsel.first = nowsel.second = 0;
    int maxh = 0;
    while (max(nowsel.first, nowsel.second) < (k << 1) &&
           seg[nowsel.first].h <= m) {
      while (nowsel.second < (k << 1) &&
             seg[nowsel.second].h == seg[nowsel.first].h)
        nowsel.second++;
      nowsel.second--;
      if (seg[nowsel.second].h > n) break;
      for (int i = nowsel.first; i <= nowsel.second; i++)
        for (int j = seg[i].l; j <= seg[i].r; j++) add[j] += seg[i].dir;
      for (int i = 0; i < usecnt; i++)
        if (!add[i]) {
          mymin(minx, useful[i]);
          mymax(maxx, useful[i]);
        }
      maxh = seg[nowsel.second].h;
      nowsel.second++;
      nowsel.first = nowsel.second;
    }
    if (maxx - minx + 1 > d) {
      err = 1;
    }
    if (maxh < n && seg[seg.size() - 1].h < n) {
      if (m > d) {
        err = 1;
      }
    }
    if (seg[0].h > 1) {
      if (m > d) {
        err = 1;
      }
    }
    swap(n, m);
    for (int i = 1; i <= k; i++) swap(dot[i].first, dot[i].second);
  }
  return err ^ 1;
}
int main() {
  scanf("%d %d %d", &m, &n, &k);
  for (int i = 1; i <= k; i++) {
    scanf("%d %d", &dot[i].first, &dot[i].second);
  }
  int l = 0, r = max(n, m);
  while (l < r) {
    int mid = (l + r) >> 1;
    if (check(mid)) {
      r = mid;
    } else {
      l = mid + 1;
    }
  }
  printf("%d\n", l);
  return 0;
}
