#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const int inf = 1e9 + 1;
int nxt = 0;
map<int, int> roots;
struct robot {
  int x, r, iq, event;
  robot() : x(0), r(0), iq(0), event(0) {}
  robot(int x, int r, int iq, int event) : x(x), r(r), iq(iq), event(event) {}
};
struct node {
  int l, r, sum;
  node() : l(-1), r(-1), sum(0) {}
} tree[maxn * 40];
void upd(int v, int tl, int tr, int pos, int add) {
  if (tl > tr) return;
  if (tl == tr) {
    tree[v].sum += add;
    return;
  }
  int tm = (tl + tr) / 2;
  if (pos <= tm) {
    if (tree[v].l == -1) tree[v].l = ++nxt;
    upd(tree[v].l, tl, tm, pos, add);
  } else {
    if (tree[v].r == -1) tree[v].r = ++nxt;
    upd(tree[v].r, tm + 1, tr, pos, add);
  }
  int ansl = 0, ansr = 0;
  if (tree[v].l != -1) ansl = tree[tree[v].l].sum;
  if (tree[v].r != -1) ansr = tree[tree[v].r].sum;
  tree[v].sum = ansl + ansr;
}
int get(int v, int tl, int tr, int l, int r) {
  if (tl == l and tr == r) return tree[v].sum;
  int tm = (tl + tr) / 2;
  int ansl = 0, ansr = 0;
  if (r <= tm) {
    if (tree[v].l != -1) ansl = get(tree[v].l, tl, tm, l, r);
  } else if (l > tm) {
    if (tree[v].r != -1) ansr = get(tree[v].r, tm + 1, tr, l, r);
  } else {
    if (tree[v].l != -1) ansl = get(tree[v].l, tl, tm, l, tm);
    if (tree[v].r != -1) ansr = get(tree[v].r, tm + 1, tr, tm + 1, r);
  }
  return ansl + ansr;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<robot> v;
  for (int i = 0; i < n; i++) {
    int x, r, q;
    cin >> x >> r >> q;
    x++;
    v.push_back(robot(x - r, r, q, 0));
    v.push_back(robot(x, r, q, 2));
    v.push_back(robot(x + r + 1, r, q, 1));
  }
  sort(v.begin(), v.end(), [](robot a, robot b) {
    if (a.x == b.x) return a.event < b.event;
    return a.x < b.x;
  });
  long long ans = 0;
  for (int i = 0; i < v.size(); i++) {
    if (v[i].event == 0) {
      if (roots.find(v[i].iq) == roots.end()) roots[v[i].iq] = ++nxt;
      upd(roots[v[i].iq], 1, inf, v[i].x + v[i].r, 1);
    } else if (v[i].event == 1) {
      if (roots.find(v[i].iq) == roots.end()) roots[v[i].iq] = ++nxt;
      upd(roots[v[i].iq], 1, inf, v[i].x - v[i].r - 1, -1);
    } else {
      for (int j = max(0, v[i].iq - k); j <= v[i].iq + k; j++) {
        if (roots.find(j) == roots.end()) continue;
        ans += get(roots[j], 1, inf, max(1, v[i].x - v[i].r),
                   min(inf, v[i].x + v[i].r));
      }
      ans--;
    }
  }
  cout << ans / 2 << endl;
  return 0;
}
