#include <bits/stdc++.h>   using namespace std;   inline int read() {     register int x = 0, f = 1;     register char ch = getchar();     while (!isdigit(ch)) {       if (ch ==  - ) f = 0;       ch = getchar();     }     while (isdigit(ch)) {       x = x * 10 + (ch ^  0 );       ch = getchar();     }     return f ? x : -x;   }   int n, m, yt, Y[200005];   struct subway {     int x, y;   } sbw[100005];   struct rabbit {     int x, y, dis;   } rbt[100005];   struct BIT {     int tr[200005];     void modify(int x, int v) {       for (; x <= yt; x += x & -x) tr[x] = max(tr[x], v);     }     int query(int x) {       int ans = -1000000000;       for (; x; x -= x & -x) ans = max(ans, tr[x]);       return ans;     }   } bit;   struct node {     int x, y, id;   } q[200005];   void work() {     memset(bit.tr, -0x3f, sizeof bit.tr);     yt = 0;     for (int i = (1), _ed_ = (n); i <= _ed_; ++i) {       Y[++yt] = rbt[i].y;     }     for (int i = (1), _ed_ = (m); i <= _ed_; ++i) {       Y[++yt] = sbw[i].y;     }     sort(Y + 1, Y + yt + 1), yt = unique(Y + 1, Y + yt + 1) - Y - 1;     for (int i = (1), _ed_ = (n); i <= _ed_; ++i)       q[i] = (node){rbt[i].x, rbt[i].y, i};     for (int i = (1), _ed_ = (m); i <= _ed_; ++i)       q[n + i] = (node){sbw[i].x, sbw[i].y, n + i};     sort(q + 1, q + n + m + 1,          [&](node a, node b) { return a.x == b.x ? a.id > b.id : a.x < b.x; });     for (int i = (1), _ed_ = (n + m); i <= _ed_; ++i) {       if (q[i].id > n)         bit.modify(lower_bound(Y + 1, Y + yt + 1, q[i].y) - Y, q[i].x + q[i].y);       else         rbt[q[i].id].dis =             min(rbt[q[i].id].dis,                 q[i].x + q[i].y -                     bit.query(lower_bound(Y + 1, Y + yt + 1, q[i].y) - Y));     }   }   int rt[100005], tcnt, tr[6000005], ls[6000005], rs[6000005];   void pushup(int p) { tr[p] = tr[ls[p]] + tr[rs[p]]; }   void insert(int& x, int y, int l, int r, int pos) {     x = ++tcnt;     tr[x] = tr[y], ls[x] = ls[y], rs[x] = rs[y];     if (l == r) return ++tr[x], void();     int mid = (l + r) >> 1;     if (pos <= mid)       insert(ls[x], ls[y], l, mid, pos);     else       insert(rs[x], rs[y], mid + 1, r, pos);     pushup(x);   }   int query(int x, int y, int l, int r, int L, int R) {     if (L > R || x == y) return 0;     if (L <= l && r <= R) return tr[x] - tr[y];     int mid = (l + r) >> 1, ans = 0;     if (L <= mid) ans += query(ls[x], ls[y], l, mid, L, R);     if (ans) return ans;     if (mid < R) ans += query(rs[x], rs[y], mid + 1, r, L, R);     return ans;   }   int lower(int x) {     int l = 1, r = m, ans = r + 1;     while (l <= r) {       int mid = (l + r) >> 1;       if (sbw[mid].x >= x)         ans = mid, r = mid - 1;       else         l = mid + 1;     }     return ans;   }   int upper(int x) {     int l = 1, r = m, ans = r + 1;     while (l <= r) {       int mid = (l + r) >> 1;       if (sbw[mid].x > x)         ans = mid, r = mid - 1;       else         l = mid + 1;     }     return ans - 1;   }   int query(int x, int y) {     int l = 0, r = 1000000000, ans, L, R, D, U;     while (l <= r) {       int mid = (l + r) >> 1;       L = lower(x - mid), R = upper(x + mid),       D = lower_bound(Y + 1, Y + yt + 1, y - mid) - Y,       U = upper_bound(Y + 1, Y + yt + 1, y + mid) - Y - 1;       if (L <= R && query(rt[R], rt[L - 1], 1, yt, D, U))         ans = mid, r = mid - 1;       else         l = mid + 1;     }     return ans;   }   struct square {     int x1, y1, x2, y2;     square(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0)         : x1(x1), y1(y1), x2(x2), y2(y2) {}     void merge(square o) {       x1 = max(x1, o.x1), y1 = max(y1, o.y1);       x2 = min(x2, o.x2), y2 = min(y2, o.y2);     }     bool valid() {       if (x1 == x2 && y1 == y2 && (x1 + y1) & 1) return 0;       return x1 <= x2 && y1 <= y2;     }   };   bool check(int tim) {     int p = n;     while (p && rbt[p].dis > tim) --p;     square nw(-1000000000, -1000000000, 1000000000, 1000000000);     for (int i = (n), _ed_ = (p + 1); i >= _ed_; --i)       nw.merge(           square(rbt[i].x - tim, rbt[i].y - tim, rbt[i].x + tim, rbt[i].y + tim));     int L, R, D, U;     while (p && nw.valid()) {       int t = tim - rbt[p].dis, x1 = nw.x1, y1 = nw.y1, x2 = nw.x2, y2 = nw.y2;       if (x1 == x2) {         if ((x1 + y1) & 1) ++y1;         if ((x2 + y2) & 1) --y2;       } else if (y1 == y2) {         if ((x1 + y1) & 1) ++x1;         if ((x2 + y2) & 1) --x2;       }       if (x1 <= x2 && y1 <= y2) {         L = lower(x1 - t), R = upper(x2 + t),         D = lower_bound(Y + 1, Y + yt + 1, y1 - t) - Y,         U = upper_bound(Y + 1, Y + yt + 1, y2 + t) - Y - 1;         if (L <= R && query(rt[R], rt[L - 1], 1, yt, D, U)) return 1;       }       nw.merge(           square(rbt[p].x - tim, rbt[p].y - tim, rbt[p].x + tim, rbt[p].y + tim));       --p;     }     if (nw.valid()) return 1;     return 0;   }   int main() {     n = read(), m = read();     for (int i = (1), _ed_ = (n); i <= _ed_; ++i)       rbt[i] = (rabbit){read(), read(), 1000000000};     for (int i = (1), _ed_ = (m); i <= _ed_; ++i)       sbw[i] = (subway){read(), read()};     for (int i = (1), _ed_ = (n); i <= _ed_; ++i) {       rbt[i].x *= -1;     }     for (int i = (1), _ed_ = (m); i <= _ed_; ++i) {       sbw[i].x *= -1;     }     work();     for (int i = (1), _ed_ = (n); i <= _ed_; ++i) {       rbt[i].y *= -1;     }     for (int i = (1), _ed_ = (m); i <= _ed_; ++i) {       sbw[i].y *= -1;     }     work();     for (int i = (1), _ed_ = (n); i <= _ed_; ++i) {       rbt[i].x *= -1;     }     for (int i = (1), _ed_ = (m); i <= _ed_; ++i) {       sbw[i].x *= -1;     }     work();     for (int i = (1), _ed_ = (n); i <= _ed_; ++i) {       rbt[i].y *= -1;     }     for (int i = (1), _ed_ = (m); i <= _ed_; ++i) {       sbw[i].y *= -1;     }     work();     for (int i = (1), _ed_ = (n); i <= _ed_; ++i) {       int x = rbt[i].x, y = rbt[i].y;       rbt[i].x = x + y, rbt[i].y = x - y;     }     for (int i = (1), _ed_ = (m); i <= _ed_; ++i) {       int x = sbw[i].x, y = sbw[i].y;       sbw[i].x = x + y, sbw[i].y = x - y;     }     sort(sbw + 1, sbw + m + 1,          [&](subway a, subway b) { return a.x == b.x ? a.y < b.y : a.x < b.x; });     yt = 0;     for (int i = (1), _ed_ = (m); i <= _ed_; ++i) Y[++yt] = sbw[i].y;     sort(Y + 1, Y + yt + 1), yt = unique(Y + 1, Y + yt + 1) - Y - 1;     for (int i = (1), _ed_ = (m); i <= _ed_; ++i)       insert(rt[i], rt[i - 1], 1, yt,              lower_bound(Y + 1, Y + yt + 1, sbw[i].y) - Y);     sort(rbt + 1, rbt + n + 1, [&](rabbit a, rabbit b) { return a.dis < b.dis; });     int l = 0, r = rbt[n].dis, ans;     while (l <= r) {       int mid = (l + r) >> 1;       if (check(mid))         ans = mid, r = mid - 1;       else         l = mid + 1;     }     printf( %d n , ans);     return 0;   }