#include <bits/stdc++.h>
using namespace std;
struct splay_node {
  splay_node *parent, *child[2];
  int value;
  int size;
  splay_node() : parent(nullptr), child{nullptr, nullptr}, size(1) {}
  static int get_size(splay_node *x) { return x == nullptr ? 0 : x->size; }
  int parent_index() const { return this == parent->child[0] ? 0 : 1; }
  void set_child(int index, splay_node *x) {
    child[index] = x;
    if (x != nullptr) x->parent = this;
  }
  void join() { size = get_size(child[0]) + get_size(child[1]) + 1; }
};
struct splay_tree {
  static const int POOL_SIZE = 10000;
  static vector<splay_node *> node_pool;
  splay_node *root;
  int tree_size;
  splay_tree() : root(nullptr), tree_size(0) {}
  static splay_node *new_node() {
    if (node_pool.empty()) {
      splay_node *ptr = new splay_node[POOL_SIZE];
      for (int i = 0; i < POOL_SIZE; i++) node_pool.push_back(ptr + i);
    }
    splay_node *node = node_pool.back();
    node_pool.pop_back();
    return node;
  }
  void rotate_up(splay_node *x) {
    splay_node *p = x->parent, *gp = p->parent;
    int index = x->parent_index();
    if (gp == nullptr) {
      x->parent = nullptr;
      root = x;
    } else {
      gp->set_child(p->parent_index(), x);
    }
    p->set_child(index, x->child[!index]);
    x->set_child(!index, p);
    p->join();
  }
  void splay(splay_node *x) {
    while (x != root) {
      splay_node *p = x->parent;
      if (p != root) rotate_up(x->parent_index() == p->parent_index() ? p : x);
      rotate_up(x);
    }
    x->join();
  }
  splay_node *insert(const int &value) {
    splay_node *x = new_node();
    x->value = value;
    tree_size++;
    if (root == nullptr) return root = x;
    splay_node *current = root, *prev = nullptr;
    while (current != nullptr) {
      prev = current;
      current->size++;
      current = current->child[value < current->value ? 0 : 1];
    }
    prev->set_child(value < prev->value ? 0 : 1, x);
    splay(x);
    return x;
  }
  splay_node *root_successor() {
    splay_node *x = root->child[1];
    while (x->child[0] != nullptr) x = x->child[0];
    return x;
  }
  void erase(splay_node *x) {
    splay(x);
    if (x->child[0] == nullptr) {
      root = x->child[1];
    } else if (x->child[1] == nullptr) {
      root = x->child[0];
    } else {
      splay(root_successor());
      assert(root->child[0] == x && x->child[1] == nullptr);
      root->set_child(0, x->child[0]);
      root->size--;
    }
    if (root != nullptr) root->parent = nullptr;
    *x = splay_node();
    node_pool.push_back(x);
    tree_size--;
  }
  splay_node *lower_bound(const int &value) {
    splay_node *current = root, *prev = nullptr, *answer = nullptr;
    while (current != nullptr) {
      prev = current;
      if (current->value < value) {
        current = current->child[1];
      } else {
        answer = current;
        current = current->child[0];
      }
    }
    if (prev != nullptr) splay(prev);
    return answer;
  }
  bool erase(const int &value) {
    splay_node *x = lower_bound(value);
    if (x == nullptr || x->value != value) return false;
    erase(x);
    return true;
  }
  int less_than(const int &value) {
    splay_node *x = lower_bound(value);
    if (x == nullptr) return tree_size;
    splay(x);
    return x->child[0] == nullptr ? 0 : x->child[0]->size;
  }
  int less_equal(const int &value) {
    assert(is_integral<int>::value);
    return less_than(value + 1);
  }
  splay_node *node_at_index(int index) {
    splay_node *current = root;
    while (current != nullptr) {
      int left_size = splay_node::get_size(current->child[0]);
      if (index == left_size) return current;
      if (index < left_size) {
        current = current->child[0];
      } else {
        current = current->child[1];
        index -= left_size + 1;
      }
    }
    return nullptr;
  }
};
vector<splay_node *> splay_tree::node_pool;
struct robot {
  int x, radius, iq;
  bool operator<(const robot &other) const { return radius > other.radius; }
};
int N, K;
vector<robot> robots;
map<int, splay_tree> iq_map;
int main() {
  scanf("%d %d", &N, &K);
  robots.resize(N);
  for (robot &r : robots) scanf("%d %d %d", &r.x, &r.radius, &r.iq);
  sort(robots.begin(), robots.end());
  long long total = 0;
  for (robot &r : robots) {
    for (int iq = r.iq - K; iq <= r.iq + K; iq++)
      if (iq_map.count(iq))
        total += iq_map[iq].less_equal(r.x + r.radius) -
                 iq_map[iq].less_than(r.x - r.radius);
    iq_map[r.iq].insert(r.x);
  }
  printf("%lld\n", total);
}
