#include <bits/stdc++.h>
using namespace std;
const int MAXN = 120000;
const int inf = 1000000000;
struct sVector {
  int c[2];
};
struct sEvent {
  int t, tp, bot, top;
};
int n, m, tl;
int dst[MAXN], order[MAXN];
int tx[MAXN], ta[MAXN], tp[MAXN];
int sq[MAXN], sqz, sp[MAXN], spz;
sVector t[MAXN], pt[MAXN];
sVector recta[MAXN], rectb[MAXN];
int rv;
bool operator<(const sEvent &a, const sEvent &b) {
  return a.t < b.t || (a.t == b.t && a.tp < b.tp);
}
bool cmpp(const int a, const int b) { return dst[a] > dst[b]; }
inline int Dist(const sVector &a, const sVector &b) {
  return max(abs(a.c[0] - b.c[0]), abs(a.c[1] - b.c[1]));
}
void Add(int z, int x) {
  z += 1;
  for (; z < MAXN; z += z & (-z)) ta[z] += x;
}
int GetSum(int z) {
  z += 1;
  int sum = 0;
  for (; z; z -= z & (-z)) sum += ta[z];
  return sum;
}
sEvent eve[MAXN * 3];
bool FindPoints() {
  int ee = 0, bot, top, t1, t3;
  for (int i = 0; i < rv; i++) {
    if (sp[0] > rectb[i].c[0] || sp[spz - 1] < recta[i].c[0]) continue;
    bot = lower_bound(sq, sq + sqz, recta[i].c[1]) - sq;
    top = lower_bound(sq, sq + sqz, rectb[i].c[1]) - sq;
    if (sq[top] > rectb[i].c[1]) top--;
    if (bot > top) continue;
    t3 = lower_bound(sp, sp + spz, rectb[i].c[0]) - sp;
    if (sp[t3] > rectb[i].c[0]) t3--;
    t1 = lower_bound(sp, sp + spz, recta[i].c[0]) - sp;
    if (t1 > t3) continue;
    eve[ee].bot = bot;
    eve[ee].top = top;
    eve[ee].tp = 3;
    eve[ee].t = t3;
    ee++;
    eve[ee].bot = bot;
    eve[ee].top = top;
    eve[ee].tp = 1;
    eve[ee].t = t1;
    ee++;
  }
  for (int i = 0; i < m; i++) {
    eve[ee].bot = lower_bound(sq, sq + sqz, t[i].c[1]) - sq;
    eve[ee].tp = 2;
    eve[ee].t = tx[i];
    ee++;
  }
  sort(eve, eve + ee);
  memset(ta, 0, sizeof(ta));
  for (int i = 0; i < ee; i++) switch (eve[i].tp) {
      case 1:
        Add(eve[i].bot, 1);
        Add(eve[i].top + 1, -1);
        break;
      case 2:
        if (GetSum(eve[i].bot) > 0) return true;
        break;
      case 3:
        Add(eve[i].bot, -1);
        Add(eve[i].top + 1, 1);
        break;
    }
  return false;
}
int rmq[2][(1 << 19) + 2];
inline void Update(int rr, int x, int val) {
  int n = 1 << 18;
  x += n;
  rmq[rr][x] = min(rmq[rr][x], val);
  for (; x /= 2;) rmq[rr][x] = min(rmq[rr][x * 2], rmq[rr][x * 2 + 1]);
}
inline int GetMin(int rr, int l, int r) {
  int n = 1 << 18;
  int ans = inf;
  for (l += n, r += n; l <= r; l = (l + 1) / 2, r = (r - 1) / 2) {
    if (l & 1) ans = min(ans, rmq[rr][l]);
    if (~r & 1) ans = min(ans, rmq[rr][r]);
  }
  return ans;
}
struct sSNode {
  sVector p;
  int id;
  sSNode(){};
  sSNode(sVector pp, int iid) : p(pp), id(iid){};
};
bool cmp1(const sSNode &a, const sSNode &b) {
  if (a.p.c[0] != b.p.c[0]) return a.p.c[0] < b.p.c[0];
  if (a.id != b.id) return a.id < b.id;
  return a.p.c[1] < b.p.c[1];
}
int ssp[MAXN * 3];
void FindNearest(vector<sSNode> &q) {
  sort(q.begin(), q.end(), cmp1);
  int mn = 0;
  for (int i = 0; i < q.size(); i++) ssp[mn++] = q[i].p.c[1];
  sort(ssp, ssp + mn);
  mn = unique(ssp, ssp + mn) - ssp;
  memset(rmq, 0x7f, sizeof(rmq));
  for (int i = 0; i < q.size(); i++) {
    int cc = lower_bound(ssp, ssp + mn, q[i].p.c[1]) - ssp;
    if (q[i].id < 0) {
      Update(0, cc, -q[i].p.c[0] - q[i].p.c[1]);
      Update(1, cc, -q[i].p.c[0] + q[i].p.c[1]);
    } else {
      dst[q[i].id] =
          min(dst[q[i].id], GetMin(0, 0, cc) + q[i].p.c[0] + q[i].p.c[1]);
      dst[q[i].id] =
          min(dst[q[i].id], GetMin(1, cc, mn - 1) + q[i].p.c[0] - q[i].p.c[1]);
    }
  }
}
vector<sSNode> vsd;
void FindNearest() {
  vsd.clear();
  for (int i = 0; i < n; i++) vsd.push_back(sSNode(pt[i], i));
  for (int i = 0; i < m; i++) vsd.push_back(sSNode(t[i], -1));
  FindNearest(vsd);
  for (int i = 0; i < vsd.size(); i++) {
    vsd[i].p.c[0] = -vsd[i].p.c[0];
    vsd[i].p.c[1] = -vsd[i].p.c[1];
  }
  FindNearest(vsd);
}
bool Check(int dd) {
  if (dd >= dst[order[0]]) return true;
  int nn[2], mm[2], i;
  nn[0] = nn[1] = -inf;
  mm[0] = mm[1] = inf;
  sVector aa, bb;
  aa.c[0] = aa.c[1] = inf;
  bb.c[0] = bb.c[1] = -inf;
  rv = 0;
  for (int k = 0, z; k < n; k++) {
    if (nn[0] > mm[0] || nn[1] > mm[1]) break;
    z = order[k];
    if (dst[z] <= dd) {
      int outd = dd - dst[z];
      aa.c[0] = nn[0] - outd;
      aa.c[1] = nn[1] - outd;
      bb.c[0] = mm[0] + outd;
      bb.c[1] = mm[1] + outd;
      recta[rv] = aa;
      rectb[rv++] = bb;
    }
    for (i = 0; i < 2; i++) {
      nn[i] = max(nn[i], pt[z].c[i] - dd);
      mm[i] = min(mm[i], pt[z].c[i] + dd);
    }
  }
  if (nn[0] <= mm[0] && nn[1] <= mm[1]) return true;
  if (m && FindPoints()) return true;
  return false;
}
int Work() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) scanf("%d%d", &pt[i].c[0], &pt[i].c[1]);
  for (int i = 0; i < m; i++) scanf("%d%d", &t[i].c[0], &t[i].c[1]);
  if (n == 1) return 0;
  memset(dst, 0x7f, sizeof(dst));
  if (m) FindNearest();
  for (int i = 0; i < n; i++) order[i] = i;
  sort(order, order + n, cmpp);
  for (int i = 0, x, y; i < n; i++) {
    x = pt[i].c[0];
    y = pt[i].c[1];
    pt[i].c[0] = x + y;
    pt[i].c[1] = x - y;
  }
  for (int i = 0, x, y; i < m; i++) {
    x = t[i].c[0];
    y = t[i].c[1];
    t[i].c[0] = x + y;
    t[i].c[1] = x - y;
  }
  sqz = spz = 0;
  sq[sqz++] = -inf;
  sq[sqz++] = inf;
  sp[spz++] = -inf;
  sp[spz++] = inf;
  for (int i = 0; i < m; i++) {
    sp[spz++] = t[i].c[0];
    sq[sqz++] = t[i].c[1];
  }
  sort(sp, sp + spz);
  sort(sq, sq + sqz);
  spz = unique(sp, sp + spz) - sp;
  sqz = unique(sq, sq + sqz) - sq;
  for (int i = 0; i < m; i++) tx[i] = lower_bound(sp, sp + spz, t[i].c[0]) - sp;
  int ll = 0, rr = dst[order[0]], mid;
  while (ll < rr) {
    mid = (ll + rr) >> 1;
    if (Check(mid))
      rr = mid;
    else
      ll = mid + 1;
  }
  return rr;
}
int main() {
  printf("%d\n", Work());
  return 0;
}
