#include <bits/stdc++.h>
using namespace std;
struct Line {
  int idx, l, r, add;
  Line(int _idx, int _l, int _r, int _add) {
    idx = _idx, l = _l, r = _r, add = _add;
  }
  bool operator<(const Line& rhs) const { return idx < rhs.idx; }
};
struct Node {
  Node *lch, *rch;
  int cover, sum;
  Node() {
    lch = rch = nullptr;
    cover = sum = 0;
  }
} * root, space[1000000], *ptr;
inline int getSum(Node* node) { return node == nullptr ? 0 : node->sum; }
void up(int l, int r, Node* node) {
  if (node->cover > 0) {
    node->sum = r - l + 1;
  } else {
    if (l == r)
      node->sum = 0;
    else
      node->sum = getSum(node->lch) + getSum(node->rch);
  }
}
void modify(int l, int r, int ql, int qr, int add, Node*& node) {
  if (node == nullptr) node = new (ptr++) Node();
  if (l == ql && r == qr) {
    node->cover += add;
    up(l, r, node);
  } else {
    int mid = (l + r) >> 1;
    if (qr <= mid)
      modify(l, mid, ql, qr, add, node->lch);
    else if (ql > mid)
      modify(mid + 1, r, ql, qr, add, node->rch);
    else {
      modify(l, mid, ql, mid, add, node->lch);
      modify(mid + 1, r, mid + 1, qr, add, node->rch);
    }
    up(l, r, node);
  }
}
int n, m, k;
vector<Line> line;
pair<int, int> pos[510];
int sweep_line(int lim, int lim2) {
  sort(line.begin(), line.end());
  if (line[0].idx > 1) return 1;
  root = nullptr;
  ptr = space;
  for (int i = 0; i < (int)line.size(); i++) {
    modify(1, lim2, line[i].l, line[i].r, line[i].add, root);
    if ((i == (int)line.size() - 1 || line[i + 1].idx != line[i].idx) &&
        line[i].idx <= lim) {
      if (getSum(root) != lim2) return line[i].idx;
    }
  }
  if (line[line.size() - 1].idx <= lim) return line[line.size() - 1].idx;
  return -1;
}
bool check(int t) {
  line.clear();
  for (int i = 1; i <= k; i++) {
    int x = max(pos[i].first - t, 1), x2 = min(pos[i].first + t, n);
    int y = max(pos[i].second - t, 1), y2 = min(pos[i].second + t, m);
    line.push_back(Line(x, y, y2, 1));
    line.push_back(Line(x2 + 1, y, y2, -1));
  }
  int minx = sweep_line(n, m);
  line.clear();
  for (int i = 1; i <= k; i++) {
    int x = max(pos[i].first - t, 1), x2 = min(pos[i].first + t, n);
    int y = max(pos[i].second - t, 1), y2 = min(pos[i].second + t, m);
    line.push_back(Line(y, x, x2, 1));
    line.push_back(Line(y2 + 1, x, x2, -1));
  }
  int miny = sweep_line(m, n);
  if (minx == -1 && miny == -1) return true;
  line.clear();
  for (int i = 1; i <= k; i++) {
    int x = max(pos[i].first - t, 1), x2 = min(pos[i].first + t, n);
    int y = max(pos[i].second - t, 1), y2 = min(pos[i].second + t, m);
    line.push_back(Line(x, y, y2, 1));
    line.push_back(Line(x2 + 1, y, y2, -1));
  }
  int x = minx, x2 = min((long long)n, (long long)x + 2 * t), y = miny,
      y2 = min((long long)m, (long long)y + 2 * t);
  line.push_back(Line(x, y, y2, 1));
  line.push_back(Line(x2 + 1, y, y2, -1));
  if (sweep_line(n, m) != -1) return false;
  return true;
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1; i <= k; i++) scanf("%d%d", &pos[i].first, &pos[i].second);
  int l = -1, r = max(n, m);
  while (r - l > 1) {
    int mid = (l + r) >> 1;
    if (check(mid))
      r = mid;
    else
      l = mid;
  }
  printf("%d\n", r);
  return 0;
}
