#include <bits/stdc++.h>   using namespace std;   unsigned long long gcd(unsigned long long a, unsigned long long b) {     return b == 0 ? a : gcd(b, a % b);   }   const int MAXTREE = 50;   const int MOD = 998244353;   const int INV6 = 166374059;   const int MINCOORD = -1000000000;   const int MAXCOORD = +1000000000;   struct P {     int x, y;     P() {}     P(int x, int y) : x(x), y(y) {}   };   P operator-(const P &a, const P &b) { return P(a.x - b.x, a.y - b.y); }   bool operator==(const P &a, const P &b) { return a.x == b.x && a.y == b.y; }   struct Pol {     vector<P> p;   };   int ntree, tlast;   P t[MAXTREE];   void rotate(P &p) { p = P(-p.y, +p.x); }   void rotate(Pol &pol) {     for (int i = (0); i < (((int)(pol.p).size())); ++i) rotate(pol.p[i]);   }   void flip(P &p) { swap(p.x, p.y); }   void flip(Pol &pol) {     for (int i = (0); i < (((int)(pol.p).size())); ++i) flip(pol.p[i]);     reverse(pol.p.begin(), pol.p.end());   }   P infleftup(const P &p) {     int t = min(p.x - MINCOORD, MAXCOORD - p.y);     return P(p.x - t, p.y + t);   }   P infleftdown(const P &p) {     int t = min(p.x - MINCOORD, p.y - MINCOORD);     return P(p.x - t, p.y - t);   }   P infrightup(const P &p) {     int t = min(MAXCOORD - p.x, MAXCOORD - p.y);     return P(p.x + t, p.y + t);   }   P infrightdown(const P &p) {     int t = min(MAXCOORD - p.x, p.y - MINCOORD);     return P(p.x + t, p.y - t);   }   int getdelta(const P &a, const P &b) {     P ba = b - a;     assert(ba.y == 0 || abs(ba.y) == abs(ba.x));     return ba.y / ba.x;   }   int getdir(const P &a, const P &b) {     P ba = b - a;     int mag = max(abs(ba.x), abs(ba.y));     assert(mag != 0 && ba.x % mag == 0 && ba.y % mag == 0);     ba.x /= mag, ba.y /= mag;     if (ba == P(1, 1)) return 0;     if (ba == P(1, 0)) return 1;     if (ba == P(1, -1)) return 2;     if (ba == P(0, -1)) return 3;     if (ba == P(-1, -1)) return 4;     if (ba == P(-1, 0)) return 5;     if (ba == P(-1, 1)) return 6;     if (ba == P(0, 1)) return 7;     assert(false);     return -1;   }   int gety(int x, const vector<P> &path) {     int idx = 0;     while (idx + 1 < ((int)(path).size()) && path[idx + 1].x <= x) ++idx;     assert(idx + 1 < ((int)(path).size()));     int v = getdelta(path[idx], path[idx + 1]);     return path[idx].y + (x - path[idx].x) * v;   }   vector<pair<P, P>> segmentsbeloworequal(P a, P b, const vector<P> &path) {     bool swapab = false;     if (a.x > b.x) swapab = true, swap(a, b);     P ba = b - a;     vector<pair<P, P>> ret;     if (ba.x == 0) {       int x = a.x, py = gety(x, path);       assert(!swapab);       if (a.y <= py)         ret.push_back(make_pair(a, P(x, min(py, b.y))));       else if (b.y <= py)         ret.push_back(make_pair(P(x, py), b));     } else {       int x = a.x, y = a.y, u = getdelta(a, b), idx = 0;       P oth = a;       while (true) {         while (idx + 1 < ((int)(path).size()) && path[idx + 1].x <= x) ++idx;         assert(idx + 1 < ((int)(path).size()));         int v = getdelta(path[idx], path[idx + 1]);         int py = path[idx].y + (x - path[idx].x) * v;         if (x == b.x) {           if (y <= py) ret.push_back(make_pair(oth, b));           break;         }         int dx = min(b.x - x, path[idx + 1].x - x);         if (y <= py) {           if (u - v >= 1) {             int t = (py - y) / (u - v);             if (t < dx) ret.push_back(make_pair(oth, P(x + t, y + u * t)));           }         } else {           if (v - u >= 1) {             int t = (y - py - 1) / (v - u);             if (t < dx) oth = P(x + t + 1, y + u * (t + 1));           }         }         x += dx, y += u * dx;       }     }     if (swapab) {       swapab = false, swap(a, b), reverse(ret.begin(), ret.end());       for (int i = (0); i < (((int)(ret).size())); ++i)         swap(ret[i].first, ret[i].second);     }     return ret;   }   bool isbeloworequal(const P &a, const vector<P> &path) {     return a.y <= gety(a.x, path);   }   bool isinside(const P &p, const Pol &pol) {     if (((int)(pol.p).size()) == 1) return pol.p[0] == p;     bool ret = false;     for (int i = (0); i < (((int)(pol.p).size())); ++i) {       P a = pol.p[i], b = pol.p[(i + 1) % ((int)(pol.p).size())],         c = pol.p[(i + 2) % ((int)(pol.p).size())],         d = pol.p[(i + 3) % ((int)(pol.p).size())];       int pdir = getdir(a, b), cdir = getdir(b, c), ndir = getdir(c, d);       int sgn, delta;       P l, r;       bool includefirst, includelast;       if (cdir < 4) {         includefirst = pdir < 3 || pdir >= cdir + 4,         includelast = cdir != 3 && ndir >= 4 && ndir <= cdir + 4;         if (cdir == 3) {           sgn = includefirst ? +1 : 0, delta = 0, l = r = b;           ++l.y, ++r.y;         } else {           sgn = +1, delta = getdelta(b, c);           l = b, r = c;           ++l.y, ++r.y;           if (!includefirst) ++l.x, l.y += delta;           if (!includelast) --r.x, r.y -= delta;         }       } else {         includefirst = pdir != 7 && pdir >= cdir - 4,         includelast = cdir != 7 && ndir <= cdir - 4;         if (cdir == 7) {           sgn = includefirst ? -1 : 0, delta = 0, l = r = b;         } else {           sgn = -1, delta = getdelta(c, b), l = c, r = b;           if (!includefirst) --r.x, r.y -= delta;           if (!includelast) ++l.x, l.y += delta;         }       }       if (sgn != 0 && l.x <= p.x && p.x <= r.x && p.y < l.y + (p.x - l.x) * delta)         ret = !ret;     }     return ret;   }   void updatepol(Pol &pol, bool prvonpol, const P p, const vector<P> &path,                  const Pol &orig) {     if (((int)(pol.p).size()) >= 1 && p == pol.p[((int)(pol.p).size()) - 1])       return;     if (!prvonpol && ((int)(pol.p).size()) >= 1) {       P a = pol.p[((int)(pol.p).size()) - 1], b = p;       bool swapab = false;       if (a.x > b.x) swapab = true, swap(a, b);       int ay = gety(a.x, path), by = gety(b.x, path);       if (ay != a.y) {         assert(ay == a.y + 1);         if (isinside(P(a.x, a.y + 1), orig))           ++a.y;         else           ++a.x, --ay;       }       if (by != b.y) {         assert(by == b.y + 1);         if (isinside(P(b.x, b.y + 1), orig))           ++b.y;         else           --b.x, --by;       }       vector<P> extra;       if (!(a == pol.p[((int)(pol.p).size()) - 1])) extra.push_back(a);       for (int i = (0); i < (((int)(path).size())); ++i)         if (a.x < path[i].x && path[i].x < b.x) extra.push_back(path[i]);       if (!(b == p) && !(b == a)) extra.push_back(b);       if (swapab) reverse(extra.begin(), extra.end());       for (int i = (0); i < (((int)(extra).size())); ++i)         pol.p.push_back(extra[i]);     }     if (((int)(pol.p).size()) == 0 || !(p == pol.p[((int)(pol.p).size()) - 1]))       pol.p.push_back(p);   }   Pol cutabove(Pol pol, const vector<P> &path) {     if (((int)(pol.p).size()) == 0) return pol;     Pol ret;     if (((int)(pol.p).size()) == 1)       return isbeloworequal(pol.p[0], path) ? pol : ret;     bool prvonpol = false;     for (int i = (0); i < (((int)(pol.p).size())); ++i) {       P a = pol.p[i], b = pol.p[(i + 1) % ((int)(pol.p).size())];       vector<pair<P, P>> segments = segmentsbeloworequal(a, b, path);       if (((int)(segments).size()) == 0 || !(segments[0].first == a))         prvonpol = false;       for (int k = (0); k < (((int)(segments).size())); ++k) {         if (segments[k].first == b) {           assert(segments[k].second == b);           assert(k == ((int)(segments).size()) - 1);           prvonpol = false;         } else {           updatepol(ret, prvonpol, segments[k].first, path, pol);           if (segments[k].first == segments[k].second) {             prvonpol = false;           } else if (segments[k].second == b) {             prvonpol = true;           } else {             updatepol(ret, true, segments[k].second, path, pol);             prvonpol = false;           }         }       }     }     if (((int)(ret.p).size()) >= 1) {       if (!(ret.p[0] == pol.p[0])) prvonpol = false;       updatepol(ret, prvonpol, ret.p[0], path, pol);       if (((int)(ret.p).size()) >= 2 &&           ret.p[((int)(ret.p).size()) - 1] == ret.p[0])         ret.p.pop_back();     }     return ret;   }   Pol cut(Pol pol, P a, P b, bool winequal) {     int nrot = 0, nflip = 0;     while (b.y <= a.y || b.x < a.x) rotate(pol), rotate(a), rotate(b), ++nrot;     if (b.y - a.y < b.x - a.x) flip(pol), flip(a), flip(b), ++nflip;     P d = b - a;     int between = d.y - 1;     int asteps = between / 2, bsteps = between / 2, turn = winequal ? 0 : 1;     if (between % 2 == 1)       if (turn == 0)         ++asteps, turn = 1;       else         ++bsteps, turn = 0;     vector<P> path;     int y = a.y + asteps;     if (d.x == d.y) {       P m(a.x + asteps + (turn == 0 ? 1 : 0), y);       path.push_back(infleftup(m));       path.push_back(infrightdown(m));     } else if (d.x == 0) {       if (asteps < bsteps) {         assert(turn == 0);         ++asteps, turn = 1;       }       if (bsteps < asteps) {         assert(turn == 1);         ++bsteps, turn = 0;       }       assert(asteps == bsteps);       P l(a.x - asteps, y), r(a.x + asteps, y);       path.push_back(turn == 0 ? infleftup(l) : infleftdown(l));       path.push_back(l);       if (l.x != r.x || l.y != r.y) path.push_back(r);       path.push_back(turn == 0 ? infrightup(r) : infrightdown(r));     } else {       P l(a.x + d.x - bsteps - (turn == 0 ? 0 : 1), y),           r(a.x + asteps + (turn == 0 ? 1 : 0), y);       path.push_back(infleftup(l));       path.push_back(l);       path.push_back(r);       path.push_back(infrightdown(r));     }     pol = cutabove(pol, path);     while (nflip % 2 != 0) flip(pol), flip(a), flip(b), ++nflip;     while (nrot % 4 != 0) rotate(pol), rotate(a), rotate(b), ++nrot;     return pol;   }   int sum(int a, int b) { return (long long)(a + b) * (b - a + 1) / 2 % MOD; }   int sumsq(int a, int b) {     return ((long long)2 * a * a + (long long)2 * b * b + (long long)2 * a * b +             b - a) %            MOD * (b - a + 1) % MOD * INV6 % MOD;   }   int calcsum(const P &l, const P &r, int delta) {     int y = l.y % MOD;     if (y < 0) y += MOD;     int x = l.x % MOD;     if (x < 0) x += MOD;     if (delta == 0) {       return (long long)sum(l.x, r.x) * y % MOD;     } else if (delta == 1) {       return ((long long)sum(l.x, r.x) * (y + MOD - x) + sumsq(l.x, r.x)) % MOD;     } else if (delta == -1) {       return ((long long)sum(l.x, r.x) * (y + x) + MOD - sumsq(l.x, r.x)) % MOD;     } else {       assert(false);     }   }   int xcalc(Pol pol) {     int ret = 0;     if (((int)(pol.p).size()) >= 2)       for (int i = (0); i < (((int)(pol.p).size())); ++i) {         P a = pol.p[i], b = pol.p[(i + 1) % ((int)(pol.p).size())],           c = pol.p[(i + 2) % ((int)(pol.p).size())],           d = pol.p[(i + 3) % ((int)(pol.p).size())];         int pdir = getdir(a, b), cdir = getdir(b, c), ndir = getdir(c, d);         int sgn, delta;         P l, r;         bool includefirst, includelast;         if (cdir < 4) {           includefirst = pdir < 3 || pdir >= cdir + 4,           includelast = cdir != 3 && ndir >= 4 && ndir <= cdir + 4;           if (cdir == 3) {             sgn = includefirst ? +1 : 0, delta = 0, l = r = b;             ++l.y, ++r.y;           } else {             sgn = +1, delta = getdelta(b, c);             l = b, r = c;             ++l.y, ++r.y;             if (!includefirst) ++l.x, l.y += delta;             if (!includelast) --r.x, r.y -= delta;           }         } else {           includefirst = pdir != 7 && pdir >= cdir - 4,           includelast = cdir != 7 && ndir <= cdir - 4;           if (cdir == 7) {             sgn = includefirst ? -1 : 0, delta = 0, l = r = b;           } else {             sgn = -1, delta = getdelta(c, b), l = c, r = b;             if (!includefirst) --r.x, r.y -= delta;             if (!includelast) ++l.x, l.y += delta;           }         }         int cur = sgn != 0 && l.x <= r.x ? calcsum(l, r, delta) : 0;         if (sgn == +1)           ret = (ret + cur) % MOD;         else           ret = (ret + MOD - cur) % MOD;       }     if (((int)(pol.p).size()) == 1) ret = (ret + pol.p[0].x) % MOD;     return ret;   }   Pol cutbelow(Pol pol, vector<P> path) {     for (int rep = (0); rep < (2); ++rep) {       rotate(pol);       for (int i = (0); i < (((int)(path).size())); ++i) rotate(path[i]);     }     reverse(path.begin(), path.end());     pol = cutabove(pol, path);     for (int rep = (0); rep < (2); ++rep) {       rotate(pol);       for (int i = (0); i < (((int)(path).size())); ++i) rotate(path[i]);     }     reverse(path.begin(), path.end());     return pol;   }   int calc(Pol pol) {     int ret = 0;     for (int rep = (0); rep < (4); ++rep) {       vector<P> upath;       upath.push_back(infleftdown(P(0, 0)));       upath.push_back(infrightup(P(0, 0)));       vector<P> lpath;       lpath.push_back(P(MINCOORD, 0));       lpath.push_back(P(1, 0));       lpath.push_back(infrightdown(P(1, 0)));       Pol cpol = cutbelow(cutabove(pol, upath), lpath);       ret = (ret + xcalc(cpol)) % MOD;       rotate(pol);     }     return ret;   }   int solve() {     if (tlast == 0) return 0;     int ret = 0;     for (int i = (0); i < (ntree); ++i) {       Pol pol;       pol.p.push_back(P(t[i].x - tlast, t[i].y + tlast));       pol.p.push_back(P(t[i].x + tlast, t[i].y + tlast));       pol.p.push_back(P(t[i].x + tlast, t[i].y - tlast));       pol.p.push_back(P(t[i].x - tlast, t[i].y - tlast));       for (int j = (0); j < (ntree); ++j)         if (j != i) {           pol = cut(pol, t[i], t[j], i < j);         }       for (int k = (0); k < (((int)(pol.p).size())); ++k)         pol.p[k] = pol.p[k] - t[i];       ret = (ret + calc(pol)) % MOD;     }     return ret;   }   void run() {     scanf( %d%d , &ntree, &tlast);     for (int i = (0); i < (ntree); ++i) scanf( %d%d , &t[i].x, &t[i].y);     printf( %d n , solve());   }   int solvestupid() {     int lx = INT_MAX, hx = INT_MIN, ly = INT_MAX, hy = INT_MIN;     for (int i = (0); i < (ntree); ++i)       lx = min(lx, t[i].x - tlast), hx = max(hx, t[i].x + tlast),       ly = min(ly, t[i].y - tlast), hy = max(hy, t[i].y + tlast);     vector<vector<int>> d(hx - lx + 1, vector<int>(hy - ly + 1, INT_MAX));     for (int i = (0); i < (ntree); ++i)       for (int x = (t[i].x - tlast); x <= (t[i].x + tlast); ++x)         for (int y = (t[i].y - tlast); y <= (t[i].y + tlast); ++y) {           int &v = d[x - lx][y - ly];           v = min(v, max(abs(x - t[i].x), abs(y - t[i].y)));         }     int ret = 0;     for (int x = (lx); x <= (hx); ++x)       for (int y = (ly); y <= (hy); ++y) {         int v = d[x - lx][y - ly];         if (v != INT_MAX) ret += v;       }     return ret;   }   void stress() {     mt19937 rnd(12344);     int mxn = 100, mxt = 100, mncoord = 0, mxcoord = 100;     for (int rep = (0); rep < (100000); ++rep) {       ntree = rnd() % mxn + 1;       tlast = rnd() % (mxt + 1);       set<pair<int, int>> seen;       for (int i = (0); i < (ntree); ++i)         while (true) {           t[i].x = rnd() % (mxcoord - mncoord + 1) + mncoord,           t[i].y = rnd() % (mxcoord - mncoord + 1) + mncoord;           if (seen.count(make_pair(t[i].x, t[i].y))) continue;           seen.insert(make_pair(t[i].x, t[i].y));           break;         }       int have = solve();       int want = solvestupid();       if (have == want) {         if (rep % 100 == 99) printf( . );         continue;       }       puts(  );       printf( %d %d n , ntree, tlast);       for (int i = (0); i < (ntree); ++i) printf( %d %d n , t[i].x, t[i].y);       printf( err have=%d want=%d n , have, want);       break;     }   }   int main() {     run();     return 0;   }