#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x) {
  x = 0;
  char c = getchar();
  bool flag = false;
  while (!isdigit(c)) {
    if (c == '-') flag = true;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 1) + (x << 3) + (c ^ 48);
    c = getchar();
  }
  if (flag) x = -x;
}
int n, k, tot;
long long ans;
int tr[300010], x[300010];
struct node {
  int pos, x, y, r, q;
} t[300010];
bool cmp1(const node &a, const node &b) { return a.r > b.r; }
bool cmp2(const node &a, const node &b) { return a.q < b.q; }
void update(int x, int v) {
  while (x <= tot) tr[x] += v, x += (x & (-x));
}
int query(int x) {
  int sum = 0;
  while (x) sum += tr[x], x -= (x & (-x));
  return sum;
}
void cdq(int l, int r) {
  if (l == r) return;
  int mid = (l + r) >> 1, p1 = l, p2 = l;
  cdq(l, mid), cdq(mid + 1, r);
  for (int i = mid + 1; i <= r; ++i) {
    while (p1 <= mid && t[p1].q < t[i].q - k) update(t[p1++].pos, -1);
    while (p2 <= mid && t[p2].q <= t[i].q + k) update(t[p2++].pos, 1);
    ans += query(t[i].y) - query(t[i].x - 1);
  }
  for (int i = p1; i < p2; ++i) update(t[i].pos, -1);
  sort(t + l, t + r + 1, cmp2);
}
int main() {
  read(n), read(k);
  for (int i = 1; i <= n; ++i) {
    read(t[i].pos), read(t[i].r), read(t[i].q);
    x[i] = t[i].pos, x[i + n] = t[i].pos - t[i].r,
    x[i + 2 * n] = t[i].pos + t[i].r;
  }
  sort(t + 1, t + n + 1, cmp1), sort(x + 1, x + 3 * n + 1),
      tot = unique(x + 1, x + 3 * n + 1) - x - 1;
  for (int i = 1; i <= n; ++i) {
    t[i].x = lower_bound(x + 1, x + tot + 1, t[i].pos - t[i].r) - x;
    t[i].y = upper_bound(x + 1, x + tot + 1, t[i].pos + t[i].r) - x - 1;
    t[i].pos = lower_bound(x + 1, x + tot + 1, t[i].pos) - x;
  }
  cdq(1, n), printf("%lld", ans);
  return 0;
}
