#include <bits/stdc++.h>
using namespace std;
const int MAX = (1e5) + 10;
struct Node {
  int key, prio, val, sum;
  Node *l, *r;
  Node(int k, int p) {
    key = k;
    prio = p;
    sum = val = 1;
    l = r = NULL;
  }
};
void update(Node *X) {
  if (X == NULL) return;
  X->sum = X->val;
  if (X->l != NULL) X->sum += X->l->sum;
  if (X->r != NULL) X->sum += X->r->sum;
  return;
}
Node *leftRotate(Node *up, Node *down) {
  up->l = down->r;
  down->r = up;
  update(down);
  update(up);
  return down;
}
Node *rightRotate(Node *up, Node *down) {
  up->r = down->l;
  down->l = up;
  update(down);
  update(up);
  return down;
}
Node *balance(Node *R) {
  if (R->l != NULL && R->l->prio < R->prio)
    return leftRotate(R, R->l);
  else if (R->r != NULL && R->r->prio < R->prio)
    return rightRotate(R, R->r);
  return R;
}
Node *add(Node *R, Node *org) {
  if (R == NULL) return org;
  if (org->key <= R->key)
    R->l = add(R->l, org);
  else
    R->r = add(R->r, org);
  R = balance(R);
  update(R);
  return R;
}
Node *meld(Node *sm, Node *bg) {
  if (sm == NULL)
    return bg;
  else if (bg == NULL)
    return sm;
  else if (sm->prio < bg->prio) {
    sm->r = meld(sm->r, bg);
    update(sm);
    return sm;
  } else {
    bg->l = meld(sm, bg->l);
    update(bg);
    return bg;
  }
}
Node *split(Node *R, int val) {
  if (R == NULL)
    return R;
  else if (R->key == val) {
    R->prio = -1;
    return R;
  } else if (R->key >= val)
    R->l = split(R->l, val);
  else
    R->r = split(R->r, val);
  R = balance(R);
  return R;
}
Node *eraseX(Node *R, int x) {
  if (R == NULL) return R;
  R = split(R, x);
  if (R->key != x)
    return R;
  else if (R->l == NULL)
    return R->r;
  else if (R->r == NULL)
    return R->l;
  else
    return meld(R->l, R->r);
}
int getSum(Node *t, int low) {
  if (t == NULL) return 0;
  if (t->key <= low) {
    int ret = t->val;
    if (t->l != NULL) ret += t->l->sum;
    return getSum(t->r, low) + ret;
  } else
    return getSum(t->l, low);
}
struct Q {
  int x, r, f;
} ara[MAX];
vector<int> out[MAX];
int main() {
  ios::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  for (int i = 0; i <= n - 1; i++) cin >> ara[i].x >> ara[i].r >> ara[i].f;
  sort(ara, ara + n, [](Q x, Q y) { return x.x < y.x; });
  for (int i = 0; i <= n - 1; i++) {
    int st = i, en = n - 1, can = i;
    while (st <= en) {
      int mid = (st + en) >> 1;
      if (ara[mid].x - ara[i].x <= ara[i].r)
        st = mid + 1, can = max(can, mid);
      else
        en = mid - 1;
    }
    out[can + 1].push_back(i);
  }
  vector<Node *> R((1e4) + 15, nullptr);
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  vector<int> per(n);
  for (int i = 0; i < n; i++) per[i] = i;
  shuffle(per.begin(), per.end(), rng);
  long long prin = 0;
  for (int p = 0; p <= n - 1; p++) {
    for (int pos : out[p]) {
      int x = ara[pos].x, r = ara[pos].r, f = ara[pos].f;
      R[f] = eraseX(R[f], x);
    }
    int x = ara[p].x, r = ara[p].r, f = ara[p].f;
    for (int i = f - k; i <= f + k; i++) {
      if (i <= 0 || R[i] == nullptr) continue;
      int v = (R[i]->sum - getSum(R[i], (x - r) - 1));
      prin += v;
    }
    R[f] = add(R[f], new Node(x, per[p]));
  }
  cout << prin << endl;
  return 0;
}
