#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmin(T &x, T y) {
  return (y < x) ? (x = y, 1) : 0;
}
template <typename T>
inline bool chkmax(T &x, T y) {
  return (y > x) ? (x = y, 1) : 0;
}
inline int read() {
  int x;
  char c;
  int f = 1;
  while ((c = getchar()) != '-' && (c > '9' || c < '0'))
    ;
  if (c == '-') f = -1, c = getchar();
  x = c ^ '0';
  while ((c = getchar()) >= '0' && c <= '9')
    x = (x << 1) + (x << 3) + (c ^ '0');
  return x * f;
}
inline long long readll() {
  long long x;
  char c;
  int f = 1;
  while ((c = getchar()) != '-' && (c > '9' || c < '0'))
    ;
  if (c == '-') f = -1, c = getchar();
  x = c ^ '0';
  while ((c = getchar()) >= '0' && c <= '9')
    x = (x << 1ll) + (x << 3ll) + (c ^ '0');
  return x * f;
}
const int maxn = 3e5 + 10, maxm = 4e6 + 10;
struct point {
  int x, y;
} a[maxn];
struct Modify {
  int t, ql, qr, v;
  bool operator<(const Modify &rhs) const { return t < rhs.t; }
} Q[maxn << 1];
struct Segment_tree {
  int Max[maxm << 2], tag[maxm << 2];
  inline void push_up(int x) {
    Max[x] = max(Max[x << 1], Max[x << 1 | 1]) + tag[x];
  }
  void update(int x, int L, int R, int ql, int qr, int v) {
    if (ql <= L && R <= qr) {
      tag[x] += v, Max[x] += v;
      return;
    }
    int Mid = (L + R) >> 1;
    if (ql <= Mid) update(x << 1, L, Mid, ql, qr, v);
    if (qr > Mid) update(x << 1 | 1, Mid + 1, R, ql, qr, v);
    push_up(x);
  }
} Seg;
int idx[maxm], idx_cnt;
int main() {
  int n = read(), R = read();
  int Min = 1e9, Max = -1e9;
  for (register int i = 1, iend = n; i <= iend; ++i) {
    int x = read(), y = read();
    a[i].x = x + y, a[i].y = x - y;
    chkmin(Min, a[i].y), chkmax(Max, a[i].y);
  }
  for (register int i = Min, iend = Max; i <= iend; ++i) idx[++idx_cnt] = i;
  sort(idx + 1, idx + idx_cnt + 1);
  idx_cnt = unique(idx + 1, idx + idx_cnt + 1) - idx - 1;
  int q_cnt = 0;
  for (register int i = 1, iend = n; i <= iend; ++i) {
    int l = lower_bound(idx + 1, idx + idx_cnt + 1, a[i].y - R) - idx;
    int r = upper_bound(idx + 1, idx + idx_cnt + 1, a[i].y + R) - idx - 1;
    Q[++q_cnt] = (Modify){a[i].x - R, l, r, 1};
    Q[++q_cnt] = (Modify){a[i].x + R + 1, l, r, -1};
  }
  sort(Q + 1, Q + q_cnt + 1);
  int ans = 0;
  for (int i = 1, j; i <= q_cnt; i = j + 1) {
    j = i;
    while (j < q_cnt && Q[j + 1].t == Q[i].t) ++j;
    for (register int k = i, kend = j; k <= kend; ++k)
      Seg.update(1, 1, idx_cnt, Q[k].ql, Q[k].qr, Q[k].v);
    chkmax(ans, Seg.Max[1]);
  }
  printf("%d\n", ans);
  return 0;
}
