#include <bits/stdc++.h>
using namespace std;
struct Segment {
  int value, delta, idx;
  Segment(int value = 0, int delta = 0, int idx = 0)
      : value(value), delta(delta), idx(idx) {}
  int getValue() const { return value + delta; }
  void merge(const Segment &lhs, const Segment &rhs) {
    int lhsValue = lhs.getValue();
    int rhsValue = rhs.getValue();
    if (lhsValue >= rhsValue) {
      value = lhsValue;
      idx = lhs.idx;
    } else {
      value = rhsValue;
      idx = rhs.idx;
    }
    delta = 0;
  }
  void pushTo(Segment &lhs, Segment &rhs) {
    lhs.delta += delta;
    rhs.delta += delta;
    delta = 0;
  }
};
template <int MAXN = 1 << 20>
struct SegmentTree {
 private:
  int n;
  Segment seg[MAXN << 2];
  static int LEFT(int idx) { return idx << 1; }
  static int RIGHT(int idx) { return (idx << 1) | 1; }
  void _build(int idx, int lower, int upper) {
    seg[idx] = Segment(0, 0, lower);
    if (lower == upper) return;
    int medium = (lower + upper) >> 1;
    _build(LEFT(idx), lower, medium);
    _build(RIGHT(idx), medium + 1, upper);
  }
  int l, r, v;
  void _update(int idx, int lower, int upper) {
    if (l <= lower && upper <= r) {
      seg[idx].delta += v;
      return;
    }
    seg[idx].pushTo(seg[LEFT(idx)], seg[RIGHT(idx)]);
    int medium = (lower + upper) >> 1;
    if (r <= medium) {
      _update(LEFT(idx), lower, medium);
    } else if (medium < l) {
      _update(RIGHT(idx), medium + 1, upper);
    } else {
      _update(LEFT(idx), lower, medium);
      _update(RIGHT(idx), medium + 1, upper);
    }
    seg[idx].merge(seg[LEFT(idx)], seg[RIGHT(idx)]);
  }
  Segment _calc(int idx, int lower, int upper) {
    if (l <= lower && upper <= r) return seg[idx];
    seg[idx].pushTo(seg[LEFT(idx)], seg[RIGHT(idx)]);
    int medium = (lower + upper) >> 1;
    Segment res;
    if (r <= medium)
      res = _calc(LEFT(idx), lower, medium);
    else if (medium < l)
      res = _calc(RIGHT(idx), medium + 1, upper);
    else
      res.merge(_calc(LEFT(idx), lower, medium),
                _calc(RIGHT(idx), medium + 1, upper));
    seg[idx].merge(seg[LEFT(idx)], seg[RIGHT(idx)]);
    return res;
  }

 public:
  void init(int n) {
    this->n = n;
    _build(1, 0, n - 1);
  }
  void update(int l, int r, int v) {
    assert(l <= r);
    this->l = l;
    this->r = r;
    this->v = v;
    _update(1, 0, n - 1);
  }
  Segment calc(int l, int r) {
    assert(l <= r);
    this->l = l;
    this->r = r;
    return _calc(1, 0, n - 1);
  }
};
const int MAXN = 200000;
int n, r, nDIS, DIS[MAXN * 3];
SegmentTree<> sgt;
priority_queue<pair<int, int>, vector<pair<int, int> >,
               greater<pair<int, int> > >
    heap;
int INDEX(int x) { return lower_bound(DIS, DIS + nDIS, x) - DIS; }
int nHEAD, HEAD[MAXN];
int calc() {
  if (!n) return 0;
  sgt.init(n * 3);
  int best = 0, pntHEAD = 0;
  while (!heap.empty()) {
    int anchor = heap.top().first;
    int other = heap.top().second;
    heap.pop();
    for (; pntHEAD < nHEAD && HEAD[pntHEAD] <= anchor; pntHEAD++) {
      int idx = INDEX(HEAD[pntHEAD] - r + 1) - 1;
      if (idx >= 0) sgt.update(nDIS, nDIS, sgt.calc(0, idx).getValue());
      DIS[nDIS++] = HEAD[pntHEAD];
    }
    if (DIS[nDIS - 1] != anchor) {
      int idx = INDEX(anchor - r + 1) - 1;
      if (idx >= 0) sgt.update(nDIS, nDIS, sgt.calc(0, idx).getValue());
      DIS[nDIS++] = anchor;
    }
    if (other != -1) sgt.update(INDEX(other), INDEX(anchor), 1);
    Segment sg = sgt.calc(0, n * 3 - 1);
    if (best < sg.getValue()) {
      best++;
      heap.push(make_pair(max(DIS[sg.idx] + r, anchor + 1), -1));
    }
  }
  return best;
}
int main() {
  int fakeN;
  scanf("%d%d", &fakeN, &r);
  for (int _ = (0); _ < (fakeN); _++) {
    int head, tail;
    scanf("%d%d", &head, &tail);
    if (tail < 0) continue;
    n++;
    HEAD[nHEAD++] = max(head, 0);
    heap.push(make_pair(tail, HEAD[nHEAD - 1]));
  }
  sort(HEAD, HEAD + nHEAD);
  nHEAD = unique(HEAD, HEAD + nHEAD) - HEAD;
  printf("%d\n", calc());
  return 0;
}
