#include <bits/stdc++.h>
using namespace std;
struct Query {
  int l, r, b, q;
};
int N, K;
int X[100005], R[100005], Q[100005];
int X2[100005], R2[100005], Q2[100005];
int Xrad[100005], SA[100005], SA2[100005];
set<int> Avail;
vector<Query> Qs;
bool CMP(Query i, Query j) { return i.b < j.b; }
bool CMP2(int i, int j) { return Xrad[i] < Xrad[j]; }
bool CMP3(int i, int j) { return X2[i] < X2[j]; }
unordered_map<int, int> Root;
int nn = 1;
int va[20 * 100005], lc[20 * 100005], rc[20 * 100005];
void up(int& P, int idx, int val, int L = 0, int R = N - 1) {
  if (!P) P = nn++;
  va[P]++;
  if (L == R) return;
  int Mid = (L + R) >> 1;
  if (idx <= Mid)
    up(lc[P], idx, val, L, Mid);
  else
    up(rc[P], idx, val, Mid + 1, R);
}
int Count(int QL, int QR, int& P, int L = 0, int R = N - 1) {
  if (!P || R < QL || QR < L) return 0;
  if (QL <= L && R <= QR) return va[P];
  int Mid = (L + R) >> 1;
  return Count(QL, QR, lc[P], L, Mid) + Count(QL, QR, rc[P], Mid + 1, R);
}
void Update(int idx) { up(Root[Q[idx]], idx, Q[idx]); }
int Query(int QL, int QR, int q) { return Count(QL, QR, Root[q]); }
int main() {
  scanf("%d%d", &N, &K);
  for (int i = 0; i < N; i++) {
    scanf("%d%d%d", &X2[i], &R2[i], &Q2[i]);
    Avail.insert(Q2[i]);
  }
  iota(SA2, SA2 + N, 0);
  sort(SA2, SA2 + N, CMP3);
  for (int i = 0; i < N; i++) {
    X[i] = X2[SA2[i]];
    R[i] = R2[SA2[i]];
    Q[i] = Q2[SA2[i]];
    Xrad[i] = X[i] - R[i];
  }
  int st, en;
  for (int i = 0; i < N; i++) {
    st = i + 1;
    en = upper_bound(X, X + N, X[i] + R[i]) - X - 1;
    if (en < st) continue;
    for (int j = Q[i] - K; j <= Q[i] + K; j++)
      if (Avail.find(j) != Avail.end()) Qs.push_back({st, en, X[i], j});
  }
  iota(SA, SA + N, 0);
  sort(SA, SA + N, CMP2);
  sort(Qs.begin(), Qs.end(), CMP);
  int ptr = 0;
  long long Ans = 0LL;
  for (auto j : Qs) {
    while (ptr < N && Xrad[SA[ptr]] <= j.b) Update(SA[ptr++]);
    Ans += Query(j.l, j.r, j.q);
  }
  printf("%I64d\n", Ans);
}
