#include <bits/stdc++.h>
using namespace std;
const int MAXK = 5e2 + 5;
const int TSIZE = (1 << 17);
int n, m, k;
int x[MAXK], y[MAXK];
void read_input() {
  cin >> n >> m >> k;
  for (int i = 0; i < k; i++) {
    cin >> y[i] >> x[i];
  }
}
struct ots {
  int l, r, x;
  bool type;
  ots(int _l, int _r, int _x, bool _type) {
    l = _l;
    r = _r;
    x = _x;
    type = _type;
  }
  bool operator<(ots other) const {
    return x < other.x || (x == other.x && type < other.type);
  }
};
int lazy[TSIZE], pnt[TSIZE];
void push(int nd, int l, int r) {
  if (lazy[nd]) {
    pnt[nd] += lazy[nd];
    if (l != r) {
      lazy[nd * 2] += lazy[nd];
      lazy[nd * 2 + 1] += lazy[nd];
    }
    lazy[nd] = 0;
  }
}
void update(int nd, int l, int r, int i, int j, int val) {
  push(nd, l, r);
  if (r < i || l > j || l > r) return;
  if (r <= j && l >= i) {
    pnt[nd] += val;
    if (l != r) {
      lazy[nd * 2] += val;
      lazy[nd * 2 + 1] += val;
    }
    return;
  }
  int middle = (l + r) >> 1;
  update(nd * 2, l, middle, i, j, val);
  update(nd * 2 + 1, middle + 1, r, i, j, val);
  pnt[nd] = min(pnt[nd * 2], pnt[nd * 2 + 1]);
}
const int INF = 1e9 + 5;
int check(int nd, int l, int r) {
  if (l > r) return INF;
  push(nd, l, r);
  if (l == r && pnt[nd] == 0) {
    return l;
  }
  int middle = (l + r) >> 1;
  int le = middle - l + 1;
  int ri = r - middle;
  if (l != r) {
    push(nd * 2, l, middle);
    push(nd * 2 + 1, middle + 1, r);
    if (pnt[nd * 2 + 1] == 0) {
      return check(nd * 2 + 1, middle + 1, r);
    }
    if (pnt[nd * 2] == 0) {
      return check(nd * 2, l, middle);
    }
  }
  return INF;
}
vector<int> cd;
int N;
map<int, int> mp, rev;
int get_ind(int v) { return mp[v]; }
pair<int, int> get_cord(vector<ots> v) {
  pair<int, int> cord = {INF, INF};
  for (int i = 0; i < v.size(); i++) {
    if (i == 0 && v[i].x != 1) {
      cord = {1, n};
      break;
    }
    if (v[i].type == 0) {
      update(1, 0, N, get_ind(v[i].r), get_ind(v[i].l), 1);
    } else {
      update(1, 0, N, get_ind(v[i].r), get_ind(v[i].l), -1);
    }
    if (i + 1 != v.size() && v[i + 1].x != v[i].x) {
      int temp = check(1, 0, N);
      if (temp != INF) {
        cord = {v[i].x, rev[temp]};
        break;
      }
    }
  }
  return cord;
}
bool check(int t) {
  vector<ots> v;
  for (int i = 0; i < TSIZE; i++) {
    lazy[i] = pnt[i] = 0;
  }
  cd.clear();
  for (int i = 0; i < k; i++) {
    v.push_back(ots(min(n, y[i] + t), max(1, y[i] - t), max(1, x[i] - t), 0));
    v.push_back(
        ots(min(n, y[i] + t), max(1, y[i] - t), min(m, x[i] + t) + 1, 1));
    cd.push_back(min(n, y[i] + t));
    cd.push_back(max(1, y[i] - t));
    cd.push_back(max(2, y[i] - t) - 1);
    cd.push_back(min(n - 1, y[i] + t) + 1);
  }
  cd.push_back(n);
  sort(cd.begin(), cd.end());
  auto X = unique(cd.begin(), cd.end());
  cd.resize(distance(cd.begin(), X));
  N = cd.size() - 1;
  for (int i = 0; i < cd.size(); i++) {
    mp[cd[i]] = i;
    rev[i] = cd[i];
  }
  sort(v.begin(), v.end());
  pair<int, int> cord = get_cord(v);
  if (cord.first == INF) {
    return true;
  }
  for (int i = 0; i < TSIZE; i++) {
    lazy[i] = pnt[i] = 0;
  }
  cord.first += t;
  cord.second -= t;
  cord.first = min(cord.first, m);
  cord.second = max(cord.second, 1);
  v.push_back(ots(min(n, cord.second + t), max(1, cord.second - t),
                  max(1, cord.first - t), 0));
  v.push_back(ots(min(n, cord.second + t), max(1, cord.second - t),
                  min(m, cord.first + t) + 1, 1));
  cd.push_back(min(n, cord.second + t));
  cd.push_back(max(1, cord.second - t));
  cd.push_back(max(2, cord.second - t) - 1);
  cd.push_back(min(n - 1, cord.second + t) + 1);
  sort(cd.begin(), cd.end());
  X = unique(cd.begin(), cd.end());
  cd.resize(distance(cd.begin(), X));
  N = cd.size() - 1;
  mp.clear();
  rev.clear();
  for (int i = 0; i < cd.size(); i++) {
    mp[cd[i]] = i;
    rev[i] = cd[i];
  }
  sort(v.begin(), v.end());
  cord = get_cord(v);
  if (cord.first == INF) {
    return true;
  }
  return false;
}
void solve() {
  int l = 0, r = max(n, m);
  int ans = r;
  while (l <= r) {
    int middle = (l + r) >> 1;
    if (check(middle)) {
      ans = middle;
      r = middle - 1;
    } else {
      l = middle + 1;
    }
  }
  cout << ans << "\n";
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  read_input();
  solve();
  return 0;
}
