#include <bits/stdc++.h>
using namespace std;
const int dt = 2000010;
void trans(int& x, int& y) {
  int xx = x, yy = y;
  x = xx - yy + dt;
  y = xx + yy + dt;
}
struct Point {
  int x, y, c;
  Point(int xx = 0, int yy = 0, int cc = 0) {
    x = xx;
    y = yy;
    c = cc;
  }
  bool operator<(const Point& b) const {
    if (y == b.y) {
      if (x == b.x) return c < b.c;
      return x < b.x;
    }
    return y < b.y;
  }
};
vector<Point> ve;
int tree[16 * dt], laz[16 * dt];
void push_down(int x) {
  if (laz[x]) {
    tree[x << 1] += laz[x];
    tree[x << 1 | 1] += laz[x];
    laz[x << 1] += laz[x];
    laz[x << 1 | 1] += laz[x];
    laz[x] = 0;
  }
  return;
}
void push_up(int x) { tree[x] = max(tree[x << 1], tree[x << 1 | 1]); }
void update(int ll, int rr, int v, int l, int r, int x) {
  if (ll <= l && rr >= r) {
    tree[x] += v;
    laz[x] += v;
    return;
  }
  push_down(x);
  int mid = l + r >> 1;
  if (ll <= mid) update(ll, rr, v, l, mid, x << 1);
  if (rr > mid) update(ll, rr, v, mid + 1, r, x << 1 | 1);
  push_up(x);
}
int query(int ll, int rr, int l, int r, int x) {
  if (ll <= l && rr >= r) {
    return tree[x];
  }
  push_down(x);
  int mid = l + r >> 1;
  int res = 0;
  if (ll <= mid) res = max(res, query(ll, rr, l, mid, x << 1));
  if (rr > mid) res = max(res, query(ll, rr, mid + 1, r, x << 1 | 1));
  push_up(x);
  return res;
}
int main() {
  int n, r, ans = 0;
  scanf("%d%d", &n, &r);
  for (int x, y, i = 1; i <= n; i++) {
    scanf("%d%d", &x, &y);
    trans(x, y);
    ve.push_back(Point(x, y, 0));
    ve.push_back(Point(x + 2 * r, y + 2 * r, 1));
  }
  sort(ve.begin(), ve.end());
  for (int i = 0; i < ve.size(); i++) {
    Point cur = ve[i];
    if (cur.c == 0) {
      update(cur.x, cur.x + 2 * r, 1, 0, 4 * dt, 1);
      int res = query(0, 4 * dt, 0, 4 * dt, 1);
      ans = max(ans, res);
    } else {
      int res = query(0, 4 * dt, 0, 4 * dt, 1);
      ans = max(ans, res);
      update(cur.x - 2 * r, cur.x, -1, 0, 4 * dt, 1);
    }
  }
  printf("%d", ans);
  return 0;
}
