#include <bits/stdc++.h>
using namespace std;
struct xxx {
  int flag, x, ly, ry;
  bool operator<(const xxx &temp) const {
    if (x == temp.x) return flag < temp.flag;
    return x < temp.x;
  }
};
xxx xx[1220000];
int cnt_x, ar[1220000];
struct segment_tree {
  int l, r, max[2];
};
segment_tree tree[1000000];
const int inf = 1e9 + 9;
struct point {
  int x, y, id;
  bool operator<(const point &temp) const {
    if (x == temp.x) return y < temp.y;
    return x < temp.x;
  }
};
point per[110000], sub[110000], pt[220000];
int n, m, cnt, dist[110000], list_y[1220000], cnt_list, pu[110000];
bool cmp(int id1, int id2) { return dist[id1] > dist[id2]; }
void build(int left, int right, int id) {
  int l = 2 * id + 1, r = 2 * id + 2, mid = (left + right) >> 1;
  tree[id].l = list_y[left];
  tree[id].r = list_y[right];
  tree[id].max[0] = tree[id].max[1] = -inf;
  if (left == right) return;
  build(left, mid, l);
  build(mid + 1, right, r);
}
void update(int pos, int value, int ip, int id) {
  int l = 2 * id + 1, r = 2 * id + 2;
  tree[id].max[ip] = max(tree[id].max[ip], value);
  if (tree[id].l == tree[id].r) return;
  if (tree[l].r < pos)
    update(pos, value, ip, r);
  else
    update(pos, value, ip, l);
}
int query(int left, int right, int ip, int id) {
  int l = 2 * id + 1, r = 2 * id + 2;
  if (tree[id].l == left && tree[id].r == right) return tree[id].max[ip];
  if (tree[l].r < left) return query(left, right, ip, r);
  if (tree[r].l > right) return query(left, right, ip, l);
  return max(query(left, tree[l].r, ip, l), query(tree[r].l, right, ip, r));
}
int lower_bound(int list_y[], int cnt_list, int x) {
  int left = 0, right = cnt_list - 1, mid;
  while (left <= right) {
    mid = (left + right) >> 1;
    if (list_y[mid] < x)
      left = mid + 1;
    else
      right = mid - 1;
  }
  return left;
}
int lowbit(int x) { return x & (-x); }
bool check(int r) {
  int i, j, s, p, q, inx, iny, axx, axy, id, su;
  inx = iny = -inf;
  axx = axy = inf;
  cnt_x = 0;
  cnt_list = 0;
  for (int ii = 0; ii < n; ii++) {
    i = pu[ii];
    if (r - dist[i] >= 0) {
      xx[cnt_x].x = inx - (r - dist[i]);
      list_y[cnt_list++] = xx[cnt_x].ly = iny - (r - dist[i]);
      list_y[cnt_list++] = xx[cnt_x].ry = axy + (r - dist[i]);
      xx[cnt_x++].flag = -1;
      xx[cnt_x].x = axx + (r - dist[i]);
      xx[cnt_x].ly = iny - (r - dist[i]);
      xx[cnt_x].ry = axy + (r - dist[i]);
      xx[cnt_x++].flag = 1;
    }
    if (inx < (per[i].x - per[i].y - r)) inx = per[i].x - per[i].y - r;
    if (axx > (per[i].x - per[i].y + r)) axx = per[i].x - per[i].y + r;
    if (iny < (per[i].x + per[i].y - r)) iny = per[i].x + per[i].y - r;
    if (axy > per[i].x + per[i].y + r) axy = per[i].x + per[i].y + r;
    if (inx > axx || iny > axy) break;
  }
  if (inx <= axx && iny <= axy) return true;
  for (i = 0; i < m; i++) {
    xx[cnt_x].x = sub[i].x - sub[i].y;
    list_y[cnt_list++] = xx[cnt_x].ly = xx[cnt_x].ry = sub[i].x + sub[i].y;
    xx[cnt_x++].flag = 0;
  }
  sort(xx, xx + cnt_x);
  sort(list_y, list_y + cnt_list);
  int tn = 0;
  for (i = 0; i < cnt_list; i++) {
    if (tn == 0 || list_y[tn - 1] < list_y[i]) list_y[tn++] = list_y[i];
  }
  cnt_list = tn;
  for (i = 0; i <= cnt_list; i++) ar[i] = 0;
  for (i = 0; i < cnt_x; i++) {
    if (xx[i].flag == 0) {
      id = lower_bound(list_y, cnt_list, xx[i].ly) + 1;
      su = 0;
      for (; id > 0; id -= lowbit(id)) su += ar[id];
      if (su > 0) return true;
    } else {
      for (id = lower_bound(list_y, cnt_list, xx[i].ly) + 1; id <= cnt_list;
           id += lowbit(id))
        ar[id] -= xx[i].flag;
      for (id = lower_bound(list_y, cnt_list, xx[i].ry + 1) + 1; id <= cnt_list;
           id += lowbit(id))
        ar[id] += xx[i].flag;
    }
  }
  return false;
}
void get_nearest() {
  int i, j, s, p, q, tn, id, now;
  cnt_list = 0;
  for (i = 0; i < cnt; i++) list_y[cnt_list++] = pt[i].y;
  sort(list_y, list_y + cnt_list);
  tn = 0;
  for (i = 0; i < cnt_list; i++) {
    if (tn == 0 || list_y[tn - 1] < list_y[i]) list_y[tn++] = list_y[i];
  }
  cnt_list = tn;
  build(0, cnt_list - 1, 0);
  for (i = 0; i < cnt; i++) {
    if (pt[i].id >= 0) {
      now = query(list_y[0], pt[i].y, 0, 0);
      if (now > -inf && dist[pt[i].id] > pt[i].x + pt[i].y - now)
        dist[pt[i].id] = pt[i].x + pt[i].y - now;
      now = query(pt[i].y, list_y[cnt_list - 1], 1, 0);
      if (now > -inf && dist[pt[i].id] > pt[i].x - pt[i].y - now)
        dist[pt[i].id] = pt[i].x - pt[i].y - now;
    } else {
      update(pt[i].y, pt[i].x + pt[i].y, 0, 0);
      update(pt[i].y, pt[i].x - pt[i].y, 1, 0);
    }
  }
}
int main() {
  int i, j, s, p, q, low, high, mid;
  scanf("%d%d", &n, &m);
  for (i = 0; i < n; i++) scanf("%d%d", &per[i].x, &per[i].y);
  for (i = 0; i < m; i++) scanf("%d%d", &sub[i].x, &sub[i].y);
  cnt = 0;
  for (i = 0; i < n; i++) {
    pt[cnt] = per[i];
    pt[cnt++].id = i;
    dist[i] = inf;
  }
  for (i = 0; i < m; i++) {
    pt[cnt] = sub[i];
    pt[cnt++].id = -1;
  }
  sort(pt, pt + cnt);
  get_nearest();
  for (i = 0; i < cnt; i++) {
    pt[i].x = -pt[i].x;
    pt[i].y = -pt[i].y;
  }
  for (i = 0; i < cnt / 2; i++) swap(pt[i], pt[cnt - 1 - i]);
  get_nearest();
  for (i = 0; i < n; i++) pu[i] = i;
  sort(pu, pu + n, cmp);
  low = 0;
  high = inf;
  while (low <= high) {
    mid = (low + high) >> 1;
    if (check(mid))
      high = mid - 1;
    else
      low = mid + 1;
  }
  printf("%d\n", low);
  return 0;
}
