#include <bits/stdc++.h>
using namespace std;
int nxi() {
  int a;
  cin >> a;
  return a;
}
vector<int> dsu;
int dsu_get(int v) { return (v == dsu[v]) ? v : (dsu[v] = dsu_get(dsu[v])); }
void dsu_join(int a, int b) {
  a = dsu_get(a);
  b = dsu_get(b);
  if (rand() & 1) swap(a, b);
  if (a != b) dsu[a] = b;
}
vector<long long> a;
void inc(int i, int v) {
  for (; i < a.size(); i |= i + 1) {
    a[i] += v;
  }
}
long long get(int r) {
  long long ans = 0;
  for (; r >= 0; r = (r & (r + 1)) - 1) {
    ans += a[r];
  }
  return ans;
}
long long get(int l, int r) { return get(r) - get(l - 1); }
struct s_station {
  int x, r, f;
  bool operator<(const s_station& s2) { return x < s2.x; }
};
bool operator<(const s_station& s1, const s_station& s2) { return s1.x < s2.x; }
int main() {
  int n = nxi(), k = nxi();
  vector<s_station> a(n);
  for (auto& s : a) {
    scanf("%d%d%d", &s.x, &s.r, &s.f);
  }
  sort(a.begin(), a.end());
  vector<vector<s_station>> fth(10011);
  vector<vector<vector<int>>> tr(10011);
  for (auto& t : a) {
    fth[t.f].push_back(t);
  }
  for (int i = 0; i <= 10000; ++i) {
    int len = fth[i].size();
    if (!len) continue;
    tr[i].assign(len * 4, vector<int>());
    const std::function<void(const int, const int, const int)> build =
        [&](const int ind, const int l, const int r) {
          if (l == r) {
            tr[i][ind].push_back(fth[i][l].x - fth[i][l].r);
            return;
          }
          int m = (l + r) / 2;
          build(2 * ind, l, m);
          build(2 * ind + 1, m + 1, r);
          int l1 = tr[i][2 * ind].size(), l2 = tr[i][2 * ind + 1].size();
          int j1 = 0, j2 = 0;
          for (int j = 0; j < l1 + l2; ++j) {
            if (j1 < l1 &&
                (j2 == l2 || tr[i][2 * ind][j1] < tr[i][2 * ind + 1][j2])) {
              tr[i][ind].push_back(tr[i][2 * ind][j1]);
              ++j1;
            } else {
              tr[i][ind].push_back(tr[i][2 * ind + 1][j2]);
              ++j2;
            }
          }
        };
    build(1, 0, len - 1);
  }
  const std::function<int(const int, const int, const int, const int, const int,
                          const int, const int)>
      find = [&](const int fq, const int ind, const int lt, const int rt,
                 const int l, const int r, const int x) -> int {
    if (r < l) return 0;
    if (l == lt && r == rt) {
      auto it = upper_bound(tr[fq][ind].begin(), tr[fq][ind].end(), x);
      return (it - tr[fq][ind].begin());
    }
    int m = (lt + rt) / 2;
    int res1 = find(fq, 2 * ind, lt, m, l, min(m, r), x);
    int res2 = find(fq, 2 * ind + 1, m + 1, rt, max(l, m + 1), r, x);
    return res1 + res2;
  };
  long long ans = 0;
  for (int i = 0; i <= 10000; ++i) {
    int len = fth[i].size();
    if (!len) continue;
    for (int fq = max(1, i - k); fq <= i + k; ++fq) {
      if (fth[fq].empty()) continue;
      for (int j = 0; j < len; ++j) {
        s_station s(fth[i][j]);
        auto it1 = upper_bound(fth[fq].begin(), fth[fq].end(), s);
        s.x += fth[i][j].r;
        auto it2 = lower_bound(fth[fq].begin(), fth[fq].end(), s);
        if (it2 == fth[fq].end()) --it2;
        if (it2 > fth[fq].begin() && it2->x > s.x) --it2;
        if (it1 == fth[fq].end() || it2 < it1 || it2->x > s.x) continue;
        int res = find(fq, 1, 0, fth[fq].size() - 1, it1 - fth[fq].begin(),
                       it2 - fth[fq].begin(), fth[i][j].x);
        ans += res;
      }
    }
  }
  cout << ans;
  return 0;
}
