#include <bits/stdc++.h>
using namespace std;
const int oo = 1047483647, maxn = 100100, L = 1000000000;
struct node {
  int n, tr[(1 << 18) * 2 + 10];
  void clean() { memset(tr, 63, sizeof tr); }
  void upd(int x, int v) {
    x += n;
    tr[x] = min(tr[x], v);
    for (; x = x / 2;) tr[x] = min(tr[x * 2], tr[x * 2 + 1]);
  }
  int ask(int l, int r) {
    int ans = 2 * L;
    for (l += n, r += n; l <= r; l = (l + 1) / 2, r = (r - 1) / 2) {
      if (l & 1) ans = min(ans, tr[l]);
      if (~r & 1) ans = min(ans, tr[r]);
    }
    return ans;
  }
} t1, t2;
pair<int, int> a[maxn * 2], b[maxn * 2], ord[3 * maxn];
pair<pair<int, int>, int> q[3 * maxn];
pair<pair<int, int>, pair<int, int> > rec[3 * maxn];
pair<int, pair<int, int> > sd[maxn * 3];
pair<int, int> ww[maxn * 3];
int ny[maxn * 3], l, near[maxn * 3], ge, w[maxn * 3], n, m, f[maxn * 3], tot;
bool cmp(const pair<pair<int, int>, int> &a,
         const pair<pair<int, int>, int> &b) {
  return ((a.first.first < b.first.first) ||
          (a.first.first == b.first.first) && (a.second < b.second));
}
bool checksimple(int d) {
  int x1, y1, x2, y2;
  x1 = y1 = -2 * L, x2 = y2 = 2 * L;
  for (int i = 1; i <= n; i++) {
    x1 = max(a[i].first - d, x1);
    x2 = min(a[i].first + d, x2);
    y1 = max(a[i].second - d, y1);
    y2 = min(a[i].second + d, y2);
    if (x1 > x2 || y1 > y2) return 0;
  }
  return 1;
}
int simple() {
  int l = 0, r = 2 * L, mid;
  while (l < r) {
    mid = (l + r) / 2;
    if (checksimple(mid))
      r = mid;
    else
      l = mid + 1;
  }
  return l;
}
void work() {
  sort(q + 1, q + l + 1, cmp);
  t1.n = t2.n = 1 << 18;
  t1.clean();
  t2.clean();
  for (int i = 1; i <= l; i++)
    w[i] = lower_bound(ny + 1, ny + ge + 1, q[i].first.second) - ny;
  for (int i = 1; i <= l; i++) {
    if (q[i].second == -1) {
      t1.upd(w[i], -q[i].first.first + q[i].first.second);
      t2.upd(w[i], -q[i].first.first - q[i].first.second);
    } else {
      int v1 = t1.ask(w[i], ge) + q[i].first.first - q[i].first.second;
      int v2 = t2.ask(1, w[i]) + q[i].first.first + q[i].first.second;
      near[q[i].second] = min(near[q[i].second], min(v1, v2));
    }
  }
}
void findclose() {
  l = 0;
  memset(near, 63, sizeof near);
  for (int i = 1; i <= n; i++) q[++l] = make_pair(a[i], i);
  for (int i = 1; i <= m; i++) q[++l] = make_pair(b[i], -1);
  for (int i = 1; i <= l; i++) ny[i] = q[i].first.second;
  sort(ny + 1, ny + 1 + l);
  ge = unique(ny + 1, ny + l + 1) - (ny + 1);
  work();
  for (int i = 1; i <= l; i++) q[i].first.first = -q[i].first.first;
  work();
}
pair<int, int> huan(pair<int, int> &t) {
  return make_pair(t.first + t.second, t.first - t.second);
}
int sum(int k) {
  int ans = 0;
  for (; k > 0; k -= k & (-k)) ans += f[k];
  return ans;
}
void add(int k, int v) {
  for (; k <= ge; k += k & (-k)) f[k] += v;
}
bool check(int k) {
  ge = 0;
  tot = 0;
  for (int i = 1; i <= k; i++) {
    ny[++ge] = rec[i].second.first;
    ny[++ge] = rec[i].second.second;
    sd[++tot] = make_pair(rec[i].first.first, make_pair(0, i));
    sd[++tot] = make_pair(rec[i].first.second, make_pair(2, i));
  }
  for (int i = 1; i <= m; i++) {
    ny[++ge] = b[i].second;
    sd[++tot] = make_pair(b[i].first, make_pair(1, i));
  }
  sort(ny + 1, ny + ge + 1);
  ge = unique(ny + 1, ny + ge + 1) - (ny + 1);
  sort(sd + 1, sd + tot + 1);
  for (int i = 1; i <= tot; i++) {
    int w1 = lower_bound(ny + 1, ny + ge + 1, rec[i].second.first) - ny;
    int w2 = lower_bound(ny + 1, ny + ge + 1, rec[i].second.second) - ny;
    ww[i] = make_pair(w1, w2);
  }
  memset(f, 0, sizeof f);
  for (int i = 1; i <= tot; i++) {
    int v = sd[i].second.second;
    if (sd[i].second.first == 1) {
      int w = lower_bound(ny + 1, ny + ge + 1, b[v].second) - ny;
      if (sum(w)) return 1;
    } else if (sd[i].second.first == 0) {
      add(ww[v].first, 1);
      add(ww[v].second + 1, -1);
    } else {
      add(ww[v].first, -1);
      add(ww[v].second + 1, +1);
    }
  }
  return 0;
}
bool checkhard(int d) {
  if (ord[1].first <= d)
    return 1;
  else if (ord[n].first > d)
    return 0;
  int x1, y1, x2, y2, k = 0;
  x1 = y1 = -2 * L, x2 = y2 = 2 * L;
  for (int i = 1; i <= n; i++) {
    if (x1 > x2 || y1 > y2) break;
    int v = ord[i].second;
    if (ord[i].first <= d) {
      int left = d - ord[i].first;
      rec[++k] = make_pair(make_pair(x1 - left, x2 + left),
                           make_pair(y1 - left, y2 + left));
    }
    x1 = max(a[v].first - d, x1);
    x2 = min(a[v].first + d, x2);
    y1 = max(a[v].second - d, y1);
    y2 = min(a[v].second + d, y2);
  }
  if (!k)
    return 0;
  else
    return check(k);
}
int hard() {
  for (int i = 1; i <= n; i++) ord[i] = make_pair(near[i], i);
  sort(ord + 1, ord + n + 1);
  reverse(ord + 1, ord + n + 1);
  int l = 0, r = 2 * L, mid;
  while (l < r) {
    mid = (l + r) / 2;
    if (checkhard(mid))
      r = mid;
    else
      l = mid + 1;
  }
  return l;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d%d", &a[i].first, &a[i].second);
  for (int i = 1; i <= m; i++) scanf("%d%d", &b[i].first, &b[i].second);
  if (m) findclose();
  for (int i = 1; i <= n; i++) a[i] = huan(a[i]);
  for (int i = 1; i <= m; i++) b[i] = huan(b[i]);
  int ans = simple();
  if (!m)
    printf("%d\n", ans);
  else {
    ans = min(hard(), ans);
    printf("%d\n", ans);
  }
  return 0;
}
