#include <bits/stdc++.h>
using namespace std;

#define int long long
#define f(i,n) for(int i=0;i<n;i++)
#define Fast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrand()
{
    uniform_int_distribution<int> uid(0, 999999999999999);
    return uid(rng);
}

struct node{
    int prior,size;
    int val;
    struct node *l,*r;
};

typedef node* pnode;

int sz(pnode t){
    return t?t->size:0;
}

void upd_sz(pnode t){
    if(t)t->size=sz(t->l)+1+sz(t->r);
}

void split(pnode t,pnode &l,pnode &r,int pos){
    if(!t)return void(l=r=NULL);

    int curr_pos = t->val;

    if(curr_pos<=pos)
        split(t->r,t->r,r,pos),l=t;
    else
        split(t->l,l,t->l,pos),r=t;

    upd_sz(t);

}

void merge(pnode &t,pnode l,pnode r){ //l->leftarray,r->rightarray,t->resulting array
    if(!l || !r) t = l?l:r;
    else if(l->prior>r->prior)merge(l->r,l->r,r),t=l;
    else merge(r->l,l,r->l),t=r;

    upd_sz(t);
}

void erase(pnode & t,int key)
{
    if(t-> val == key)
      merge(t,t->l,t->r);

    else
        erase (key < t->val ? t->l : t->r, key);
}

pnode init(int val)
{
    pnode ret = new node();
    ret->prior=getrand();
    ret->size=1;
    ret->val=val;
    return ret;
}

int range_query(pnode t,int x)
{
    pnode a,b;

    if(t==NULL) return 0;

    split(t,a,b,x);

    int ans = 0;

    ans = sz(a);

    merge(t,a,b);

    return ans;
}

const int N = 1e4+10;
const int NN = 1e5+10;

pnode aa[N];
pair<pair<int,int>,int> data[NN];

bool comp(const pair<pair<int,int>,int> & a,const pair<pair<int,int>,int> & b)
{
    return a.F.S < b.F.S;
}

signed main()
{
    Fast;

    int n,k,ans=0;

    cin >> n >> k;

    f(i,n)
    {
     cin >> data[i].F.F >> data[i].F.S >> data[i].S;

     if(aa[data[i].S] == NULL) aa[data[i].S] = init(data[i].F.F);
     else merge(aa[data[i].S],aa[data[i].S],init(data[i].F.F));
    }

    sort(data,data+n,comp);

    f(i,n)
    {
      for(int j=max(1LL,data[i].S-k);j<=min(10000*1LL,data[i].S+k);j++)
      {
          ans+=range_query(aa[j],data[i].F.F+data[i].F.S)-range_query(aa[j],data[i].F.F-data[i].F.S-1);
      }
      erase(aa[data[i].S],data[i].F.F);
    }

    cout << ans-n;
}


#include <bits/stdc++.h>
using namespace std;

#define int long long
#define f(i,n) for(int i=0;i<n;i++)
#define Fast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrand()
{
    uniform_int_distribution<int> uid(0*1LL, 9999999999999*1LL);
    return uid(rng);
}

struct node{
    int prior,size;
    int val;
    struct node *l,*r;
};

typedef node* pnode;

int sz(pnode t){
    return t?t->size:0;
}

void upd_sz(pnode t){
    if(t) t->size=sz(t->l)+1+sz(t->r);
}

void split(pnode t,pnode &l,pnode &r,int pos){

    if(!t) (l=r=NULL);
    else if(t->val<=pos) split(t->r,t->r,r,pos),l=t;
    else split(t->l,l,t->l,pos),r=t;

    upd_sz(t);
}

void merge(pnode &t,pnode l,pnode r)
{
    if (!l || !r) t = l?l:r;
    else if (l->prior > r->prior) merge(l->r,l->r,r),t=l;
    else merge(r->l,l,r->l),t=r;

    upd_sz(t);
}

void erase(pnode & t,int key)
{
    if(t-> val == key)  merge(t,t->l,t->r);
    else erase (key < t->val ? t->l : t->r, key);
}

pnode init(int val)
{
    pnode ret = new node();
    ret->prior=getrand();
    ret->size=1;
    ret->val=val;
    return ret;
}

int range_query(pnode t,int x)
{
    pnode a=NULL,b=NULL;

    if(t==NULL) return 0;

    int ans = 0;

    if(x < t->val) return range_query(t->l,x);
    else return sz(t->l)+1+range_query(t->r,x);

}

void insert (pnode & t, pnode it)
{
    if (!t)
        t = it;
    else if (it->prior > t->prior)
        split (t, it->l, it->r , it->val),  t = it;
    else
        insert (it->val < t->val ? t->l : t->r, it);
}

const int N = 1e4+10;
const int NN = 1e5+10;

pnode aa[N];
pair<pair<int,int>,int> dat[NN];

bool comp(const pair<pair<int,int>,int> & a,const pair<pair<int,int>,int> & b)
{
    if(a.F.S == b.F.S) return a.F.F < b.F.F;
    return a.F.S < b.F.S;
}

signed main()
{
    Fast;

    int n,k,ans=0;

    cin >> n >> k;

    f(i,n)
    {
     cin >> dat[i].F.F >> dat[i].F.S >> dat[i].S;

     insert(aa[dat[i].S],init(dat[i].F.F));
    }

    sort(dat,dat+n,comp);

    f(i,n)
    {
      for(int j=max(1LL,dat[i].S-k);j<=min(10000*1LL,dat[i].S+k);j++)
      {
          ans+=range_query(aa[j],dat[i].F.F+dat[i].F.S)-range_query(aa[j],dat[i].F.F-dat[i].F.S-1);
      }
      erase(aa[dat[i].S],dat[i].F.F);
    }

    cout << ans-n;
}


#include <bits/stdc++.h>
using namespace std;

#define int long long
#define f(i,n) for(int i=0;i<n;i++)
#define Fast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrand()
{
    uniform_int_distribution<int> uid(0*1LL, 9999999999999*1LL);
    return uid(rng);
}

struct node{
    int prior,size;
    int val;
    struct node *l,*r;
};

typedef node* pnode;

int sz(pnode t){
    return t?t->size:0;
}

void upd_sz(pnode t){
    if(t) t->size=sz(t->l)+1+sz(t->r);
}

void split(pnode t,pnode &l,pnode &r,int pos){

    if(!t) return void(l=r=NULL);

    if(t->val<=pos) split(t->r,t->r,r,pos),l=t;
    else split(t->l,l,t->l,pos),r=t;

    upd_sz(t);
}

void merge(pnode &t,pnode l,pnode r)
{
    if (!l || !r) t = l?l:r;
    else if (l->prior > r->prior) merge(l->r,l->r,r),t=l;
    else merge(r->l,l,r->l),t=r;

    upd_sz(t);
}

void erase(pnode & t,int key)
{
    if(t-> val == key)  merge(t,t->l,t->r);
    else erase (key < t->val ? t->l : t->r, key);
}

pnode init(int val)
{
    pnode ret = new node();
    ret->prior=getrand();
    ret->size=1;
    ret->val=val;
    return ret;
}

int range_query(pnode t,int x)
{
    pnode a=NULL,b=NULL;

    if(t==NULL) return 0;

    split(t,a,b,x);

    int ans = 0;

    ans = sz(a);

    merge(t,a,b);

    return ans;
}

void insert (pnode & t, pnode it)
{
    if (!t)
        t = it;
    else if (it->prior > t->prior)
        split (t, it->l, it->r , it->val),  t = it;
    else
        insert (it->val < t->val ? t->l : t->r, it);
}

const int N = 1e4+10;
const int NN = 1e5+10;

pnode aa[N];
pair<pair<int,int>,int> dat[NN];

bool comp(const pair<pair<int,int>,int> & a,const pair<pair<int,int>,int> & b)
{
    if(a.F.S == b.F.S) return a.F.F < b.F.F;
    return a.F.S < b.F.S;
}

signed main()
{
    Fast;

    int n,k,ans=0;

    cin >> n >> k;

    f(i,n)
    {
     cin >> dat[i].F.F >> dat[i].F.S >> dat[i].S;

     insert(aa[dat[i].S],init(dat[i].F.F));
    }

    sort(dat,dat+n,comp);

    f(i,n)
    {
      for(int j=max(1LL,dat[i].S-k);j<=min(10000*1LL,dat[i].S+k);j++)
      {
          ans+=range_query(aa[j],dat[i].F.F+dat[i].F.S)-range_query(aa[j],dat[i].F.F-dat[i].F.S-1);
      }
      erase(aa[dat[i].S],dat[i].F.F);
    }

    cout << ans-n;
}


#include <bits/stdc++.h>
using namespace std;

#define int long long
#define f(i,n) for(int i=0;i<n;i++)
#define Fast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrand()
{
    uniform_int_distribution<int> uid(0*1LL, 99999999999999*1LL);
    return uid(rng);
}

struct node{
    int prior,size;
    int val;
    struct node *l,*r;
};

typedef node* pnode;

int sz(pnode t){
    return t?t->size:0;
}

void upd_sz(pnode t){
    if(t)t->size=sz(t->l)+1+sz(t->r);
}

void split(pnode t,pnode &l,pnode &r,int pos){

    if(!t) return void(l=r=NULL);

    int curr_pos = t->val;

    if(curr_pos<=pos)
        split(t->r,t->r,r,pos),l=t;
    else
        split(t->l,l,t->l,pos),r=t;

    upd_sz(t);

}

void merge(pnode &t,pnode l,pnode r){ //l->leftarray,r->rightarray,t->resulting array

    if(!l || !r) t = l?l:r;
    else if(l->prior>r->prior)merge(l->r,l->r,r),t=l;
    else merge(r->l,l,r->l),t=r;

    upd_sz(t);
}

void erase(pnode & t,int key)
{
    if(t-> val == key)
      merge(t,t->l,t->r);

    else
        erase (key < t->val ? t->l : t->r, key);
}

pnode init(int val)
{
    pnode ret = new node();
    ret->prior=getrand();
    ret->size=1;
    ret->val=val;
    return ret;
}

int range_query(pnode t,int x)
{
    pnode a,b;

    if(t==NULL) return 0;

    split(t,a,b,x);

    int ans = 0;

    ans = sz(a);

    merge(t,a,b);

    return ans;
}

void insert (pnode & t, pnode it)
{
    if (!t)
        t = it;
    else if (it->prior > t->prior)
        split (t, it->l, it->r , it->val),  t = it;
    else
        insert (it->val < t->val ? t->l : t->r, it);
}

const int N = 1e4+10;
const int NN = 1e5+10;

pnode aa[N];
pair<pair<int,int>,int> dat[NN];

bool comp(const pair<pair<int,int>,int> & a,const pair<pair<int,int>,int> & b)
{
    if(a.F.S == b.F.S) return a.F.F < b.F.F;
    return a.F.S < b.F.S;
}

signed main()
{
    Fast;

    int n,k,ans=0;

    cin >> n >> k;

    f(i,N) aa[i] = NULL;

    f(i,n)
    {
     cin >> dat[i].F.F >> dat[i].F.S >> dat[i].S;

     insert(aa[dat[i].S],init(dat[i].F.F));
    }

    sort(dat,dat+n,comp);

    f(i,n)
    {
      for(int j=max(1LL,dat[i].S-k);j<=min(10000*1LL,dat[i].S+k);j++)
      {
          ans+=range_query(aa[j],dat[i].F.F+dat[i].F.S)-range_query(aa[j],dat[i].F.F-dat[i].F.S-1);
      }
      erase(aa[dat[i].S],dat[i].F.F);
    }

    cout << ans-n;
}


#include <bits/stdc++.h>
using namespace std;

#define int long long
#define f(i,n) for(int i=0;i<n;i++)
#define Fast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrand()
{
    uniform_int_distribution<int> uid(0, 99999999999*1LL);
    return uid(rng);
}

struct node{
    int prior,size;
    int val;
    struct node *l,*r;
};

typedef node* pnode;

int sz(pnode t){
    return t?t->size:0;
}

void upd_sz(pnode t){
    if(t)t->size=sz(t->l)+1+sz(t->r);
}

void split(pnode t,pnode &l,pnode &r,int pos){

    if(!t) return void(l=r=NULL);

    int curr_pos = t->val;

    if(curr_pos<=pos)
        split(t->r,t->r,r,pos),l=t;
    else
        split(t->l,l,t->l,pos),r=t;

    upd_sz(t);

}

void merge(pnode &t,pnode l,pnode r){ //l->leftarray,r->rightarray,t->resulting array

    if(!l || !r) t = l?l:r;
    else if(l->prior>r->prior)merge(l->r,l->r,r),t=l;
    else merge(r->l,l,r->l),t=r;

    upd_sz(t);
}

void erase(pnode & t,int key)
{
    if(t-> val == key)
      merge(t,t->l,t->r);

    else
        erase (key < t->val ? t->l : t->r, key);
}

pnode init(int val)
{
    pnode ret = new node();
    ret->prior=getrand();
    ret->size=1;
    ret->val=val;
    return ret;
}

int range_query(pnode t,int x)
{
    pnode a,b;

    if(t==NULL) return 0;

    split(t,a,b,x);

    int ans = 0;

    ans = sz(a);

    merge(t,a,b);

    return ans;
}

const int N = 1e4+10;
const int NN = 1e5+10;

pnode aa[N];
pair<pair<int,int>,int> data[NN];

bool comp(const pair<pair<int,int>,int> & a,const pair<pair<int,int>,int> & b)
{
    return a.F.S < b.F.S;
}

signed main()
{
    Fast;

    int n,k,ans=0;

    cin >> n >> k;

    f(i,N) aa[i] = NULL;

    f(i,n)
    {
     cin >> data[i].F.F >> data[i].F.S >> data[i].S;

     if(aa[data[i].S] == NULL) aa[data[i].S] = init(data[i].F.F);
     else merge(aa[data[i].S],aa[data[i].S],init(data[i].F.F));

    }

    sort(data,data+n,comp);

    f(i,n)
    {
      for(int j=max(1LL,data[i].S-k);j<=min(10000*1LL,data[i].S+k);j++)
      {
          ans+=range_query(aa[j],data[i].F.F+data[i].F.S)-range_query(aa[j],data[i].F.F-data[i].F.S-1);
      }
      erase(aa[data[i].S],data[i].F.F);
    }

    cout << ans-n;
}


#include <bits/stdc++.h>
using namespace std;

#define int long long
#define f(i,n) for(int i=0;i<n;i++)
#define Fast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrand()
{
    uniform_int_distribution<int> uid(0*1LL, 9999999999999*1LL);
    return uid(rng);
}

struct node{
    int prior,size;
    int val;
    struct node *l,*r;
};

typedef node* pnode;

int sz(pnode t){
    return t?t->size:0;
}

void upd_sz(pnode t){
    if(t) t->size=sz(t->l)+1+sz(t->r);
}

void split(pnode t,pnode &l,pnode &r,int pos){

    if(!t) (l=r=NULL);
    else if(t->val<=pos) split(t->r,t->r,r,pos),l=t;
    else split(t->l,l,t->l,pos),r=t;

    upd_sz(t);
}

void merge(pnode &t,pnode l,pnode r)
{
    if (!l || !r) t = l?l:r;
    else if (l->prior > r->prior) merge(l->r,l->r,r),t=l;
    else merge(r->l,l,r->l),t=r;

    upd_sz(t);
}

void erase(pnode & t,int key)
{
    if(!t) return;

    else if(t-> val == key)  merge(t,t->l,t->r);
    else erase (key < t->val ? t->l : t->r, key);

    upd_sz(t);
}

pnode init(int val)
{
    pnode ret = new node();
    ret->prior=rand();
    ret->size=1;
    ret->val=val;
    ret->l = ret-> r = NULL;
    return ret;
}

int range_query(pnode t,int x)
{

    if(t==NULL) return 0;

    int ans = 0;

    if(x < t->val) return range_query(t->l,x);

    return sz(t->l)+1+range_query(t->r,x);

}

void insert (pnode & t, pnode it)
{
    if (!t)
        t = it;
    else if (it->prior > t->prior)
        split (t, it->l, it->r , it->val),  t = it;
    else
        insert (it->val < t->val ? t->l : t->r, it);

    upd_sz(t);
}

const int N = 1e4+10;
const int NN = 1e5+10;

pnode aa[N];
pair<pair<int,int>,int> dat[NN];

bool comp(const pair<pair<int,int>,int> & a,const pair<pair<int,int>,int> & b)
{
    if(a.F.S == b.F.S) return a.F.F < b.F.F;
    return a.F.S < b.F.S;
}

signed main()
{
    Fast;

    int n,k,ans=0;

    cin >> n >> k;

    f(i,n)
    {
     cin >> dat[i].F.F >> dat[i].F.S >> dat[i].S;

     insert(aa[dat[i].S],init(dat[i].F.F));
    }

    sort(dat,dat+n,comp);

    f(i,n)
    {
      for(int j=max(1LL,dat[i].S-k);j<=min(10000*1LL,dat[i].S+k);j++)
      {
          ans+=range_query(aa[j],dat[i].F.F+dat[i].F.S)-range_query(aa[j],dat[i].F.F-dat[i].F.S-1);
      }
      erase(aa[dat[i].S],dat[i].F.F);
    }

    cout << ans-n;
}


#include <bits/stdc++.h>
using namespace std;

#define int long long
#define f(i,n) for(int i=0;i<n;i++)
#define Fast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrand()
{
    uniform_int_distribution<int> uid(0*1LL, 9999999999999*1LL);
    return uid(rng);
}

struct node{
    int prior,size;
    int val;
    struct node *l,*r;
};

typedef node* pnode;

int sz(pnode t){
    return t?t->size:0;
}

void upd_sz(pnode t){
    if(t) t->size=sz(t->l)+1+sz(t->r);
}

void split(pnode t,pnode &l,pnode &r,int pos){

    if(!t) (l=r=NULL);
    else if(t->val<=pos) split(t->r,t->r,r,pos),l=t;
    else split(t->l,l,t->l,pos),r=t;

    upd_sz(t);
}

void merge(pnode &t,pnode l,pnode r)
{
    if (!l || !r) t = l?l:r;
    else if (l->prior > r->prior) merge(l->r,l->r,r),t=l;
    else merge(r->l,l,r->l),t=r;

    upd_sz(t);
}

void erase(pnode & t,int key)
{
    if(!t) return;

    else if(t-> val == key)  merge(t,t->l,t->r);
    else erase (key < t->val ? t->l : t->r, key);

    upd_sz(t);
}

pnode init(int val)
{
    pnode ret = new node();
    ret->prior=getrand();
    ret->size=1;
    ret->val=val;
    ret->l = ret-> r = NULL;
    return ret;
}

int range_query(pnode t,int x)
{
    pnode a=NULL,b=NULL;

    if(t==NULL) return 0;

    int ans = 0;

    if(x < t->val) return range_query(t->l,x);
    else return sz(t->l)+1+range_query(t->r,x);

}

void insert (pnode & t, pnode it)
{
    if (!t)
        t = it;
    else if (it->prior > t->prior)
        split (t, it->l, it->r , it->val),  t = it;
    else
        insert (it->val < t->val ? t->l : t->r, it);
}

const int N = 1e4+10;
const int NN = 1e5+10;

pnode aa[N];
pair<pair<int,int>,int> dat[NN];

bool comp(const pair<pair<int,int>,int> & a,const pair<pair<int,int>,int> & b)
{
    if(a.F.S == b.F.S) return a.F.F < b.F.F;
    return a.F.S < b.F.S;
}

signed main()
{
    Fast;

    int n,k,ans=0;

    cin >> n >> k;

    f(i,n)
    {
     cin >> dat[i].F.F >> dat[i].F.S >> dat[i].S;

     insert(aa[dat[i].S],init(dat[i].F.F));
    }

    sort(dat,dat+n,comp);

    f(i,n)
    {
      for(int j=max(1LL,dat[i].S-k);j<=min(10000*1LL,dat[i].S+k);j++)
      {
          ans+=range_query(aa[j],dat[i].F.F+dat[i].F.S)-range_query(aa[j],dat[i].F.F-dat[i].F.S-1);
      }
      erase(aa[dat[i].S],dat[i].F.F);
    }

    cout << ans-n;
}


#include <bits/stdc++.h>
using namespace std;

#define int long long
#define f(i,n) for(int i=0;i<n;i++)
#define Fast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrand()
{
    uniform_int_distribution<int> uid(0*1LL, 99999999999999*1LL);
    return uid(rng);
}

struct node{
    int prior,size;
    int val;
    struct node *l,*r;
};

typedef node* pnode;

int sz(pnode t){
    return t?t->size:0;
}

void upd_sz(pnode t){
    if(t)t->size=sz(t->l)+1+sz(t->r);
}

void split(pnode t,pnode &l,pnode &r,int pos){

    if(!t) return void(l=r=NULL);

    int curr_pos = t->val;

    if(curr_pos<=pos)
        split(t->r,t->r,r,pos),l=t;
    else
        split(t->l,l,t->l,pos),r=t;

    upd_sz(t);

}

void merge(pnode &t,pnode l,pnode r){ //l->leftarray,r->rightarray,t->resulting array

    if(!l || !r) t = l?l:r;
    else if(l->prior>r->prior)merge(l->r,l->r,r),t=l;
    else merge(r->l,l,r->l),t=r;

    upd_sz(t);
}

void erase(pnode & t,int key)
{
    if(t-> val == key)
      merge(t,t->l,t->r);

    else
        erase (key < t->val ? t->l : t->r, key);
}

pnode init(int val)
{
    pnode ret = new node();
    ret->prior=getrand();
    ret->size=1;
    ret->val=val;
    return ret;
}

int range_query(pnode t,int x)
{
    pnode a,b;

    if(t==NULL) return 0;

    split(t,a,b,x);

    int ans = 0;

    ans = sz(a);

    merge(t,a,b);

    return ans;
}

void insert (pnode & t, pnode it)
{
    if (!t)
        t = it;
    else if (it->prior > t->prior)
        split (t, it->l, it->r , it->val),  t = it;
    else
        insert (it->val < t->val ? t->l : t->r, it);
}

const int N = 1e4+10;
const int NN = 1e5+10;

pnode aa[N];
pair<pair<int,int>,int> dat[NN];

bool comp(const pair<pair<int,int>,int> & a,const pair<pair<int,int>,int> & b)
{
    return a.F.S < b.F.S;
}

signed main()
{
    Fast;

    int n,k,ans=0;

    cin >> n >> k;

    f(i,N) aa[i] = NULL;

    f(i,n)
    {
     cin >> dat[i].F.F >> dat[i].F.S >> dat[i].S;

     insert(aa[dat[i].S],init(dat[i].F.F));
    }

    sort(dat,dat+n,comp);

    f(i,n)
    {
      for(int j=max(1LL,dat[i].S-k);j<=min(10000*1LL,dat[i].S+k);j++)
      {
          ans+=range_query(aa[j],dat[i].F.F+dat[i].F.S)-range_query(aa[j],dat[i].F.F-dat[i].F.S-1);
      }
      erase(aa[dat[i].S],dat[i].F.F);
    }

    cout << ans-n;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=lower_bound(all(A),vl)-A.begin();
    return tp+1;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*5];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
        if(A[ny-1]!=(v[i].x+v[i].r)) ny--;
        if(ny==0) {
            Root[nf]=Update(Root[nf],1,10000,Id(v[i].x)); continue;
        }
        nx=max(1,nx);
//        trace2(nx,ny)
        if(nx<=0||nx>n||ny<=0||ny>n) assert(0);
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,10000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,10000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,10000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=lower_bound(all(A),vl)-A.begin();
    return tp+1;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*20];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
        if(A[ny-1]!=(v[i].x+v[i].r)) ny--;
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,100000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,100000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,100000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=upper_bound(all(A),vl)-A.begin();
    return tp;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*5];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,10000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,10000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,10000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=lower_bound(all(A),vl)-A.begin();
    return tp+1;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*5];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
        if(A[ny-1]!=(v[i].x+v[i].r)) ny--;
        if(ny==0) {
            Root[nf]=Update(Root[nf],1,10000,Id(v[i].x)); continue;
        }
        nx=max(1,nx);
//        trace2(nx,ny)
        if(nx>ny) assert(0);
        if(nx<=0||nx>n||ny<=0||ny>n) assert(0);
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,10000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,10000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,10000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=lower_bound(all(A),vl)-A.begin();
    return tp+1;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*20];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
        if(A[ny-1]!=(v[i].x+v[i].r)) ny--;
        if(ny==0) {
            Root[nf]=Update(Root[nf],1,100000,Id(v[i].x)); continue;
        }
        nx=max(1,nx);
//        trace2(nx,ny)
        if(nx>ny) assert(0);
        if(nx<=0||nx>n||ny<=0||ny>n) assert(0);
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,100000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,100000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,100000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=lower_bound(all(A),vl)-A.begin();
    return tp+1;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*20];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
        if(A[ny-1]!=(v[i].x+v[i].r)) ny--;
        if(ny==0) {
            Root[nf]=Update(Root[nf],1,100000,Id(v[i].x)); continue;
        }
        nx=max(1,nx);
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,100000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,100000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,100000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=upper_bound(all(A),vl)-A.begin();
    return tp;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*5];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
        if(nx<=0||nx>n||ny<=0||ny>n) assert(0);
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,10000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,10000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,10000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=upper_bound(all(A),vl)-A.begin();
    return tp;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*5];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        nx=max(1,nx);
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
//        trace2(nx,ny)
        if(nx<=0||nx>n||ny<=0||ny>n) assert(0);
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,10000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,10000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,10000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/********************************************
*                                           *
*    Solved By : Bir Bahadur Khatri(B'ru)   *
*      Be Positive,be Happy.                *
*                                           *
*********************************************/

#define ff first
#define D double
#define sz size()
#define ss second
#define PB push_back
#define MP make_pair
#define SQR(n) (n*n)
#define CHR getchar()
#define NL printf("\n")
#include<bits/stdc++.h>
#define ULL unsigned LL
#define PI 2.0*acos(0.0)
#define LL long long int
#define S1(a) a=in<int>()
#define SL1(a) a=in<LL>()
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define all(a) a.begin(),a.end()
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SL2(a,b) a=in<LL>(),b=in<LL>()
#define F(i,a,b) for(int i=a;i<b; i++)
#define S2(a,b) a=in<int>(),b=in<int>()
#define R(i,a,b) for(int i=a-1;i>=b; i--)
#define BitCnt(a) __builtin_popcountll(a)
#define MEM(a,val) memset(a,val,sizeof(a))
#define SL3(a,b,c) a=in<LL>(),b=in<LL>(),c=in<LL>()
#define S3(a,b,c) a=in<int>(),b=in<int>(),c=in<int>()
#define _cin ios_base::sync_with_stdio(0); cin.tie(0)
#define cp printf("***** here here here here *****\n");
#define trace1(x)                cerr << #x << ": " << x << endl;
#define InpOut freopen("A.in","r",stdin),freopen("A1.out","w",stdout)
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

using namespace std;
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Gcd(T a,T b){if(a<0)return Gcd(-a,b);if(b<0)return Gcd(a,-b);return (b==0)?a:Gcd(b,a%b);}
template<typename T>inline T Lcm(T a,T b) {if(a<0)return Lcm(-a,b);if(b<0)return Lcm(a,-b);return a*(b/Gcd(a,b));}
long long Bigmod(long long base, long long power, long long MOD){long long ret=1;while(power){if(power & 1)ret=(ret*base)%MOD;base=(base*base)%MOD;power>>=1;}return ret;}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
template <typename T> LL isLeft(T a,T b,T c) {return(a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y);}
long long ModInverse(long long number, long long MOD){return Bigmod(number, MOD-2, MOD);}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
///**********************************************************//

#define MD1 1000000007ULL
#define MD2 1000000009ULL
#define MD3 1000000021ULL
#define BS1 10000019ULL
#define BS2 10000079ULL
#define BS3 10000103ULL
#define PUL pair<ULL,ULL>
#define PLL pair<LL,LL>
#define PII pair<int,int>

///         0123456789
#define MX  200007
#define MOD 1000000007
#define INF 1000000000000000LL
#define EPS 1e-9

/// ==========================================////

struct z{
    int x,r,f;
    z(){}
    z(int _,int __,int ___) {
        x=_,r=__,f=___;
    }
};

bool cmp(z a, z b) {
    return (a.r>b.r);
}
vector<z> v;
vector<int> A;

int Id(int vl) {
    int tp=upper_bound(all(A),vl)-A.begin();
    return tp;
}

int Root[MX];
struct Node{
    int l,r,sum;
    Node(){
        l=r=sum=0;
    }
};

int avail;
Node Tree[MX*5];
int Update(int id,int l,int r,int pos) {
    int u=++avail;
    Tree[u]=Tree[id];

    if(l==r) {
        Tree[u].sum++;
        return u;
    }
    int mid=(l+r)/2;

    if(pos<=mid)        Tree[u].l=Update(Tree[u].l,l,mid,pos);
    else                Tree[u].r=Update(Tree[u].r,mid+1,r,pos);
    Tree[u].sum=Tree[ Tree[u].l ].sum+Tree[ Tree[u].r ].sum;
    return u;
}

int Qry(int id,int l,int r,int st,int ed) {
    if(st<=l&&ed>=r)            return Tree[id].sum;

    int mid=(l+r)/2;

    if(ed<=mid)             return Qry(Tree[id].l,l,mid,st,ed);
    else if(st>mid)         return Qry(Tree[id].r,mid+1,r,st,ed);
    else {
                            return Qry(Tree[id].l,l,mid,st,ed)+Qry(Tree[id].r,mid+1,r,st,ed);
    }
}

int nx,ny;

int main(){

    int n,k;
    S2(n,k);

    F(i,1,n+1) {
        int a,b,c;
        S3(a,b,c);
        A.PB(a);
        v.PB( z(a,b,c) );
    }
    sort(all(A));
    sort(all(v),cmp);
    LL ans=0;
    Root[0]=0;
    Tree[0]=Node();
    for(int i=0;i<v.sz;i++) {
        int nf=v[i].f;
        nx=v[i].x-v[i].r;
        ny=v[i].x+v[i].r;
        nx=Id(nx);
        ny=Id(ny);
        if(ny==0) {
            Root[nf]=Update(Root[nf],1,10000,Id(v[i].x)); continue;
        }
        nx=max(1,nx);
//        trace2(nx,ny)
        if(nx<=0||nx>n||ny<=0||ny>n) assert(0);
        for(int j=0;j<=k;j++) {
            int wf=nf+j;
            ans+=Qry(Root[wf],1,10000,nx,ny);
            if(j) {
                wf=nf-j;
                if(wf>0) ans+=Qry(Root[wf],1,10000,nx,ny);
            }
        }
        Root[nf]=Update(Root[nf],1,10000,Id(v[i].x));
    }
    printf("%lld\n",ans);

    return 0;
}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll long long int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<int,int>
#define pic pair<int,char>
#define N 300100
#define lgn 20
#define ddouble long double
#define minus minu
using namespace std;
ll seg[4*N];
ll x[N],r[N],f[N];
map<ll,ll> comp;
ll query(ll qlow,ll qhigh,ll low,ll high,ll pos)
{
    if((qlow<=low)&&(qhigh>=high))
    {
        return seg[pos];
    }
    else
    {
        ll mid=(low+high)/2;
        if(qlow>mid)
        {
            return query(qlow,qhigh,mid+1,high,2*pos+2);
        }
        else if(qhigh<=mid)
        {
            return query(qlow,qhigh,low,mid,2*pos+1);
        }
        else
        {
            ll q1,q2;
            q1=query(qlow,qhigh,low,mid,2*pos+1);
            q2=query(qlow,qhigh,mid+1,high,2*pos+2);
            return (q1+q2);
        }
    }
}
void update(ll q,ll low,ll high,ll pos,ll val)
{
    if(low==high)
    {
        seg[pos]=val;
    }
    else
    {
        ll mid=(low+high)/2;
        if(q<=mid)
        {
            update(q,low,mid,2*pos+1,val);
        }
        else
        {
            update(q,mid+1,high,2*pos+2,val);
        }
        seg[pos]=seg[2*pos+1]+seg[2*pos+2];
    }

}
vector<list<pii> > adjlist(N);

li eval(ll st,ll en)
{
    set<pii> s;
    for(list<pii> ::iterator it=adjlist[st].begin();it!=adjlist[st].end();it++)
    {
        s.insert((*it));
        update(comp[it->sec],0,N-1,0,1);
    }
    if(en!=st)
    {
        for(list<pii> ::iterator it=adjlist[en].begin();it!=adjlist[en].end();it++)
        {
            s.insert((*it));
            update(comp[it->sec],0,N-1,0,1);
        }
    }
    li ret=0;
    for(set<pii> ::iterator it=s.begin();it!=s.end();it++)
    {
        update(comp[it->sec],0,N-1,0,0);
        ret=ret+(li)query(comp[it->sec-it->fi],comp[it->sec+it->fi],0,N-1,0);
    }
    return ret;

}

li alone[N];

int main()
{
    //dont use x r f as other variables
    ll n,k;
    cin>>n>>k;
    set<ll> s;
    ll temp=0;
    for(ll i=0;i<n;i++)
    {
        cin>>x[i]>>r[i]>>f[i];
        adjlist[f[i]].pb(mp(r[i],x[i]));
        s.insert(x[i]);
        s.insert(x[i]-r[i]);
        s.insert(x[i]+r[i]);
    }
    for(set<ll> ::iterator it=s.begin();it!=s.end();it++)
    {
        comp[(*it)]=(temp);//coordinate compression!!
        // cout<<(*it)<<" "<<temp<<endl;
        temp++;
    }
    li ans=0;
    for(ll i=1;i<=(10000+1);i++)
    {
        alone[i]=eval(i,i);
        ans=ans+(li)alone[i];
        // if(i==5)
        // {
        //     cout<<eval(i,i);
        // }
    }
    for(ll i=1;i<=(10000+1-k);i++)
    {
        for(ll j=(i+1);j<=(i+k);j++)
        {
            ans=(ans+(li)eval(i,j)-alone[i]-alone[j]);
        }
    }
    cout<<ans;

}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<int,int>
#define pic pair<int,char>
#define N 300001
#define lgn 20
#define ddouble long double
#define minus minu
using namespace std;
ll seg[4*N];
ll x[N],r[N],f[N];
unordered_map<ll,ll> comp;
ll query(ll qlow,ll qhigh,ll low,ll high,ll pos)
{
    if((qlow<=low)&&(qhigh>=high))
    {
        return seg[pos];
    }
    else
    {
        ll mid=(low+high)/2;
        if(qlow>mid)
        {
            return query(qlow,qhigh,mid+1,high,2*pos+2);
        }
        else if(qhigh<=mid)
        {
            return query(qlow,qhigh,low,mid,2*pos+1);
        }
        else
        {
            ll q1,q2;
            q1=query(qlow,qhigh,low,mid,2*pos+1);
            q2=query(qlow,qhigh,mid+1,high,2*pos+2);
            return (q1+q2);
        }
    }
}
void update(ll q,ll low,ll high,ll pos,ll val)
{
    if(low==high)
    {
        seg[pos]=val;
    }
    else
    {
        ll mid=(low+high)/2;
        if(q<=mid)
        {
            update(q,low,mid,2*pos+1,val);
        }
        else
        {
            update(q,mid+1,high,2*pos+2,val);
        }
        seg[pos]=seg[2*pos+1]+seg[2*pos+2];
    }

}

struct node{
    ll lef,rig,me;
};
vector<list<pair<ll,pair<ll,pii> > > > adjlist(N);
li eval(ll st,ll en)
{
    set<pair<ll,pair<ll,pii> > > s;//change it to vector in case of tle!!
    for(list<pair<ll,pair<ll,pii> > > ::iterator it=adjlist[st].begin();it!=adjlist[st].end();it++)
    {
        s.insert((*it));
        update((it->sec).sec.fi,0,N-1,0,1);
    }
    if(en!=st)
    {
        for(list<pair<ll,pair<ll,pii> > > ::iterator it=adjlist[en].begin();it!=adjlist[en].end();it++)
        {
            s.insert((*it));
            update((it->sec).sec.fi,0,N-1,0,1);
        }
    }
    li ret=0;
    for(set<pair<ll,pair<ll,pii> > > ::iterator it=s.begin();it!=s.end();it++)
    {
        update((it->sec).sec.fi,0,N-1,0,0);
        ret=ret+(li)query((it->sec).fi,(it->sec).sec.sec,0,N-1,0);//time limit
    }
    return ret;

}

li alone[N];

int main()
{
    //dont use x r f as other variables
    std::ios::sync_with_stdio(false);
    ll n,k;
    cin>>n>>k;
    set<ll> s;
    ll temp=0;
    for(ll i=0;i<n;i++)
    {
        cin>>x[i]>>r[i]>>f[i];

        s.insert(x[i]);
        s.insert(x[i]-r[i]);
        s.insert(x[i]+r[i]);
    }
    for(set<ll> ::iterator it=s.begin();it!=s.end();it++)
    {
        comp[(*it)]=(temp);//coordinate compression!!
        // cout<<(*it)<<" "<<temp<<endl;
        temp++;
    }
    for(ll i=0;i<n;i++)
    {
        pair<ll,pii> ch;
        ch.fi=comp[x[i]-r[i]];
        ch.sec.fi=comp[x[i]];
        ch.sec.sec=comp[x[i]+r[i]];
        adjlist[f[i]].pb(mp(r[i],ch));
    }
    li ans=0;
    for(ll i=1;i<=(10000);i++)
    {
        if(adjlist[i].size())
        alone[i]=eval(i,i);
        ans=ans+(li)alone[i];
    }
    for(ll i=1;i<=(10000);i++)
    {
        for(ll j=(i+1);j<=(i+k)&&(j<=10000);j++)
        {
            if((adjlist[i].size())&&(adjlist[j].size()))
            ans=(ans+(li)eval(i,j)-alone[i]-alone[j]);
        }
    }
    cout<<ans;

}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll long long int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<int,int>
#define pic pair<int,char>
#define N 5000001
#define lgn 20
#define ddouble long double
#define minus minu
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>pbd_set;
pbd_set s[20000];
pair<ll,pii> r[N];
int main()
{
    ll n,k;
    cin>>n>>k;
    for(ll i=0;i<n;i++){
        cin>>r[i].sec.fi>>r[i].fi>>r[i].sec.sec;
        s[r[i].sec.sec].insert(r[i].sec.fi);
    }
    sort(r,r+n);
    li ans=0;
    for(ll i=0;i<n;i++)
    {
        for(ll j=(r[i].sec.sec-k);j<=(r[i].sec.sec+k);j++)
        {
            if(j>=0)
            {
                ans+=(s[j].order_of_key(r[i].sec.fi+r[i].fi+1));
                ans-=(s[j].order_of_key(r[i].sec.fi-r[i].fi));

            }
        }
        ans-=1;
        s[r[i].sec.sec].erase(r[i].sec.fi);
        // cout<<ans<<"\n";
    }
    cout<<ans;

}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<long long int,long long int>
#define pic pair<int,char>
#define N 300100
#define lgn 20
#define ddouble long double
#define minus minu
using namespace std;
ll seg[4*N];
ll x[N],r[N],f[N];
unordered_map<ll,ll> comp;
ll query(ll qlow,ll qhigh,ll low,ll high,ll pos)
{
    if((qlow<=low)&&(qhigh>=high))
    {
        return seg[pos];
    }
    else
    {
        ll mid=(low+high)/2;
        if(qlow>mid)
        {
            return query(qlow,qhigh,mid+1,high,2*pos+2);
        }
        else if(qhigh<=mid)
        {
            return query(qlow,qhigh,low,mid,2*pos+1);
        }
        else
        {
            ll q1,q2;
            q1=query(qlow,qhigh,low,mid,2*pos+1);
            q2=query(qlow,qhigh,mid+1,high,2*pos+2);
            return (q1+q2);
        }
    }
}
void update(ll q,ll low,ll high,ll pos,ll val)
{
    if(low==high)
    {
        seg[pos]=val;
    }
    else
    {
        ll mid=(low+high)/2;
        if(q<=mid)
        {
            update(q,low,mid,2*pos+1,val);
        }
        else
        {
            update(q,mid+1,high,2*pos+2,val);
        }
        seg[pos]=seg[2*pos+1]+seg[2*pos+2];
    }

}
vector<list<pii> > adjlist(N);

li eval(ll st,ll en)
{
    set<pii> s;//change it to vector in case of tle!!
    for(list<pii> ::iterator it=adjlist[st].begin();it!=adjlist[st].end();it++)
    {
        s.insert((*it));
        update(comp[it->sec],0,N-1,0,1);
    }
    if(en!=st)
    {
        for(list<pii> ::iterator it=adjlist[en].begin();it!=adjlist[en].end();it++)
        {
            s.insert((*it));
            update(comp[it->sec],0,N-1,0,1);
        }
    }
    li ret=0;
    for(set<pii> ::iterator it=s.begin();it!=s.end();it++)
    {
        update(comp[it->sec],0,N-1,0,0);
        ret=ret+(li)query(comp[it->sec-it->fi],comp[it->sec+it->fi],0,N-1,0);
    }
    return ret;

}

li alone[N];

int main()
{
    //dont use x r f as other variables
    std::ios::sync_with_stdio(false);
    ll n,k;
    cin>>n>>k;
    set<ll> s;
    ll temp=0;
    for(ll i=0;i<n;i++)
    {
        cin>>x[i]>>r[i]>>f[i];
        adjlist[f[i]].pb(mp(r[i],x[i]));
        s.insert(x[i]);
        s.insert(x[i]-r[i]);
        s.insert(x[i]+r[i]);
    }
    for(set<ll> ::iterator it=s.begin();it!=s.end();it++)
    {
        comp[(*it)]=(temp);//coordinate compression!!
        // cout<<(*it)<<" "<<temp<<endl;
        temp++;
    }
    li ans=0;
    for(ll i=1;i<=(10000+1);i++)
    {
        alone[i]=eval(i,i);
        ans=ans+(li)alone[i];
        // if(i==5)
        // {
        //     cout<<eval(i,i);
        // }
    }
    for(ll i=1;i<=(10000+1);i++)
    {
        for(ll j=(i+1);j<=(i+k);j++)
        {
            if(alone[i]&&alone[j])
            ans=(ans+(li)eval(i,j)-alone[i]-alone[j]);
        }
    }
    cout<<ans;

}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll long long int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<long long int,long long int>
#define pic pair<int,char>
#define N 300100
#define lgn 20
#define ddouble long double
#define minus minu
using namespace std;
ll seg[4*N];
ll x[N],r[N],f[N];
map<ll,ll> comp;
ll query(ll qlow,ll qhigh,ll low,ll high,ll pos)
{
    if((qlow<=low)&&(qhigh>=high))
    {
        return seg[pos];
    }
    else
    {
        ll mid=(low+high)/2;
        if(qlow>mid)
        {
            return query(qlow,qhigh,mid+1,high,2*pos+2);
        }
        else if(qhigh<=mid)
        {
            return query(qlow,qhigh,low,mid,2*pos+1);
        }
        else
        {
            ll q1,q2;
            q1=query(qlow,qhigh,low,mid,2*pos+1);
            q2=query(qlow,qhigh,mid+1,high,2*pos+2);
            return (q1+q2);
        }
    }
}
void update(ll q,ll low,ll high,ll pos,ll val)
{
    if(low==high)
    {
        seg[pos]=val;
    }
    else
    {
        ll mid=(low+high)/2;
        if(q<=mid)
        {
            update(q,low,mid,2*pos+1,val);
        }
        else
        {
            update(q,mid+1,high,2*pos+2,val);
        }
        seg[pos]=seg[2*pos+1]+seg[2*pos+2];
    }

}
vector<list<pii> > adjlist(N);

li eval(ll st,ll en)
{
    set<pii> s;//change it to vector in case of tle!!
    for(list<pii> ::iterator it=adjlist[st].begin();it!=adjlist[st].end();it++)
    {
        s.insert((*it));
        update(comp[it->sec],0,N-1,0,1);
    }
    if(en!=st)
    {
        for(list<pii> ::iterator it=adjlist[en].begin();it!=adjlist[en].end();it++)
        {
            s.insert((*it));
            update(comp[it->sec],0,N-1,0,1);
        }
    }
    li ret=0;
    for(set<pii> ::iterator it=s.begin();it!=s.end();it++)
    {
        update(comp[it->sec],0,N-1,0,0);
        ret=ret+(li)query(comp[it->sec-it->fi],comp[it->sec+it->fi],0,N-1,0);
    }
    return ret;

}

li alone[N];

int main()
{
    //dont use x r f as other variables
    ll n,k;
    cin>>n>>k;
    set<ll> s;
    ll temp=0;
    for(ll i=0;i<n;i++)
    {
        cin>>x[i]>>r[i]>>f[i];
        adjlist[f[i]].pb(mp(r[i],x[i]));
        s.insert(x[i]);
        s.insert(x[i]-r[i]);
        s.insert(x[i]+r[i]);
    }
    for(set<ll> ::iterator it=s.begin();it!=s.end();it++)
    {
        comp[(*it)]=(temp);//coordinate compression!!
        // cout<<(*it)<<" "<<temp<<endl;
        temp++;
    }
    li ans=0;
    for(ll i=1;i<=(10000+1);i++)
    {
        alone[i]=eval(i,i);
        ans=ans+(li)alone[i];
        // if(i==5)
        // {
        //     cout<<eval(i,i);
        // }
    }
    for(ll i=1;i<=(10000+1);i++)
    {
        for(ll j=(i+1);j<=(i+k);j++)
        {
            ans=(ans+(li)eval(i,j)-alone[i]-alone[j]);
        }
    }
    cout<<ans;

}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<int,int>
#define pic pair<int,char>
#define N 300001
#define lgn 20
#define ddouble long double
#define minus minu
using namespace std;
ll seg[4*N];
ll x[N],r[N],f[N];
unordered_map<ll,ll> comp;
ll query(ll qlow,ll qhigh,ll low,ll high,ll pos)
{
    if((qlow<=low)&&(qhigh>=high))
    {
        return seg[pos];
    }
    else
    {
        ll mid=(low+high)/2;
        if(qlow>mid)
        {
            return query(qlow,qhigh,mid+1,high,2*pos+2);
        }
        else if(qhigh<=mid)
        {
            return query(qlow,qhigh,low,mid,2*pos+1);
        }
        else
        {
            ll q1,q2;
            q1=query(qlow,qhigh,low,mid,2*pos+1);
            q2=query(qlow,qhigh,mid+1,high,2*pos+2);
            return (q1+q2);
        }
    }
}
void update(ll q,ll low,ll high,ll pos,ll val)
{
    if(low==high)
    {
        seg[pos]=val;
    }
    else
    {
        ll mid=(low+high)/2;
        if(q<=mid)
        {
            update(q,low,mid,2*pos+1,val);
        }
        else
        {
            update(q,mid+1,high,2*pos+2,val);
        }
        seg[pos]=seg[2*pos+1]+seg[2*pos+2];
    }

}

struct node{
    ll lef,rig,me;
};
vector<list<pair<ll,pair<ll,pii> > > > adjlist(N);
li eval(ll st,ll en)
{
    vector<pair<ll,pair<ll,pii> > > s;//change it to vector in case of tle!!
    for(list<pair<ll,pair<ll,pii> > > ::iterator it=adjlist[st].begin();it!=adjlist[st].end();it++)
    {
        s.pb((*it));
        update((it->sec).sec.fi,0,N-1,0,1);
    }
    if(en!=st)
    {
        for(list<pair<ll,pair<ll,pii> > > ::iterator it=adjlist[en].begin();it!=adjlist[en].end();it++)
        {
            s.pb((*it));
            update((it->sec).sec.fi,0,N-1,0,1);
        }
    }
    li ret=0;
    sort(s.begin(),s.end());
    for(vector<pair<ll,pair<ll,pii> > > ::iterator it=s.begin();it!=s.end();it++)
    {
        update((it->sec).sec.fi,0,N-1,0,0);
        ret=ret+(li)query((it->sec).fi,(it->sec).sec.sec,0,N-1,0);//time limit
    }
    return ret;

}

li alone[N];

int main()
{
    //dont use x r f as other variables
    std::ios::sync_with_stdio(false);
    ll n,k;
    cin>>n>>k;
    set<ll> s;
    ll temp=0;
    for(ll i=0;i<n;i++)
    {
        cin>>x[i]>>r[i]>>f[i];

        s.insert(x[i]);
        s.insert(x[i]-r[i]);
        s.insert(x[i]+r[i]);
    }
    for(set<ll> ::iterator it=s.begin();it!=s.end();it++)
    {
        comp[(*it)]=(temp);//coordinate compression!!
        // cout<<(*it)<<" "<<temp<<endl;
        temp++;
    }
    for(ll i=0;i<n;i++)
    {
        pair<ll,pii> ch;
        ch.fi=comp[x[i]-r[i]];
        ch.sec.fi=comp[x[i]];
        ch.sec.sec=comp[x[i]+r[i]];
        adjlist[f[i]].pb(mp(r[i],ch));
    }
    li ans=0;
    for(ll i=1;i<=(10000);i++)
    {
        if(adjlist[i].size())
        alone[i]=eval(i,i);
        ans=ans+(li)alone[i];
    }
    for(ll i=1;i<=(10000);i++)
    {
        for(ll j=(i+1);j<=(i+k)&&(j<=10000);j++)
        {
            if((adjlist[i].size())&&(adjlist[j].size()))
            ans=(ans+(li)eval(i,j)-alone[i]-alone[j]);
        }
    }
    cout<<ans;

}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<long long int,long long int>
#define pic pair<int,char>
#define N 300100
#define lgn 20
#define ddouble long double
#define minus minu
using namespace std;
ll seg[4*N];
ll x[N],r[N],f[N];
unordered_map<ll,ll> comp;
ll query(ll qlow,ll qhigh,ll low,ll high,ll pos)
{
    if((qlow<=low)&&(qhigh>=high))
    {
        return seg[pos];
    }
    else
    {
        ll mid=(low+high)/2;
        if(qlow>mid)
        {
            return query(qlow,qhigh,mid+1,high,2*pos+2);
        }
        else if(qhigh<=mid)
        {
            return query(qlow,qhigh,low,mid,2*pos+1);
        }
        else
        {
            ll q1,q2;
            q1=query(qlow,qhigh,low,mid,2*pos+1);
            q2=query(qlow,qhigh,mid+1,high,2*pos+2);
            return (q1+q2);
        }
    }
}
void update(ll q,ll low,ll high,ll pos,ll val)
{
    if(low==high)
    {
        seg[pos]=val;
    }
    else
    {
        ll mid=(low+high)/2;
        if(q<=mid)
        {
            update(q,low,mid,2*pos+1,val);
        }
        else
        {
            update(q,mid+1,high,2*pos+2,val);
        }
        seg[pos]=seg[2*pos+1]+seg[2*pos+2];
    }

}
vector<list<pii> > adjlist(N);

li eval(ll st,ll en)
{
    set<pii> s;//change it to vector in case of tle!!
    for(list<pii> ::iterator it=adjlist[st].begin();it!=adjlist[st].end();it++)
    {
        s.insert((*it));
        update(comp[it->sec],0,N-1,0,1);
    }
    if(en!=st)
    {
        for(list<pii> ::iterator it=adjlist[en].begin();it!=adjlist[en].end();it++)
        {
            s.insert((*it));
            update(comp[it->sec],0,N-1,0,1);
        }
    }
    li ret=0;
    for(set<pii> ::iterator it=s.begin();it!=s.end();it++)
    {
        update(comp[it->sec],0,N-1,0,0);
        ret=ret+(li)query(comp[it->sec-it->fi],comp[it->sec+it->fi],0,N-1,0);
    }
    return ret;

}

li alone[N];

int main()
{
    //dont use x r f as other variables
    std::ios::sync_with_stdio(false);
    ll n,k;
    cin>>n>>k;
    set<ll> s;
    ll temp=0;
    for(ll i=0;i<n;i++)
    {
        cin>>x[i]>>r[i]>>f[i];
        adjlist[f[i]].pb(mp(r[i],x[i]));
        s.insert(x[i]);
        s.insert(x[i]-r[i]);
        s.insert(x[i]+r[i]);
    }
    for(set<ll> ::iterator it=s.begin();it!=s.end();it++)
    {
        comp[(*it)]=(temp);//coordinate compression!!
        // cout<<(*it)<<" "<<temp<<endl;
        temp++;
    }
    li ans=0;
    for(ll i=1;i<=(10000+1);i++)
    {
        alone[i]=eval(i,i);
        ans=ans+(li)alone[i];
        // if(i==5)
        // {
        //     cout<<eval(i,i);
        // }
    }
    for(ll i=1;i<=(10000+1);i++)
    {
        for(ll j=(i+1);j<=(i+k);j++)
        {
            if((adjlist[i].size())&&(adjlist[j].size()))
            ans=(ans+(li)eval(i,j)-alone[i]-alone[j]);
        }
    }
    cout<<ans;

}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<int,int>
#define pic pair<int,char>
#define N 300001
#define lgn 20
#define ddouble long double
#define minus minu
using namespace std;
ll seg[4*N];
ll x[N],r[N],f[N];
map<ll,ll> comp;
ll query(ll qlow,ll qhigh,ll low,ll high,ll pos)
{
    if((qlow<=low)&&(qhigh>=high))
    {
        return seg[pos];
    }
    else
    {
        ll mid=(low+high)/2;
        if(qlow>mid)
        {
            return query(qlow,qhigh,mid+1,high,2*pos+2);
        }
        else if(qhigh<=mid)
        {
            return query(qlow,qhigh,low,mid,2*pos+1);
        }
        else
        {
            ll q1,q2;
            q1=query(qlow,qhigh,low,mid,2*pos+1);
            q2=query(qlow,qhigh,mid+1,high,2*pos+2);
            return (q1+q2);
        }
    }
}
void update(ll q,ll low,ll high,ll pos,ll val)
{
    if(low==high)
    {
        seg[pos]=val;
    }
    else
    {
        ll mid=(low+high)/2;
        if(q<=mid)
        {
            update(q,low,mid,2*pos+1,val);
        }
        else
        {
            update(q,mid+1,high,2*pos+2,val);
        }
        seg[pos]=seg[2*pos+1]+seg[2*pos+2];
    }

}

struct node{
    ll lef,rig,me;
};
vector<list<pair<ll,pair<ll,pii> > > > adjlist(N);
li eval(ll st,ll en)
{
    vector<pair<ll,pair<ll,pii> > > s;//change it to vector in case of tle!!
    for(list<pair<ll,pair<ll,pii> > > ::iterator it=adjlist[st].begin();it!=adjlist[st].end();it++)
    {
        s.pb((*it));
        update((it->sec).sec.fi,0,N-1,0,1);
    }
    if(en!=st)
    {
        for(list<pair<ll,pair<ll,pii> > > ::iterator it=adjlist[en].begin();it!=adjlist[en].end();it++)
        {
            s.pb((*it));
            update((it->sec).sec.fi,0,N-1,0,1);
        }
    }
    li ret=0;
    sort(s.begin(),s.end());
    for(vector<pair<ll,pair<ll,pii> > > ::iterator it=s.begin();it!=s.end();it++)
    {
        update((it->sec).sec.fi,0,N-1,0,0);
        ret=ret+(li)query((it->sec).fi,(it->sec).sec.sec,0,N-1,0);//time limit
    }
    return ret;

}

li alone[N];

int main()
{
    //dont use x r f as other variables
    std::ios::sync_with_stdio(false);
    ll n,k;
    cin>>n>>k;
    set<ll> s;
    ll temp=0;
    for(ll i=0;i<n;i++)
    {
        cin>>x[i]>>r[i]>>f[i];

        s.insert(x[i]);
        s.insert(x[i]-r[i]);
        s.insert(x[i]+r[i]);
    }
    for(set<ll> ::iterator it=s.begin();it!=s.end();it++)
    {
        comp[(*it)]=(temp);//coordinate compression!!
        // cout<<(*it)<<" "<<temp<<endl;
        temp++;
    }
    for(ll i=0;i<n;i++)
    {
        pair<ll,pii> ch;
        ch.fi=comp[x[i]-r[i]];
        ch.sec.fi=comp[x[i]];
        ch.sec.sec=comp[x[i]+r[i]];
        adjlist[f[i]].pb(mp(r[i],ch));
    }
    li ans=0;
    for(ll i=1;i<=(10000);i++)
    {
        if(adjlist[i].size())
        alone[i]=eval(i,i);
        ans=ans+(li)alone[i];
    }
    for(ll i=1;i<=(10000);i++)
    {
        for(ll j=(i+1);j<=(i+k)&&(j<=10000);j++)
        {
            if((adjlist[i].size())&&(adjlist[j].size()))
            ans=(ans+(li)eval(i,j)-alone[i]-alone[j]);
        }
    }
    cout<<ans;

}


/*NAME: SANYAM GARG
INSTITUTION : DELHI TECHNOLOGICAL UNIVERSITY*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#define mod 1000000007
#define li long long int
#define ll int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s",&x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000010LL
#define MINN -1000000000000000000
#define pii pair<int,int>
#define pic pair<int,char>
#define N 300100
#define lgn 20
#define ddouble long double
#define minus minu
using namespace std;
ll seg[4*N];
ll x[N],r[N],f[N];
map<ll,ll> comp;
ll query(ll qlow,ll qhigh,ll low,ll high,ll pos)
{
    if((qlow<=low)&&(qhigh>=high))
    {
        return seg[pos];
    }
    else
    {
        ll mid=(low+high)/2;
        if(qlow>mid)
        {
            return query(qlow,qhigh,mid+1,high,2*pos+2);
        }
        else if(qhigh<=mid)
        {
            return query(qlow,qhigh,low,mid,2*pos+1);
        }
        else
        {
            ll q1,q2;
            q1=query(qlow,qhigh,low,mid,2*pos+1);
            q2=query(qlow,qhigh,mid+1,high,2*pos+2);
            return (q1+q2);
        }
    }
}
void update(ll q,ll low,ll high,ll pos,ll val)
{
    if(low==high)
    {
        seg[pos]=val;
    }
    else
    {
        ll mid=(low+high)/2;
        if(q<=mid)
        {
            update(q,low,mid,2*pos+1,val);
        }
        else
        {
            update(q,mid+1,high,2*pos+2,val);
        }
        seg[pos]=seg[2*pos+1]+seg[2*pos+2];
    }

}
vector<list<pii> > adjlist(N);

li eval(ll st,ll en)
{
    set<pii> s;//change it to vector in case of tle!!
    for(list<pii> ::iterator it=adjlist[st].begin();it!=adjlist[st].end();it++)
    {
        s.insert((*it));
        update(comp[it->sec],0,N-1,0,1);
    }
    if(en!=st)
    {
        for(list<pii> ::iterator it=adjlist[en].begin();it!=adjlist[en].end();it++)
        {
            s.insert((*it));
            update(comp[it->sec],0,N-1,0,1);
        }
    }
    li ret=0;
    for(set<pii> ::iterator it=s.begin();it!=s.end();it++)
    {
        update(comp[it->sec],0,N-1,0,0);
        ret=ret+(li)query(comp[it->sec-it->fi],comp[it->sec+it->fi],0,N-1,0);
    }
    return ret;

}

li alone[N];

int main()
{
    //dont use x r f as other variables
    ll n,k;
    cin>>n>>k;
    set<ll> s;
    ll temp=0;
    for(ll i=0;i<n;i++)
    {
        cin>>x[i]>>r[i]>>f[i];
        adjlist[f[i]].pb(mp(r[i],x[i]));
        s.insert(x[i]);
        s.insert(x[i]-r[i]);
        s.insert(x[i]+r[i]);
    }
    for(set<ll> ::iterator it=s.begin();it!=s.end();it++)
    {
        comp[(*it)]=(temp);//coordinate compression!!
        // cout<<(*it)<<" "<<temp<<endl;
        temp++;
    }
    li ans=0;
    for(ll i=1;i<=(10000+1);i++)
    {
        alone[i]=eval(i,i);
        ans=ans+(li)alone[i];
        // if(i==5)
        // {
        //     cout<<eval(i,i);
        // }
    }
    for(ll i=1;i<=(10000+1);i++)
    {
        for(ll j=(i+1);j<=(i+k);j++)
        {
            ans=(ans+(li)eval(i,j)-alone[i]-alone[j]);
        }
    }
    cout<<ans;

}