#include <bits/stdc++.h>
using namespace std;
const int maxn = 102000;
int n, k;
struct node {
  int x, r, q, nb;
} A[maxn];
struct edge {
  int x, r, dr;
};
vector<node> vec[maxn];
vector<edge> ff[maxn];
int cmp(node a, node b) { return a.x < b.x; }
int cmpp(edge a, edge b) { return a.x < b.x; }
int IQ[maxn], iqsz;
int lisan[maxn], num;
int C[maxn];
int lowbit(int x) { return x & -x; }
int query(int now) {
  int res = 0;
  while (now) {
    res += C[now];
    now -= lowbit(now);
  }
  return res;
}
void add(int now, int dt) {
  while (now <= num) {
    C[now] += dt;
    now += lowbit(now);
  }
}
void read() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) scanf("%d%d%d", &A[i].x, &A[i].r, &A[i].q);
  for (int i = 1; i <= n; i++) IQ[i] = A[i].q;
  for (int i = 1; i <= n; i++) lisan[i] = A[i].r;
}
void init() {
  sort(IQ + 1, IQ + n + 1);
  iqsz = unique(IQ + 1, IQ + n + 1) - IQ - 1;
  sort(lisan + 1, lisan + n + 1);
  num = unique(lisan + 1, lisan + n + 1) - lisan - 1;
  for (int i = 1; i <= n; i++)
    A[i].nb = lower_bound(IQ + 1, IQ + iqsz + 1, A[i].q) - IQ;
  for (int i = 1; i <= n; i++) vec[A[i].nb].push_back(A[i]);
  for (int i = 1; i <= iqsz; i++) sort(vec[i].begin(), vec[i].end(), cmp);
  for (int i = 1; i <= n; i++) {
    int z = A[i].nb;
    for (int j = z - 1; j >= max(0, z - k); j--) {
      if (A[i].q - IQ[j] <= k) {
        ff[j].push_back((edge){A[i].x - A[i].r - 1, A[i].r, -1});
        ff[j].push_back((edge){A[i].x + A[i].r, A[i].r, 1});
      }
    }
    for (int j = z + 1; j <= min(iqsz, z + k); j++) {
      if (abs(A[i].q - IQ[j]) <= k) {
        ff[j].push_back((edge){A[i].x - A[i].r - 1, A[i].r - 1, -1});
        ff[j].push_back((edge){A[i].x + A[i].r, A[i].r - 1, 1});
      }
    }
    ff[z].push_back((edge){A[i].x - A[i].r - 1, A[i].r, -1});
    ff[z].push_back((edge){A[i].x, A[i].r, 1});
    ff[z].push_back((edge){A[i].x + A[i].r, A[i].r - 1, 1});
    ff[z].push_back((edge){A[i].x, A[i].r - 1, -1});
  }
  for (int i = 1; i <= iqsz; i++) sort(ff[i].begin(), ff[i].end(), cmpp);
}
long long totans;
void work() {
  for (int i = 1; i <= iqsz; i++) {
    int pt = 0;
    for (int j = 0; j < vec[i].size(); j++) {
      vec[i][j].r =
          lower_bound(lisan + 1, lisan + num + 1, vec[i][j].r) - lisan;
      while (pt < ff[i].size() && ff[i][pt].x < vec[i][j].x) {
        ff[i][pt].r =
            upper_bound(lisan + 1, lisan + num + 1, ff[i][pt].r) - lisan - 1;
        totans += ff[i][pt].dr * (query(num) - query(ff[i][pt].r));
        pt++;
      }
      add(vec[i][j].r, 1);
    }
    while (pt < ff[i].size()) {
      ff[i][pt].r =
          upper_bound(lisan + 1, lisan + num + 1, ff[i][pt].r) - lisan - 1;
      totans += ff[i][pt].dr * (query(num) - query(ff[i][pt].r));
      pt++;
    }
    for (int j = 0; j < vec[i].size(); j++) {
      add(vec[i][j].r, -1);
    }
  }
  for (int i = 1; i <= iqsz; i++) {
    for (int j = 0; j < vec[i].size(); j++) {
      int nxt = j, hh = 1;
      while (nxt + 1 < vec[i].size() && vec[i][nxt + 1].r == vec[i][j].r &&
             vec[i][nxt + 1].x == vec[i][j].x)
        hh++, nxt++;
      totans += (1ll * hh * hh - hh) / 2;
      j = nxt;
    }
  }
  printf("%I64d\n", totans);
}
int main() {
  read();
  init();
  work();
  return 0;
}
