#include <bits/stdc++.h>
using namespace std;
char buf[1 << 20], *p1, *p2;
inline int rd() {
  int w = 0, x = 0;
  char ch = 0;
  while (!isdigit(ch)) {
    w |= ch == '-';
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 3) + (x << 1) + (ch ^ 48);
    ch = getchar();
  }
  return w ? -x : x;
}
const int maxn = 1e5 + 110, maxf = 1e4 + 110, NlogN = 5e6;
struct node {
  int x, r, f;
  bool operator<(const node &b) const { return r > b.r; }
} data[maxn];
int root[maxf], n, k, mx;
int ls[NlogN], rs[NlogN], val[NlogN], tot;
inline void push_up(int i) {
  val[i] = 0;
  if (ls[i]) val[i] += val[ls[i]];
  if (rs[i]) val[i] += val[rs[i]];
}
inline void ins(int i, int l, int r, int x) {
  if (l == r) {
    val[i]++;
    return;
  }
  int mid = l + r >> 1;
  if (x <= mid) {
    if (!ls[i]) ls[i] = ++tot;
    ins(ls[i], l, mid, x);
  } else {
    if (!rs[i]) rs[i] = ++tot;
    ins(rs[i], mid + 1, r, x);
  }
  push_up(i);
}
inline int query(int i, int l, int r, int L, int R) {
  if (l >= L && r <= R) return val[i];
  int mid = l + r >> 1, res = 0;
  if (ls[i] && mid >= L) res += query(ls[i], l, mid, L, R);
  if (rs[i] && mid < R) res += query(rs[i], mid + 1, r, L, R);
  return res;
}
int main() {
  n = rd();
  k = rd();
  for (int i = 1; i <= n; i++) {
    data[i].x = rd();
    data[i].r = rd();
    data[i].f = rd();
    mx = max(mx, data[i].x);
    if (!root[data[i].f]) root[data[i].f] = ++tot;
  }
  sort(data + 1, data + n + 1);
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = max(data[i].f - k, 1); j <= data[i].f + k; j++) {
      ans += (long long)query(root[j], 1, mx, max(0, data[i].x - data[i].r),
                              min(mx, data[i].x + data[i].r));
    }
    ins(root[data[i].f], 1, mx, data[i].x);
  }
  printf("%lld\n", ans);
  return 0;
}
