#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, INF = 1e9 + 10;
int m, k;
long long ans;
int tmp[N], t[N];
struct robot {
  int pos, r, q;
  int lt, rt;
} rt[N];
inline bool cmp(robot x, robot y) { return x.r < y.r; }
inline int lowbit(int x) { return x & (-x); }
inline void change(int x, int c) {
  for (int i = x; i <= m; i += lowbit(i)) t[i] += c;
}
inline int query(int x) {
  int res = 0;
  for (int i = x; i >= 1; i -= lowbit(i)) res += t[i];
  return res;
}
struct node {
  int a, b, c1, c2;
  int type;
  bool operator<(const node &x) const {
    if (b == x.b)
      return type > x.type;
    else
      return b < x.b;
  }
} v[3 * N], w[3 * N];
inline void CDQ(int l, int r) {
  if (l == r) return;
  int mid = (l + r) / 2, p = l, q = mid + 1;
  CDQ(l, mid), CDQ(mid + 1, r);
  for (int i = l; i <= r; i++) {
    if ((p <= mid && v[p] < v[q]) || q > r) {
      if (v[p].type == 2) change(v[p].c1, 1);
      w[i] = v[p++];
    } else {
      if (v[q].type != 2) ans += v[q].type * (query(v[q].c2) - query(v[q].c1));
      w[i] = v[q++];
    }
  }
  for (int i = l; i <= mid; i++)
    if (v[i].type == 2) change(v[i].c1, -1);
  for (int i = l; i <= r; i++) v[i] = w[i];
}
int main() {
  int n, tot = 0;
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &rt[i].pos, &rt[i].r, &rt[i].q);
    tmp[++m] = rt[i].q;
  }
  tmp[++m] = INF;
  sort(tmp + 1, tmp + m + 1);
  m = unique(tmp + 1, tmp + m + 1) - (tmp + 1);
  for (int i = 1; i <= n; i++) {
    rt[i].lt = lower_bound(tmp + 1, tmp + m + 1, rt[i].q - k) - tmp - 1;
    rt[i].rt = upper_bound(tmp + 1, tmp + m + 1, rt[i].q + k) - tmp - 1;
    rt[i].q = lower_bound(tmp + 1, tmp + m + 1, rt[i].q) - tmp;
  }
  sort(rt + 1, rt + n + 1, cmp);
  for (int i = n; i >= 1; i--) {
    v[++tot] = (node){tot, rt[i].pos - rt[i].r - 1, rt[i].lt, rt[i].rt, -1};
    v[++tot] = (node){tot, rt[i].pos + rt[i].r, rt[i].lt, rt[i].rt, 1};
    v[++tot] = (node){tot, rt[i].pos, rt[i].q, rt[i].q, 2};
  }
  CDQ(1, tot);
  printf("%lld\n", ans);
  return 0;
}
