#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
struct Node *nil = 0;
struct Node {
  int val, sz, h;
  Node *lc, *rc;
  Node() {}
  Node(int x) : val(x), sz(1), h(rand()), lc(nil), rc(nil) {}
  inline void update() { sz = (lc ? lc->sz : 0) + (rc ? rc->sz : 0) + 1; }
} node[MAXN * 20];
int pnode = 0;
inline Node *newnode(int x) {
  node[pnode] = Node(x);
  return &node[pnode++];
}
Node *merge(Node *a, Node *b) {
  if (!a) return b;
  if (!b) return a;
  if (a->h < b->h) {
    a->rc = merge(a->rc, b), a->update();
    return a;
  } else {
    b->lc = merge(a, b->lc), b->update();
    return b;
  }
}
pair<Node *, Node *> split(Node *p, int k) {
  if (!p) return make_pair(nil, nil);
  if (k >= p->val) {
    pair<Node *, Node *> y = split(p->rc, k);
    p->rc = y.first, p->update();
    return make_pair(p, y.second);
  } else {
    pair<Node *, Node *> y = split(p->lc, k);
    p->lc = y.second, p->update();
    return make_pair(y.first, p);
  }
}
void insert(Node *&root, int k) {
  pair<Node *, Node *> y = split(root, k);
  root = merge(y.first, merge(newnode(k), y.second));
}
void erase(Node *&root, int k) {
  pair<Node *, Node *> y = split(root, k);
  pair<Node *, Node *> x = split(y.first, k - 1);
  if (x.second) x.second = merge(x.second->lc, x.second->rc);
  root = merge(merge(x.first, x.second), y.second);
}
int query(Node *&root, int l, int r) {
  pair<Node *, Node *> y = split(root, r);
  pair<Node *, Node *> x = split(y.first, l - 1);
  int ret = (x.second ? x.second->sz : 0);
  root = merge(merge(x.first, x.second), y.second);
  return ret;
}
int N = 0;
Node *root[MAXN << 1];
inline int lowbit(int x) { return x & -x; }
void insert(int pos, int val) {
  for (int i = pos; i <= N; i += lowbit(i)) insert(root[i], val);
}
void erase(int pos, int val) {
  for (int i = pos; i <= N; i += lowbit(i)) erase(root[i], val);
}
int query(int pos, int l, int r) {
  int ret = 0;
  for (int i = pos; i > 0; i ^= lowbit(i)) ret += query(root[i], l, r);
  return ret;
}
struct Opt {
  int tp, x, id, q;
  Opt() {}
  Opt(int a, int b, int c, int d) : tp(a), x(b), id(c), q(d) {}
};
bool operator<(const Opt &a, const Opt &b) {
  return (a.x == b.x ? a.tp < b.tp : a.x < b.x);
}
vector<Opt> opt;
int n, k, x[MAXN], r[MAXN], q[MAXN];
long long res = 0;
map<int, int> cnt;
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &x[i], &r[i], &q[i]);
    opt.emplace_back(Opt(1, x[i], i, q[i]));
    opt.emplace_back(Opt(-1, x[i] + r[i] + 1, i, q[i]));
    cnt[x[i]] = 0, cnt[x[i] - r[i] - 1] = 0;
  }
  for (auto &x : cnt) x.second = ++N;
  sort(opt.begin(), opt.end());
  for (auto w : opt) {
    if (w.tp == -1)
      erase(cnt[x[w.id]], w.q);
    else {
      int val = query(cnt[x[w.id]], w.q - k, w.q + k) -
                query(cnt[x[w.id] - r[w.id] - 1], w.q - k, w.q + k);
      res += val;
      insert(cnt[x[w.id]], w.q);
    }
  }
  printf("%I64d\n", res);
  return 0;
}
