#include <bits/stdc++.h>
using namespace std;
const long long INFLL = 1e18;
class fenv_tree {
  vector<long long> xs;
  vector<pair<long long, int> > tr;
  static int f(int x) { return x ^ (x & (x - 1)); }

 public:
  fenv_tree(const vector<long long> &_xs)
      : xs(_xs), tr(((int)(xs).size()) + 1, make_pair(INFLL, -1)) {}
  void relax(long long x, const pair<long long, int> &val) {
    x = lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    x++;
    assert(0 < x && x < ((int)(tr).size()));
    for (; x > 0; x -= f(x)) tr[x] = min(tr[x], val);
  }
  pair<long long, int> get(long long x) {
    x = lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    x++;
    assert(0 <= x && x < ((int)(tr).size()));
    pair<long long, int> res(INFLL, -1);
    for (; x < ((int)(tr).size()); x += f(x)) res = min(res, tr[x]);
    return res;
  }
};
struct pt {
  long long x, y;
  pt(long long _x = 0, long long _y = 0) : x(_x), y(_y) {}
  bool operator<(const pt &p2) const { return y != p2.y ? y < p2.y : x < p2.x; }
};
class segm_tree2 {
  vector<vector<long long> > tr;
  int off;
  vector<long long> ys;
  bool get(const vector<long long> &t, long long x1, long long x2) {
    int i = lower_bound(t.begin(), t.end(), x1) - t.begin();
    return i < ((int)(t).size()) && t[i] <= x2;
  }

 public:
  segm_tree2() {}
  segm_tree2(const vector<pt> &pts) : ys(((int)(pts).size())) {
    for (int i = 0; i < ((int)(pts).size()); i++) ys[i] = pts[i].y;
    ys.erase(unique(ys.begin(), ys.end()), ys.end());
    off = 1;
    while (off <= ((int)(ys).size())) off <<= 1;
    tr = vector<vector<long long> >(2 * off);
    for (int i = 0; i < ((int)(pts).size()); i++) {
      int v = lower_bound(ys.begin(), ys.end(), pts[i].y) - ys.begin();
      tr[off + v].push_back(pts[i].x);
    }
    for (int i = off; i < ((int)(tr).size()); i++) {
      sort(tr[i].begin(), tr[i].end());
      tr[i].erase(unique(tr[i].begin(), tr[i].end()), tr[i].end());
    }
    for (int i = off - 1; i >= 1; i--) {
      const vector<long long> &l = tr[2 * i], &r = tr[2 * i + 1];
      tr[i].resize(((int)(l).size()) + ((int)(r).size()));
      merge(l.begin(), l.end(), r.begin(), r.end(), tr[i].begin());
      tr[i].erase(unique(tr[i].begin(), tr[i].end()), tr[i].end());
    }
  }
  bool get(long long x1, long long x2, long long y1, long long y2) {
    y1 = lower_bound(ys.begin(), ys.end(), y1) - ys.begin();
    y2 = upper_bound(ys.begin(), ys.end(), y2) - ys.begin() - 1;
    y1 += off;
    y2 += off;
    while (y1 <= y2) {
      if (y1 & 1)
        if (get(tr[y1++], x1, x2)) return true;
      if (!(y2 & 1))
        if (get(tr[y2--], x1, x2)) return true;
      y1 >>= 1;
      y2 >>= 1;
    }
    return false;
  }
};
struct Ev {
  int ty;
  long long x, y;
  int id;
  Ev(int _ty, long long _x, long long _y, int _id)
      : ty(_ty), x(_x), y(_y), id(_id) {}
  bool operator<(const Ev &e2) const {
    if (y != e2.y) return y > e2.y;
    if (x != e2.x) return x > e2.x;
    return ty > e2.ty;
  }
};
long long maxt;
void cross(long long &mix, long long &mxx, long long &miy, long long &mxy,
           const pt &p) {
  mix = max(mix, p.x - maxt);
  miy = max(miy, p.y - maxt);
  mxx = min(mxx, p.x + maxt);
  mxy = min(mxy, p.y + maxt);
}
vector<pt> subs;
segm_tree2 str;
bool findSubway(long long x1, long long x2, long long y1, long long y2) {
  return str.get(x1, x2, y1, y2);
}
int main() {
  int n, m;
  while (scanf("%d%d", &n, &m) >= 1) {
    vector<pt> pts(n);
    subs.resize(m);
    for (int i = 0; i < n; i++) scanf("%I64d%I64d", &pts[i].x, &pts[i].y);
    for (int i = 0; i < m; i++) scanf("%I64d%I64d", &subs[i].x, &subs[i].y);
    vector<int> nearest(n, -1);
    vector<long long> ndist(n, INFLL);
    for (int step = 0; step < 4; step++) {
      vector<long long> xs;
      for (int i = 0; i < n; i++) xs.push_back(pts[i].x);
      for (int i = 0; i < m; i++) xs.push_back(subs[i].x);
      sort(xs.begin(), xs.end());
      xs.erase(unique(xs.begin(), xs.end()), xs.end());
      fenv_tree tr(xs);
      vector<Ev> evs;
      for (int i = 0; i < n; i++) evs.push_back(Ev(0, pts[i].x, pts[i].y, i));
      for (int i = 0; i < m; i++) evs.push_back(Ev(1, subs[i].x, subs[i].y, i));
      sort(evs.begin(), evs.end());
      for (int i = 0; i < ((int)(evs).size()); i++) {
        if (evs[i].ty == 1) {
          tr.relax(evs[i].x, make_pair(evs[i].x + evs[i].y, evs[i].id));
        } else {
          pair<long long, int> cd = tr.get(evs[i].x);
          if (cd.second >= 0) {
            long long ncand = cd.first - evs[i].x - evs[i].y;
            if (ndist[evs[i].id] > ncand) {
              ndist[evs[i].id] = ncand;
              nearest[evs[i].id] = cd.second;
            }
          }
        }
      }
      if ((step & 1) == 0) {
        for (int i = 0; i < n; i++) pts[i].x = -pts[i].x;
        for (int i = 0; i < m; i++) subs[i].x = -subs[i].x;
      } else {
        for (int i = 0; i < n; i++) pts[i].y = -pts[i].y;
        for (int i = 0; i < m; i++) subs[i].y = -subs[i].y;
      }
    }
    vector<pair<long long, int> > ord(n);
    for (int i = 0; i < n; i++) ord[i] = make_pair(ndist[i], i);
    sort(ord.begin(), ord.end());
    for (int i = 0; i < n; i++) {
      pts[i] = pt(pts[i].x + pts[i].y, pts[i].x - pts[i].y);
    }
    for (int i = 0; i < m; i++) {
      subs[i] = pt(subs[i].x + subs[i].y, subs[i].x - subs[i].y);
    }
    sort(subs.begin(), subs.end());
    str = segm_tree2(subs);
    fprintf(stderr, "go\n");
    long long L = -1, R = ord[n - 1].first;
    while (L + 1 < R) {
      maxt = (L + R) / 2;
      long long mix = -INFLL, miy = -INFLL;
      long long mxx = INFLL, mxy = INFLL;
      int ptr = n - 1;
      for (; ptr >= 0 && ord[ptr].first > maxt; ptr--) {
        cross(mix, mxx, miy, mxy, pts[ord[ptr].second]);
      }
      for (; ptr >= 0 && mix <= mxx && miy <= mxy; ptr--) {
        long long remt = maxt - ord[ptr].first;
        assert(remt >= 0);
        if (findSubway(mix - remt, mxx + remt, miy - remt, mxy + remt)) {
          break;
        } else {
          cross(mix, mxx, miy, mxy, pts[ord[ptr].second]);
        }
      }
      if (mix <= mxx && miy <= mxy) {
        R = maxt;
      } else
        L = maxt;
    }
    printf("%I64d\n", R);
  }
  return 0;
}
