#include <bits/stdc++.h>
using namespace std;
int N;
vector<int> x, r;
void UpdateFw(vector<int> &fw, int x, int diff) {
  int MAXX = fw.size() - 1;
  for (int i = x; i <= MAXX; i += i & -i) {
    fw[i] += diff;
    if (i > (MAXX - (i & -i))) {
      break;
    }
  }
}
int64_t SumFw(const vector<int> &fw, int x) {
  int64_t res = 0;
  for (int i = x; i > 0; i -= i & -i) {
    res += fw[i];
  }
  return res;
}
int64_t QueryFw(const vector<int> &fw, int xmin, int xmax) {
  if (xmax < xmin) {
    return 0;
  }
  return SumFw(fw, xmax) - SumFw(fw, xmin - 1);
}
bool IsLess(const int i, const int j) {
  int pi = i % N, pj = j % N;
  int ti = i / N, tj = j / N;
  int vi = x[pi], vj = x[pj];
  if (ti == 0) {
    vi -= r[pi];
  } else if (ti == 2) {
    vi += r[pi];
  }
  if (tj == 0) {
    vj -= r[pj];
  } else if (tj == 2) {
    vj += r[pj];
  }
  if (vi != vj) {
    return vi < vj;
  } else {
    return ti < tj;
  }
}
void CalcRank(const vector<int> &a, vector<int> &id2rank,
              vector<int> &rank2id) {
  int n = a.size();
  vector<pair<int, int> > b(n);
  for (int i = 0; i < n; i++) {
    b[i] = make_pair(a[i], i);
  }
  sort(b.begin(), b.end());
  for (int i = 0; i < n; i++) {
    id2rank[b[i].second] = i;
    rank2id[i] = b[i].second;
  }
  return;
}
int CalcRankUniqe(const vector<int> &a, vector<int> &id2rank,
                  vector<int> &rank2id) {
  int n = a.size();
  vector<pair<int, int> > b(n);
  for (int i = 0; i < n; i++) {
    b[i] = make_pair(a[i], i);
  }
  sort(b.begin(), b.end());
  int rank = 0;
  for (int i = 0; i < n; i++) {
    if (i > 0 && b[i].first != b[i - 1].first) {
      rank++;
    }
    id2rank[b[i].second] = rank;
    rank2id[rank] = b[i].second;
  }
  return rank + 1;
}
int main(int argc, char **argv) {
  int K;
  scanf("%d%d", &N, &K);
  const int NMAX = 1e5l;
  vector<int> q(N);
  x.resize(N);
  r.resize(N);
  for (int i = 0; i < N; i++) {
    scanf("%d%d%d", &x[i], &r[i], &q[i]);
  }
  vector<int> qid2rnk(N), qrnk2id(N);
  int rnksize = CalcRankUniqe(q, qid2rnk, qrnk2id);
  vector<vector<int> > gqx(rnksize, vector<int>(1, -1)),
      gqxid(rnksize, vector<int>(1, -1));
  vector<int> xid2qxrnk(N);
  for (int i = 0; i < N; i++) {
    int qrank = qid2rnk[i];
    gqx[qrank].push_back(x[i]);
    gqxid[qrank].push_back(i);
  }
  vector<vector<int> > fw(rnksize);
  for (int qrank = 0; qrank < rnksize; qrank++) {
    int m = gqx[qrank].size();
    vector<int> gqrnk2id(m), gqid2rnk(m);
    CalcRank(gqx[qrank], gqid2rnk, gqrnk2id);
    for (int j = 1; j < m; j++) {
      xid2qxrnk[gqxid[qrank][j]] = gqid2rnk[j];
    }
    sort(gqx[qrank].begin() + 1, gqx[qrank].end());
    fw[qrank] = vector<int>(m, 0);
  }
  gqxid.clear();
  vector<int> id(3 * N);
  for (int i = 0; i < N; i++) {
    id[i] = i;
    id[N + i] = N + i;
    id[N + N + i] = N + N + i;
  }
  sort(id.begin(), id.end(), IsLess);
  int64_t res = 0;
  for (int i = 0; i < 3 * N; i++) {
    int ti = id[i] / N;
    int bi = id[i] % N;
    int xi = x[bi], ri = r[bi], qi = q[bi];
    int qpos = qid2rnk[bi];
    int xpos = xid2qxrnk[bi];
    if (ti == 0) {
      UpdateFw(fw[qpos], xpos, 1);
    } else if (ti == 1) {
      vector<int> qps(1, qpos);
      int qkmin = max(0, qi - K), qkmax = min(qi + K, 1000000000);
      for (int d = 1; d <= rnksize; d++) {
        int cnt = 0;
        int qjpos = qpos - d;
        if (qjpos >= 0 && qjpos < rnksize) {
          int v = q[qrnk2id[qjpos]];
          if (v >= qkmin && v <= qkmax) {
            qps.push_back(qjpos);
            cnt++;
          }
        }
        qjpos = qpos + d;
        if (qjpos >= 0 && qjpos < rnksize) {
          int v = q[qrnk2id[qjpos]];
          if (v >= qkmin && v <= qkmax) {
            qps.push_back(qjpos);
            cnt++;
          }
        }
        if (cnt == 0) {
          break;
        }
      }
      for (int j = 0; j < qps.size(); j++) {
        int qjpos = qps[j];
        if (gqx[qjpos].size() < 2) {
          continue;
        }
        int xmin = max(0, xi - ri);
        int xmax = min(xi + ri, 1000000000);
        int xminpos =
            lower_bound(gqx[qjpos].begin() + 1, gqx[qjpos].end(), xmin) -
            gqx[qjpos].begin();
        int xmaxpos =
            upper_bound(gqx[qjpos].begin() + 1, gqx[qjpos].end(), xmax) -
            gqx[qjpos].begin() - 1;
        res += QueryFw(fw[qjpos], xminpos, xmaxpos);
      }
    } else {
      UpdateFw(fw[qpos], xpos, -1);
    }
  }
  res -= N;
  res >>= 1;
  printf("%" PRId64 "\n", res);
  return 0;
}
