#include <bits/stdc++.h>
using namespace std;
mt19937 randGenerator(27081999);
struct Treap {
  long long key;
  int priority, subtreeSize;
  Treap *left, *right;
  Treap(long long pKey = 0) {
    key = pKey;
    subtreeSize = 1;
    priority = randGenerator();
    left = nullptr;
    right = nullptr;
  }
  void recalc() {
    subtreeSize = 1;
    subtreeSize += (left == nullptr ? 0 : left->subtreeSize);
    subtreeSize += (right == nullptr ? 0 : right->subtreeSize);
  }
  long long find_kth(int k) {
    if (key == k) {
      return 1ll + (right == nullptr ? 0ll : right->subtreeSize);
    } else if (key < k) {
      return (right == nullptr ? 0ll : right->find_kth(k));
    } else {
      return 1ll + (right == nullptr ? 0ll : right->subtreeSize) +
             (left == nullptr ? 0ll : left->find_kth(k));
    }
  }
};
Treap *root[100000] = {nullptr};
Treap *merge(Treap *sm, Treap *bg) {
  if (sm == nullptr) {
    return bg;
  } else if (bg == nullptr) {
    return sm;
  }
  if (sm->priority > bg->priority) {
    sm->right = merge(sm->right, bg);
    sm->recalc();
    return sm;
  } else {
    bg->left = merge(sm, bg->left);
    bg->recalc();
    return bg;
  }
}
pair<Treap *, Treap *> split(Treap *t, long long key) {
  if (t == nullptr) {
    return {nullptr, nullptr};
  }
  if (t->key < key) {
    auto splitResults = split(t->right, key);
    t->right = splitResults.first;
    t->recalc();
    return {t, splitResults.second};
  } else {
    auto splitResults = split(t->left, key);
    t->left = splitResults.second;
    t->recalc();
    return {splitResults.first, t};
  }
}
void add_number(long long x, int i) {
  if (root[i] == nullptr) {
    root[i] = new Treap(x);
    return;
  }
  Treap *newTreap = new Treap(x);
  auto splitResults = split(root[i], x);
  splitResults.first = merge(splitResults.first, newTreap);
  root[i] = merge(splitResults.first, splitResults.second);
}
void remove_number(long long x, int i) {
  auto splitResults1 = split(root[i], x);
  auto splitResults2 = split(splitResults1.second, x + 1);
  root[i] = merge(splitResults1.first, splitResults2.second);
}
long long kth_number(int k, int i) {
  return (root[i] == nullptr ? 0ll : root[i]->find_kth(k));
}
int n, m, k;
struct robot {
  int x, r, q;
  bool operator<(robot rob) const { return x < rob.x; }
};
robot a[100001];
int lx[100001], rx[100001];
int lq[100001], rq[100001];
int iq[100001];
vector<int> IQ;
vector<int> sight[100001];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n >> k;
  for (int i = 0; i < n; i++) {
    cin >> a[i].x >> a[i].r >> a[i].q;
    iq[i] = a[i].q;
  }
  sort(a, a + n);
  robot rob;
  for (int i = 0; i < n; i++) {
    rob.x = a[i].x - a[i].r - 1;
    lx[i] = upper_bound(a, a + n, rob) - a;
    rob.x = a[i].x + a[i].r;
    rx[i] = upper_bound(a, a + n, rob) - a - 1;
    sight[rx[i]].push_back(i);
  }
  sort(iq, iq + n);
  IQ.push_back(iq[0]);
  for (int i = 1; i < n; i++) {
    if (iq[i] != iq[i - 1]) IQ.push_back(iq[i]);
  }
  m = IQ.size();
  for (int i = 0; i < m; i++) {
    lq[i] = upper_bound(IQ.begin(), IQ.end(), IQ[i] - k - 1) - IQ.begin();
    rq[i] = upper_bound(IQ.begin(), IQ.end(), IQ[i] + k) - IQ.begin() - 1;
  }
  long long ans = 0ll;
  for (int i = 0; i < n; i++) {
    a[i].q = lower_bound(IQ.begin(), IQ.end(), a[i].q) - IQ.begin();
    for (int j = lq[a[i].q]; j <= rq[a[i].q]; j++) ans += kth_number(lx[i], j);
    add_number(i, a[i].q);
    for (int j : sight[i]) {
      remove_number(j, a[j].q);
    }
  }
  cout << ans << '\n';
  return 0;
}
