#include <bits/stdc++.h>
using namespace std;
class Timer {
 private:
  string scope_name;
  chrono::high_resolution_clock::time_point start_time;

 public:
  Timer(string name) : scope_name(name) {
    start_time = chrono::high_resolution_clock::now();
  }
  ~Timer() {
    auto stop_time = chrono::high_resolution_clock::now();
    auto length =
        chrono::duration_cast<chrono::microseconds>(stop_time - start_time)
            .count();
    double mlength = double(length) * 0.001;
    ;
  }
};
const long long MOD = 1000000007;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int iNF = 0x3f3f3f3f;
const long long MAXN = 100005;
struct Robot {
  int x, r, q, qid;
} rbt[MAXN];
int n, k;
long long ans;
vector<int> qval;
struct Treap {
  struct Node {
    Node *l, *r;
    int pri, sz;
    pair<int, int> key;
    Node(int x, int id) {
      l = r = nullptr;
      pri = rand();
      sz = 1;
      key = pair<int, int>(x, id);
    }
    void pull() {
      sz = 1;
      if (l) {
        sz += l->sz;
      }
      if (r) {
        sz += r->sz;
      }
    }
  };
  Node *root;
  int SIZ(Node *a) { return a ? a->sz : 0; }
  Node *mrg(Node *a, Node *b) {
    if (!a || !b) {
      return a ? a : b;
    }
    if (a->pri > b->pri) {
      a->r = mrg(a->r, b);
      a->pull();
      return a;
    } else {
      b->l = mrg(a, b->l);
      b->pull();
      return b;
    }
  }
  void split(Node *o, Node *&a, Node *&b, pair<int, int> sp) {
    if (!o) {
      a = b = nullptr;
      return;
    } else {
      if (o->key >= sp) {
        b = o;
        split(b->l, a, b->l, sp);
      } else {
        a = o;
        split(a->r, a->r, b, sp);
      }
      o->pull();
    }
  }
  void era(int x, int id) {
    Node *l, *m, *r;
    split(root, l, m, pair<int, int>(x, id));
    split(m, m, r, pair<int, int>(x, id + 1));
    root = mrg(l, r);
    if (m) {
      delete m;
    }
  }
  void ins(int x, int id) {
    Node *nw = new Node(x, id);
    if (!root) {
      root = nw;
    } else {
      Node *l, *r;
      split(root, l, r, pair<int, int>(x, id));
      root = mrg(l, mrg(nw, r));
    }
  }
  int qry(int l, int r) {
    Node *L, *M, *R;
    split(root, L, M, pair<int, int>(l, -iNF));
    split(M, M, R, pair<int, int>(r + 1, -iNF));
    int ret = SIZ(M);
    root = mrg(L, mrg(M, R));
    return ret;
  }
} trp[MAXN];
int main() {
  ;
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> k;
  for (int i = 0; i < n; i += 1) {
    cin >> rbt[i].x >> rbt[i].r >> rbt[i].q;
    qval.emplace_back(rbt[i].q);
  }
  sort(qval.begin(), qval.end());
  qval.resize(unique(qval.begin(), qval.end()) - qval.begin());
  for (int i = 0; i < n; i += 1) {
    rbt[i].qid = lower_bound(qval.begin(), qval.end(), rbt[i].q) - qval.begin();
  }
  sort(rbt, rbt + n, [&](Robot r1, Robot r2) { return r1.x < r2.x; });
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      pq;
  for (int i = 0; i < n; i += 1) {
    ;
    int x = rbt[i].x, r = rbt[i].r, q = rbt[i].q, qid = rbt[i].qid;
    while (!pq.empty() && pq.top().first < x) {
      int id = pq.top().second;
      trp[rbt[id].qid].era(rbt[id].x, id);
      pq.pop();
    }
    int ptr = qid;
    while (ptr > 0 && q - qval[ptr - 1] <= k) {
      ptr--;
    }
    while (ptr < int(qval.size()) && abs(q - qval[ptr]) <= k) {
      ans += trp[ptr].qry(x - r, x + r);
      ptr++;
    }
    pq.emplace(x + r, i);
    trp[qid].ins(x, i);
  }
  cout << ans << '\n';
  return 0;
}
