#include <bits/stdc++.h>
using namespace std;
vector<int> vt;
vector<vector<int>> vt1;
pair<pair<int, int>, int> q[100010];
vector<int> seg[5000010];
int getidx(int x) { return lower_bound(vt.begin(), vt.end(), x) - vt.begin(); }
int getidx1(int here, int x) {
  return lower_bound(vt1[here].begin(), vt1[here].end(), x) - vt1[here].begin();
}
int update(int ch, int pos, int val, int node, int x, int y) {
  if (pos < x || y < pos) return seg[ch][node];
  if (x == y) return seg[ch][node] += val;
  int mid = (x + y) / 2;
  return seg[ch][node] = update(ch, pos, val, node * 2, x, mid) +
                         update(ch, pos, val, node * 2 + 1, mid + 1, y);
}
int query(int ch, int lo, int hi, int node, int x, int y) {
  if (hi < x || y < lo) return 0;
  if (lo <= x && y <= hi) return seg[ch][node];
  int mid = (x + y) / 2;
  return query(ch, lo, hi, node * 2, x, mid) +
         query(ch, lo, hi, node * 2 + 1, mid + 1, y);
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d %d %d", &q[i].first.second, &q[i].first.first, &q[i].second);
    for (int y = q[i].second - m; y <= q[i].second + m; y++) vt.push_back(y);
  }
  sort(vt.begin(), vt.end());
  vt.erase(unique(vt.begin(), vt.end()), vt.end());
  vt1.resize(vt.size());
  for (int i = 0; i < n; i++) {
    vt1[getidx(q[i].second)].push_back(q[i].first.second);
  }
  for (int i = 0; i < vt.size(); i++) {
    sort(vt1[i].begin(), vt1[i].end());
    vt1[i].erase(unique(vt1[i].begin(), vt1[i].end()), vt1[i].end());
    seg[i].resize(vt1[i].size() * 4);
  }
  sort(q, q + n);
  reverse(q, q + n);
  long long dap = 0;
  for (int i = 0; i < n; i++) {
    for (int y = q[i].second - m; y <= q[i].second + m; y++) {
      int level = getidx(y);
      if (vt1[level].size() == 0) continue;
      int xx = lower_bound(vt1[level].begin(), vt1[level].end(),
                           q[i].first.second - q[i].first.first) -
               vt1[level].begin();
      int yy = upper_bound(vt1[level].begin(), vt1[level].end(),
                           q[i].first.second + q[i].first.first) -
               vt1[level].begin();
      yy--;
      if (xx <= yy)
        dap += (long long)query(level, xx, yy, 1, 0, vt1[level].size());
    }
    int level = getidx(q[i].second);
    update(level, getidx1(level, q[i].first.second), 1, 1, 0,
           vt1[level].size());
  }
  printf("%lld\n", dap);
}
