#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
inline long long getint() {
  long long _x = 0, _tmp = 1;
  char _tc = getchar();
  while ((_tc < '0' || _tc > '9') && _tc != '-') _tc = getchar();
  if (_tc == '-') _tc = getchar(), _tmp = -1;
  while (_tc >= '0' && _tc <= '9') _x *= 10, _x += (_tc - '0'), _tc = getchar();
  return _x * _tmp;
}
inline long long add(long long _x, long long _y,
                     long long _mod = 1000000007LL) {
  _x += _y;
  return _x >= _mod ? _x - _mod : _x;
}
inline long long sub(long long _x, long long _y,
                     long long _mod = 1000000007LL) {
  _x -= _y;
  return _x < 0 ? _x + _mod : _x;
}
inline long long mul(long long _x, long long _y,
                     long long _mod = 1000000007LL) {
  _x *= _y;
  return _x >= _mod ? _x % _mod : _x;
}
long long mypow(long long _a, long long _x, long long _mod) {
  if (_x == 0) return 1LL;
  long long _ret = mypow(mul(_a, _a, _mod), _x >> 1, _mod);
  if (_x & 1) _ret = mul(_ret, _a, _mod);
  return _ret;
}
long long mymul(long long _a, long long _x, long long _mod) {
  if (_x == 0) return 0LL;
  long long _ret = mymul(add(_a, _a, _mod), _x >> 1, _mod);
  if (_x & 1) _ret = add(_ret, _a, _mod);
  return _ret;
}
inline bool equal(double _x, double _y) {
  return _x > _y - 1e-9 && _x < _y + 1e-9;
}
int __ = 1, _cs;
struct Nd {
  int sum, tl, tr;
  Nd() { sum = tl = tr = 0; }
} nd[101010 * 30 * 4];
int nid;
int new_node() { return ++nid; }
inline int Sum(int x) { return x ? nd[x].sum : 0; }
void modify(int now, int l, int r, int p) {
  if (l == r) {
    nd[now].sum++;
    return;
  }
  if (p <= ((l + r) >> 1)) {
    if (!nd[now].tl) nd[now].tl = new_node();
    modify(nd[now].tl, l, ((l + r) >> 1), p);
  } else {
    if (!nd[now].tr) nd[now].tr = new_node();
    modify(nd[now].tr, ((l + r) >> 1) + 1, r, p);
  }
  nd[now].sum = Sum(nd[now].tl) + Sum(nd[now].tr);
}
int query(int now, int l, int r, int ql, int qr) {
  if (!now || r < ql || l > qr) return 0;
  if (ql <= l && r <= qr) return nd[now].sum;
  return query(nd[now].tl, l, ((l + r) >> 1), ql, qr) +
         query(nd[now].tr, ((l + r) >> 1) + 1, r, ql, qr);
}
int rt[10101];
void build() {}
int n, k, maxx, maxf;
vector<pair<int, pair<int, int> > > v;
void init() {
  n = getint();
  k = getint();
  for (int i = 0; i < n; i++) {
    int xi = getint();
    int ri = getint();
    int fi = getint();
    maxx = max(maxx, xi);
    maxf = max(maxf, fi);
    v.push_back({ri, {xi, fi}});
  }
}
void solve() {
  sort(v.begin(), v.end());
  reverse(v.begin(), v.end());
  long long ans = 0;
  for (auto i : v) {
    int nr = i.first;
    int nx = i.second.first;
    int nf = i.second.second;
    int lx = max(1, nx - nr), rx = min(maxx, nx + nr);
    int lf = max(1, nf - k), rf = min(maxf, nf + k);
    for (int j = lf; j <= rf; j++) ans += query(rt[j], 1, maxx, lx, rx);
    if (!rt[nf]) rt[nf] = new_node();
    modify(rt[nf], 1, maxx, nx);
  }
  printf("%lld\n", ans);
}
int main() {
  build();
  while (__--) {
    init();
    solve();
  }
}
