#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int NINF = 0xc0c0c0c0;
const int maxn = 1e5 + 5;
const int maxm = (maxn << 2) + 2e6;
struct Node {
  int x, r, q;
  bool operator<(const Node &A) const { return r > A.r; }
};
Node a[maxn];
map<int, int> Hashq, Hashx;
int root[maxn];
long long sum[maxm];
int lch[maxm], rch[maxm];
int dfn;
void build(int &k, int l, int r) {
  k = ++dfn;
  sum[k] = 0;
  if (l == r) return;
  int mid = l + r >> 1;
  build(lch[k], l, mid);
  build(rch[k], mid + 1, r);
}
inline void pushup(int k) { sum[k] = sum[lch[k]] + sum[rch[k]]; }
inline void newnode(int old, int k) {
  sum[k] = sum[old];
  lch[k] = lch[old];
  rch[k] = rch[old];
}
void update(int old, int &k, int l, int r, int p, int x) {
  k = ++dfn;
  newnode(old, k);
  if (l == r) {
    sum[k] += x;
    return;
  }
  int mid = l + r >> 1;
  if (p <= mid) update(lch[old], lch[k], l, mid, p, x);
  if (mid + 1 <= p) update(rch[old], rch[k], mid + 1, r, p, x);
  pushup(k);
}
long long query(int k, int l, int r, int L, int R) {
  if (L <= l && R >= r) return sum[k];
  int mid = l + r >> 1;
  long long ret = 0;
  if (L <= mid) ret += query(lch[k], l, mid, L, R);
  if (mid + 1 <= R) ret += query(rch[k], mid + 1, r, L, R);
  return ret;
}
int main() {
  std::ios::sync_with_stdio(false);
  int n, m;
  scanf("%d%d", &n, &m);
  vector<int> X;
  for (int i = 0; i < n; i++)
    scanf("%d%d%d", &a[i].x, &a[i].r, &a[i].q), X.push_back(a[i].x);
  (sort(X.begin(), X.end())),
      X.resize(distance(X.begin(), unique(X.begin(), X.end())));
  int N = X.size();
  for (int i = 0; i < n; i++) {
    int pos = lower_bound(X.begin(), X.end(), a[i].x) - X.begin();
    Hashx[a[i].x] = pos;
  }
  sort(a, a + n);
  dfn = 0;
  int tot = 0;
  long long ans = 0;
  build(root[tot++], 0, N - 1);
  for (int i = 0; i < n; i++) {
    int base = max(0, a[i].q - m);
    int top = a[i].q + m;
    for (int j = base; j <= top; j++) {
      if (Hashq.find(j) == Hashq.end()) continue;
      int l = lower_bound(X.begin(), X.end(), a[i].x - a[i].r) - X.begin();
      int r = upper_bound(X.begin(), X.end(), a[i].x + a[i].r) - X.begin() - 1;
      ans += query(root[Hashq[j]], 0, N - 1, l, r);
    }
    int old = root[Hashq[a[i].q]];
    Hashq[a[i].q] = tot++;
    update(old, root[Hashq[a[i].q]], 0, N - 1, Hashx[a[i].x], 1);
  }
  printf("%lld\n", ans);
}
