#include <bits/stdc++.h>
using namespace std;
template <class T>
void chmax(T& l, const T r) {
  l = max(l, r);
}
template <class T>
void chmin(T& l, const T r) {
  l = min(l, r);
}
const pair<int, int> Pinf =
    pair<int, int>(numeric_limits<int>::max(), numeric_limits<int>::max());
class RangeTree {
 public:
  int n;
  vector<pair<int, int>> xsorted;
  vector<vector<pair<int, int>>> dat;
  vector<vector<pair<int, int>>> bsearch_speedup;
  RangeTree(vector<pair<int, int>>& a) {
    n = 1;
    while (n < ((int)(a).size())) n <<= 1;
    dat.resize(2 * n - 1);
    sort(a.begin(), a.end());
    xsorted = a;
    xsorted.resize(n, Pinf);
    bsearch_speedup.resize(n);
    for (int i = 0; i < (n); i++) {
      int k = n - 1 + i;
      if (i < ((int)(a).size()))
        dat[k].push_back(a[i]);
      else
        dat[k].push_back(Pinf);
    }
    for (int i = n - 2; i >= 0; i--) {
      auto &cur_dat = dat[i], &lchild = dat[2 * i + 1], rchild = dat[2 * i + 2];
      cur_dat.resize(((int)(lchild).size()) + ((int)(rchild).size()));
      merge(lchild.begin(), lchild.end(), rchild.begin(), rchild.end(),
            cur_dat.begin(),
            [](const pair<int, int>& l, const pair<int, int>& r) {
              return l.second != r.second ? l.second < r.second
                                          : l.first < r.first;
            });
      auto& bs = bsearch_speedup[i];
      bs.resize(((int)(cur_dat).size()));
      int a1 = 0, a2 = 0;
      for (int k = 0; k < (((int)(cur_dat).size())); k++) {
        while (a1 < ((int)(lchild).size()) &&
               lchild[a1].second < cur_dat[k].second)
          a1++;
        bs[k].first = a1;
        while (a2 < ((int)(rchild).size()) &&
               rchild[a2].second < cur_dat[k].second)
          a2++;
        bs[k].second = a2;
      }
      bs.emplace_back(((int)(lchild).size()), ((int)(rchild).size()));
    }
  }
  int query(int lx, int rx, int ly, int ry) {
    int ly_index = lower_bound(dat[0].begin(), dat[0].end(), ly,
                               [](const pair<int, int>& l, const int val) {
                                 return l.second < val;
                               }) -
                   dat[0].begin();
    int ry_index = lower_bound(dat[0].begin(), dat[0].end(), ry,
                               [](const pair<int, int>& l, const int val) {
                                 return l.second < val;
                               }) -
                   dat[0].begin();
    return query(lx, rx, ly_index, ry_index, 0, 0, n);
  }
  int query(int lx, int rx, int ly_index, int ry_index, int k, int a, int b) {
    if (rx <= xsorted[a].first || xsorted[b - 1].first < lx) return 0;
    if (lx <= xsorted[a].first && xsorted[b - 1].first < rx) {
      return ry_index - ly_index;
    }
    int nly_idx_f, nly_idx_s, nry_idx_f, nry_idx_s;
    tie(nly_idx_f, nly_idx_s) = bsearch_speedup[k][ly_index];
    tie(nry_idx_f, nry_idx_s) = bsearch_speedup[k][ry_index];
    int lval = query(lx, rx, nly_idx_f, nry_idx_f, 2 * k + 1, a, (a + b) / 2);
    int rval = query(lx, rx, nly_idx_s, nry_idx_s, 2 * k + 2, (a + b) / 2, b);
    return lval + rval;
  }
};
int near_station(pair<int, int> d, RangeTree& rt) {
  int l = -1, r = ((int)1e8) * 4 + 1;
  while (r - l != 1) {
    int md = (r + l) / 2;
    int reach = rt.query(d.first - md, d.first + md + 1, d.second - md,
                         d.second + md + 1);
    if (reach >= 1)
      r = md;
    else
      l = md;
  }
  return r;
}
int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  vector<pair<int, int>> dwarves(n), stations(k);
  for (int i = 0; i < (n); i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    dwarves[i].first = a + b;
    dwarves[i].second = a - b;
  }
  for (int i = 0; i < (k); i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    stations[i].first = a + b;
    stations[i].second = a - b;
  }
  RangeTree rt(stations);
  vector<tuple<int, int, int>> dwarves_dist;
  for (int i = 0; i < (n); i++) {
    int dist = near_station(dwarves[i], rt);
    dwarves_dist.emplace_back(dist, dwarves[i].first, dwarves[i].second);
  }
  sort(dwarves_dist.rbegin(), dwarves_dist.rend());
  int l = -1, r = ((int)1e8) * 2;
  while (r - l != 1) {
    int md = (l + r) / 2;
    int lx = -((int)1e8) * 2, rx = ((int)1e8) * 2 + 1, ly = -((int)1e8) * 2,
        ry = ((int)1e8) * 2 + 1;
    bool b = false;
    for (int i = 0; i < (n + 1); i++) {
      if (i == n) {
        b = true;
        break;
      }
      int most_far = get<0>(dwarves_dist[i]);
      int s = md - most_far;
      if (s >= 0) {
        int reach = rt.query(lx - s, rx + s + 1, ly - s, ry + s + 1);
        if (reach >= 1) {
          b = true;
          break;
        }
      }
      lx = max(lx, get<1>(dwarves_dist[i]) - md);
      rx = min(rx, get<1>(dwarves_dist[i]) + md);
      ly = max(ly, get<2>(dwarves_dist[i]) - md);
      ry = min(ry, get<2>(dwarves_dist[i]) + md);
      if (lx > rx || ly > ry) break;
    }
    if (b)
      r = md;
    else
      l = md;
  }
  cout << r << endl;
  return 0;
}
