#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;
const int fwmax = (1<<18)+1;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

ll FW[fwmax]; // fenwick

void inc(int i,ll v){
	while (i < fwmax){
		FW[i] += v;
		i += i & (-i);
	}
}
ll get(int i){
	ll sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; scanf("%d%d",&n,&k);

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		scanf("%d%d%d",&x[i],&r[i],&freq);
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	ll sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		queue <int> back;
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				back.push(p);
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				ll v = get(p2) - get(p1-1);
				sol += v-1;
			}
		}
		while (back.size() > 0){
			inc(back.front(),-1); back.pop();
		}

	}
	printf(lld,sol);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;
const int fwmax = 1e7 + 100;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

int FW[fwmax]; // fenwick

void inc(int i,int v){
	while (i < maxn){
		FW[i] += v;
		i += i & (-i);
	}
}
int get(int i){
	int sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; cin >> n >> k;

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		cin >> x[i] >> r[i] >> freq;
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	int sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				Q.push_back( mp(f[j][qw] , i == j) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				int v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v;
				inc(p2 , 1);
			}
		}
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , -1);
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				inc(p2 , -1);
			}
		}

	}
	cout << sol << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;
const int maxk = 100005;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

int FW[maxn]; // fenwick

void inc(int i,int v){
	while (i < maxn){
		FW[i] += v;
		i += i & (-i);
	}
}
int get(int i){
	int sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; cin >> n >> k;

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		cin >> x[i] >> r[i] >> freq;
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());
	for (int i = 0;i < points.size();i++){
		c[points[i]] = i+1;
	}

	int sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				Q.push_back( mp(f[j][qw] , i == j) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				int v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v;
				inc(p2 , 1);
			}
		}
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , -1);
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				inc(p2 , -1);
			}
		}

	}
	cout << sol << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;
const int fwmax = 1e7 + 100;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

int FW[fwmax]; // fenwick

void inc(int i,int v){
	while (i < maxn){
		FW[i] += v;
		i += i & (-i);
	}
}
int get(int i){
	int sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; cin >> n >> k;

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		cin >> x[i] >> r[i] >> freq;
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	int sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				int v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v-1;
				//inc(p2 , 1);
			}
		}
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , -1);
			}
		}

	}
	cout << sol << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 20;//1e4 + 100;
const int maxk = 100005;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

int FW[maxn]; // fenwick

void inc(int i,int v){
	while (i < maxn){
		FW[i] += v;
		i += i & (-i);
	}
}
int get(int i){
	int sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; cin >> n >> k;

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		cin >> x[i] >> r[i] >> freq;
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());
	for (int i = 0;i < points.size();i++){
		c[points[i]] = i+1;
	}

	int sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				Q.push_back( mp(f[j][qw] , i == j) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				int v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v;
				inc(p2 , 1);
			}
		}
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , -1);
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				inc(p2 , -1);
			}
		}

	}
	cout << sol << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 5;
const int maxf = 1e4 ;
const int fwmax = (1<<18)+1;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

ll FW[fwmax]; // fenwick

void inc(int i,ll v){
	while (i < fwmax){
		FW[i] += v;
		i += i & (-i);
	}
}
ll get(int i){
	ll sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; scanf("%d%d",&n,&k);

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		scanf("%d%d%d",&x[i],&r[i],&freq);
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	ll sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		queue <int> back;
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				back.push(p);
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				ll v = get(p2) - get(p1-1);
				sol += v-1;
			}
		}
		while (back.size() > 0){
			inc(back.front(),-1); back.pop();
		}

	}
	printf(lld,sol);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 5;
const int maxf = 1e4 + 5;
const int fwmax = (1<<18)+1;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

ll FW[fwmax]; // fenwick

void inc(int i,ll v){
	while (i < fwmax){
		FW[i] += v;
		i += i & (-i);
	}
}
ll get(int i){
	ll sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; scanf("%d%d",&n,&k);

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		scanf("%d%d%d",&x[i],&r[i],&freq);
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	ll sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		queue <int> back;
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				back.push(p);
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				ll v = get(p2) - get(p1-1);
				sol += v-1;
			}
		}
		while (back.size() > 0){
			inc(back.front(),-1); back.pop();
		}

	}
	printf(lld,sol);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;
const int fwmax = 1e7 + 100;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

ll FW[fwmax]; // fenwick

void inc(int i,ll v){
	while (i < fwmax){
		FW[i] += v;
		i += i & (-i);
	}
}
ll get(int i){
	ll sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; cin >> n >> k;

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		cin >> x[i] >> r[i] >> freq;
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	ll sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				ll v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v-1;
				//inc(p2 , 1);
			}
		}
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , -1);
			}
		}

	}
	cout << sol << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 5;
const int maxf = 1e4 + 5;
const int fwmax = (1<<18)+1;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

ll FW[fwmax]; // fenwick

void inc(int i,ll v){
	while (i < fwmax){
		FW[i] += v;
		i += i & (-i);
	}
}
ll get(int i){
	ll sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
struct compare2{
	bool operator()(int a,int b){
		return a > b;
	}
};
int main(){
	int n , k; scanf("%d%d",&n,&k);

	priority_queue <int,vector<int>,compare2> points;

	for (int i = 1;i <= n;i++){
		int freq;
		scanf("%d%d%d",&x[i],&r[i],&freq);
		f[freq].push_back(i);
		points.push(x[i]);
		points.push(x[i] + r[i]);
	}
	//sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	while (points.size() > 0){
		if (points.top() != last) c[points.top()] = cnt++;
		last = points.top();
		points.pop();
	}

	ll sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		queue <int> back;
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				back.push(p);
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				ll v = get(p2) - get(p1-1);
				sol += v-1;
			}
		}
		while (back.size() > 0){
			inc(back.front(),-1); back.pop();
		}

	}
	printf(lld,sol);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;
const int fwmax = (1<<17)+1;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

ll FW[fwmax]; // fenwick

void inc(int i,ll v){
	while (i < fwmax){
		FW[i] += v;
		i += i & (-i);
	}
}
ll get(int i){
	ll sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; scanf("%d%d",&n,&k);

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		scanf("%d%d%d",&x[i],&r[i],&freq);
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	ll sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				ll v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v-1;
				//inc(p2 , 1);
			}
		}
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , -1);
			}
		}

	}
	printf(lld,sol);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;
const int fwmax = (1<<18)+1;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

ll FW[fwmax]; // fenwick

void inc(int i,ll v){
	while (i < fwmax){
		FW[i] += v;
		i += i & (-i);
	}
}
ll get(int i){
	ll sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; scanf("%d%d",&n,&k);

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		scanf("%d%d%d",&x[i],&r[i],&freq);
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	ll sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		queue <int> back;
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				back.push(p);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				ll v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v-1;
				//inc(p2 , 1);
			}
		}
		while (back.size() > 0){
			inc(back.front(),-1); back.pop();
		}

	}
	printf(lld,sol);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;
const int fwmax = 1e7 + 100;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

ll FW[fwmax]; // fenwick

void inc(int i,int v){
	while (i < maxn){
		FW[i] += v;
		i += i & (-i);
	}
}
ll get(int i){
	ll sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; cin >> n >> k;

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		cin >> x[i] >> r[i] >> freq;
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	ll sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				if (i == j) Q.push_back( mp(f[j][qw] , 1) );
 				Q.push_back( mp(f[j][qw] , 0) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				ll v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v-1;
				//inc(p2 , 1);
			}
		}
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , -1);
			}
		}

	}
	cout << sol << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e5 + 100;
const int maxf = 1e4 + 100;

map <int , int > c; // coordinates
int x[maxn] , r[maxn] ;
vector <int> f[maxf];

int FW[maxn]; // fenwick

void inc(int i,int v){
	while (i < maxn){
		FW[i] += v;
		i += i & (-i);
	}
}
int get(int i){
	int sol = 0;
	while (i > 0){
		sol += FW[i];
		i -= i & (-i);
	}
	return sol;
}
bool compare( pi a, pi b){
	int a_pos = a.second ? x[a.first] : x[a.first]-r[a.first];
	int b_pos = b.second ? x[b.first] : x[b.first]-r[b.first];
	if (a_pos != b_pos){
		return a_pos < b_pos;
	}
	return a.second < b.second;
}
int main(){
	int n , k; cin >> n >> k;

	vector <int> points;

	for (int i = 1;i <= n;i++){
		int freq;
		cin >> x[i] >> r[i] >> freq;
		f[freq].push_back(i);
		points.push_back(x[i]);
		points.push_back(x[i] + r[i]);
	}
	sort(points.begin(),points.end());

	int last = -1;
	int cnt = 1;
	for (int i = 0;i < points.size();i++){
		if (points[i] != last) c[points[i]] = cnt++;
		last = points[i];
	}

	int sol = 0;
	for (int i = 1;i <= maxf;i++){ // for each freq
		//cout << "freq " << i << ": \n";
		vector <pi> Q;
		for (int j = max(1,i - k);j <= min(maxf,i + k);j++){
 			//cout << "add f " << j << '\n';
 			for (int qw = 0;qw < f[j].size();qw++){
 				Q.push_back( mp(f[j][qw] , i == j) );
 			}
		}

		sort( Q.begin() , Q.end() , compare);
		//cout << "qz = " << Q.size() << '\n';
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , 1);
				//cout << "inc " << x[Q[j].first] << '\n';
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				//cout << p1 << ' ' << p2 << '\n';
				int v = get(p2) - get(p1-1);
				//cout << "add " << Q[j].first << ":" << v <<  '\n';
				sol += v;
				inc(p2 , 1);
			}
		}
		for (int j = 0;j < Q.size();j++){
			if (Q[j].second == 0){
				int p = c[x[Q[j].first]];
				inc(p , -1);
			}
			if (Q[j].second == 1){
				int p1 = c[x[Q[j].first]];
				int p2 = c[x[Q[j].first]+r[Q[j].first]];
				inc(p2 , -1);
			}
		}

	}
	cout << sol << '\n';
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i, x, n) for(int i = x; i < (int)n; ++i)

vector<pair<int, int> > f[10001];
int fn[2][100001], n, k;
vector<int> id;

inline void ad(int i, int x, int fn[]) { while (i <= n)fn[i] += x, i += i & -i; }
inline int gt(int i, int fn[]) { i = max(i, 0); int an = 0; while (i)an += fn[i], i ^= i & -i; return an; }

inline int gtid(int x){
	return lower_bound(id.begin(), id.end(), x) - id.begin() + 1;
}

int main() {
	scanf("%d%d", &n, &k);
	f(i, 0, n){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		f[c].push_back(make_pair(a, b));
		id.push_back(a);
	}
	sort(id.begin(), id.end());
	f(i, 1, 10001)sort(f[i].begin(), f[i].end());
	ll an = 0;
	f(i, 1, 10001)if (!f[i].empty())f(j, 0, k + 1)if (i + j <= 10000 && !f[i + j].empty()){
		set<pair<int, int> > d[2];
		vector<pair<int, int> > v;
		f(z, 0, f[i].size())v.push_back(make_pair(f[i][z].first, z));
		f(z, 0, f[i + j].size())v.push_back(make_pair(f[i + j][z].first, f[i].size() + z));
		sort(v.begin(), v.end());
		ll kk = 0;
		f(z, 0, v.size()){
			int o = v[z].second >= f[i].size();
			if (o)v[z].second -= f[i].size();
			while (!d[o ^ 1].empty() && d[o ^ 1].begin()->first < v[z].first){
				int t = d[o ^ 1].begin()->second;
				ad(f[o ? i : i + j][t].first, -1, fn[o ^ 1]);
				d[o ^ 1].erase(d[o ^ 1].begin());
			}
			kk += d[o ^ 1].size() - gt(v[z].first - 1 - f[o ? j + i : i][v[z].second].second, fn[o ^ 1]);
			d[o].insert(make_pair(v[z].first + f[o ? j + i : i][v[z].second].second, v[z].second));
			ad(v[z].first, 1, fn[o]);
		}
		f(o, 0, 2)while (!d[o].empty()){
			int t = d[o].begin()->second;
			ad(f[o ? i + j : i][t].first, -1, fn[o]);
			d[o].erase(d[o].begin());
		}
		if (j == 0)kk -= f[i].size(), kk >>= 1;
		an += kk;
	}
	printf("%lld\n", an);
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i, x, n) for(int i = x; i < (int)n; ++i)

vector<pair<int, int> > f[10001];
int fn[2][100001], n, k;
vector<int> id;

inline void ad(int i, int x, int fn[]) { while (i <= n)fn[i] += x, i += i & -i; }
inline int gt(int i, int fn[]) { i = max(i, 0); int an = 0; while (i)an += fn[i], i ^= i & -i; return an; }

inline int gtid(int x) { return lower_bound(id.begin(), id.end(), x) - id.begin() + 1; }

int main() {
	scanf("%d%d", &n, &k);
	f(i, 0, n){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		f[c].push_back(make_pair(a, b));
		id.push_back(a);
	}
	sort(id.begin(), id.end());
	f(i, 1, 10001)sort(f[i].begin(), f[i].end());
	ll an = 0;
	f(i, 1, 10001)if (!f[i].empty())f(j, 0, k + 1)if (i + j <= 10000 && !f[i + j].empty()){
		set<pair<int, int> > d[2];
		vector<pair<int, int> > v;
		f(z, 0, f[i].size())v.push_back(make_pair(f[i][z].first, z));
		f(z, 0, f[i + j].size())v.push_back(make_pair(f[i + j][z].first, f[i].size() + z));
		sort(v.begin(), v.end());
		ll kk = 0;
		f(z, 0, v.size()){
			int o = v[z].second >= f[i].size();
			if (o)v[z].second -= f[i].size();
			while (!d[o ^ 1].empty() && d[o ^ 1].begin()->first < v[z].first){
				int t = d[o ^ 1].begin()->second;
				ad(gtid(f[o ? i : i + j][t].first), -1, fn[o ^ 1]);
				d[o ^ 1].erase(d[o ^ 1].begin());
			}
			kk += d[o ^ 1].size() - gt(v[z].first - 1 - f[o ? j + i : i][v[z].second].second, fn[o ^ 1]);
			d[o].insert(make_pair(v[z].first + f[o ? j + i : i][v[z].second].second, v[z].second));
			ad(gtid(v[z].first), 1, fn[o]);
			if (o)v[z].second += f[i].size();
		}
		f(o, 0, 2)while (!d[o].empty()){
			int t = d[o].begin()->second;
			ad(gtid(f[o ? i + j : i][t].first), -1, fn[o]);
			d[o].erase(d[o].begin());
		}
		if (j == 0)kk -= f[i].size(), kk >>= 1;
		an += kk;
	}
	printf("%lld\n", an);
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i, x, n) for(int i = x; i < (int)n; ++i)

vector<pair<int, int> > f[10001];
int fn[2][100001], n, k;
vector<int> id;

inline void ad(int i, int x, int fn[]) { while (i <= n)fn[i] += x, i += i & -i; }
inline int gt(int i, int fn[]) { i = max(i, 0); int an = 0; while (i)an += fn[i], i ^= i & -i; return an; }

inline int gtid(int x){
	return lower_bound(id.begin(), id.end(), x) - id.begin() + 1;
}

int main() {
	scanf("%d%d", &n, &k);
	f(i, 0, n){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		f[c].push_back(make_pair(a, b));
		id.push_back(a);
	}
	sort(id.begin(), id.end());
	f(i, 1, 10001)sort(f[i].begin(), f[i].end());
	ll an = 0;
	f(i, 1, 10001)if (!f[i].empty())f(j, 0, k + 1)if (i + j <= 10000 && !f[i + j].empty()){
		set<pair<int, int> > d[2];
		vector<pair<int, int> > v;
		f(z, 0, f[i].size())v.push_back(make_pair(f[i][z].first, z));
		f(z, 0, f[i + j].size())v.push_back(make_pair(f[i + j][z].first, f[i].size() + z));
		sort(v.begin(), v.end());
		ll kk = 0;
		f(z, 0, v.size()){
			int o = v[z].second >= f[i].size();
			if (o)v[z].second -= f[i].size();
			while (!d[o ^ 1].empty() && d[o ^ 1].begin()->first < v[z].first){
				int t = d[o ^ 1].begin()->second;
				ad(gtid(f[o ? i : i + j][t].first), -1, fn[o ^ 1]);
				d[o ^ 1].erase(d[o ^ 1].begin());
			}
			kk += d[o ^ 1].size() - gt(v[z].first - 1 - f[o ? j + i : i][v[z].second].second, fn[o ^ 1]);
			d[o].insert(make_pair(v[z].first + f[o ? j + i : i][v[z].second].second, v[z].second));
			ad(gtid(v[z].first), 1, fn[o]);
		}
		f(o, 0, 2)while (!d[o].empty()){
			int t = d[o].begin()->second;
			ad(gtid(f[o ? i + j : i][t].first), -1, fn[o]);
			d[o].erase(d[o].begin());
		}
		if (j == 0)kk -= f[i].size(), kk >>= 1;
		an += kk;
	}
	printf("%lld\n", an);
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i, x, n) for(int i = x; i < (int)n; ++i)

vector<pair<int, int> > f[10001];
int fn[100001], n, k;
vector<int> id;

inline void ad(int i, int x) { while (i <= n)fn[i] += x, i += i & -i; }
inline int gt(int i) { i = max(i, 0); int an = 0; while (i)an += fn[i], i ^= i & -i; return an; }

inline int gtid(int x){
	return lower_bound(id.begin(), id.end(), x) - id.begin() + 1;
}

int main() {
	scanf("%d", &n, &k);
	f(i, 0, n){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		f[c].push_back(make_pair(a, b));
		id.push_back(a);
	}
	sort(id.begin(), id.end());
	f(i, 1, 10001)sort(f[i].begin(), f[i].end());
	ll an = 0;
	f(i, 1, 10001)if (!f[i].empty())f(j, 0, k + 1)if (!f[i + j].empty()){
		set<pair<int, int> > d[2];
		vector<pair<int, int> > v;
		f(z, 0, f[i].size())v.push_back(make_pair(f[i][z].first, z));
		f(z, 0, f[i + j].size())v.push_back(make_pair(f[j][z].first, f[i].size() + z));
		sort(v.begin(), v.end());
		f(z, 0, v.size()){
			int o = v[z].second >= f[i].size();
			while (!d[o ^ 1].empty() && d[o ^ 1].begin()->first < v[z].first){
				int t = d[o ^ 1].begin()->second;
				ad(f[o ? j : i][t].first, -1);
				d[o ^ 1].erase(d[o ^ 1].begin());
			}
			an += d[o ^ 1].size() - gt(v[z].first - 1 - f[o ? j : i][v[z].second].second);
			d[o].insert(make_pair(v[z].first + f[o ? j : i][v[z].second].first, v[z].second));
		}
	}
	printf("%lld\n", an);
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i, x, n) for(int i = x; i < (int)n; ++i)

vector<pair<int, int> > f[10001];
int fn[2][200001], n, k;
vector<int> id;

inline void ad(int i, int x, int fn[]) { while (i <= n << 1)fn[i] += x, i += i & -i; }
inline int gt(int i, int fn[]) { int an = 0; while (i)an += fn[i], i ^= i & -i; return an; }
inline int gtid(int x) { return lower_bound(id.begin(), id.end(), x) - id.begin() + 1; }

int main() {
	scanf("%d%d", &n, &k);
	f(i, 0, n){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		f[c].push_back(make_pair(a, b));
		id.push_back(a);
		id.push_back(a - b - 1);
	}
	sort(id.begin(), id.end());
	f(i, 1, 10001)sort(f[i].begin(), f[i].end());
	ll an = 0;
	f(i, 1, 10001)if (!f[i].empty())f(j, 0, k + 1)if (i + j <= 10000 && !f[i + j].empty()){
		set<pair<int, int> > d[2];
		vector<pair<int, int> > v;
		f(z, 0, f[i].size())v.push_back(make_pair(f[i][z].first, z));
		f(z, 0, f[i + j].size())v.push_back(make_pair(f[i + j][z].first, f[i].size() + z));
		sort(v.begin(), v.end());
		ll kk = 0;
		f(z, 0, v.size()){
			int o = v[z].second >= f[i].size();
			if (o)v[z].second -= f[i].size();
			while (!d[o ^ 1].empty() && d[o ^ 1].begin()->first < v[z].first){
				int t = d[o ^ 1].begin()->second;
				ad(gtid(f[o ? i : i + j][t].first), -1, fn[o ^ 1]);
				d[o ^ 1].erase(d[o ^ 1].begin());
			}
			kk += d[o ^ 1].size() - gt(gtid(v[z].first - 1 - f[o ? j + i : i][v[z].second].second), fn[o ^ 1]);
			d[o].insert(make_pair(v[z].first + f[o ? j + i : i][v[z].second].second, v[z].second));
			ad(gtid(v[z].first), 1, fn[o]);
			if (o)v[z].second += f[i].size();
		}
		f(o, 0, 2)while (!d[o].empty()){
			int t = d[o].begin()->second;
			ad(gtid(f[o ? i + j : i][t].first), -1, fn[o]);
			d[o].erase(d[o].begin());
		}
		if (j == 0)kk -= f[i].size(), kk >>= 1;
		an += kk;
	}
	printf("%lld\n", an);
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i, x, n) for(int i = x; i < (int)n; ++i)

vector<pair<int, int> > f[10001];
int fn[2][200001], n, k;
vector<int> id;

inline void ad(int i, int x, int fn[]) { while (i <= n)fn[i] += x, i += i & -i; }
inline int gt(int i, int fn[]) { int an = 0; while (i)an += fn[i], i ^= i & -i; return an; }

inline int gtid(int x) { return lower_bound(id.begin(), id.end(), x) - id.begin() + 1; }

int main() {
	scanf("%d%d", &n, &k);
	f(i, 0, n){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		f[c].push_back(make_pair(a, b));
		id.push_back(a);
		id.push_back(a - b - 1);
	}
	sort(id.begin(), id.end());
	f(i, 1, 10001)sort(f[i].begin(), f[i].end());
	ll an = 0;
	f(i, 1, 10001)if (!f[i].empty())f(j, 0, k + 1)if (i + j <= 10000 && !f[i + j].empty()){
		set<pair<int, int> > d[2];
		vector<pair<int, int> > v;
		f(z, 0, f[i].size())v.push_back(make_pair(f[i][z].first, z));
		f(z, 0, f[i + j].size())v.push_back(make_pair(f[i + j][z].first, f[i].size() + z));
		sort(v.begin(), v.end());
		ll kk = 0;
		f(z, 0, v.size()){
			int o = v[z].second >= f[i].size();
			if (o)v[z].second -= f[i].size();
			while (!d[o ^ 1].empty() && d[o ^ 1].begin()->first < v[z].first){
				int t = d[o ^ 1].begin()->second;
				ad(gtid(f[o ? i : i + j][t].first), -1, fn[o ^ 1]);
				d[o ^ 1].erase(d[o ^ 1].begin());
			}
			kk += d[o ^ 1].size() - gt(gtid(v[z].first - 1 - f[o ? j + i : i][v[z].second].second), fn[o ^ 1]);
			d[o].insert(make_pair(v[z].first + f[o ? j + i : i][v[z].second].second, v[z].second));
			ad(gtid(v[z].first), 1, fn[o]);
			if (o)v[z].second += f[i].size();
		}
		f(o, 0, 2)while (!d[o].empty()){
			int t = d[o].begin()->second;
			ad(gtid(f[o ? i + j : i][t].first), -1, fn[o]);
			d[o].erase(d[o].begin());
		}
		if (j == 0)kk -= f[i].size(), kk >>= 1;
		an += kk;
	}
	printf("%lld\n", an);
}


// for multiple merge, see : https://codeforces.com/contest/762/submission/76750679

/*
    NOTE: There are other data structures that might work for this, which also allow updation :o
    Check these submissions:
    https://codeforces.com/contest/762/submission/58092388
    https://codeforces.com/contest/1093/submission/47229079
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 5; // see range
ll a[N];
vector<ll> tree[N << 2];
void build(int node, int st, int end){
    if(st == end){
        tree[node].push_back(a[st]);
        return;
    }
    int mid = st + end >> 1;
    build(node << 1, st, mid);
    build((node << 1) | 1, mid + 1, end);
    merge(tree[node << 1].begin(), tree[node << 1].end(),
          tree[(node << 1) | 1].begin(), tree[(node << 1) | 1].end(),
          back_inserter(tree[node]));
}
// returns the count of elements <= k in range [l, r]
ll query(int node, int st, int end, int l, int r, ll k){    // see return type and type of k
    if(st > end || r < st || end < l)
        return 0;
    if(l <= st && end <= r){
        return(upper_bound(tree[node].begin(), tree[node].end(), k) - tree[node].begin());
    }
    int mid = st + end >> 1;
    return (query(node << 1, st, mid, l, r, k) + query((node << 1) | 1, mid + 1, end, l, r, k));
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n, m, t, l, r;
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> a[i];
    build(1, 1, n);
return 0;
}


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

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

const int N = 1e4 + 10;
struct radio{
    int x, r, f;
    bool operator <(const radio & r) const{
        return x < r.x;
    }
};
vector<radio> tower[N];
ll a[N];
vector<vector<int> > tree[N];
int cnt = 0;
void build(int id, int node, int st, int end){
    if(st == end){
        tree[id][node].push_back(tower[id][st - 1].x - tower[id][st - 1].r);
        return;
    }
    int mid = st + end >> 1;
    build(id, node << 1, st, mid);
    build(id, (node << 1) | 1, mid + 1, end);
    merge(tree[id][node << 1].begin(), tree[id][node << 1].end(),
          tree[id][(node << 1) | 1].begin(), tree[id][(node << 1) | 1].end(),
          back_inserter(tree[id][node]));
}
// returns the count of elements <= k in range [l, r]
ll query(int id, int node, int st, int end, int l, int r, ll k){    // see return type and type of k
    if(st > end || r < st || end < l || l > r)
        return 0;
    if(l <= st && end <= r){
        return(upper_bound(tree[id][node].begin(), tree[id][node].end(), k) - tree[id][node].begin());
    }
    int mid = st + end >> 1;
    return (query(id, node << 1, st, mid, l, r, k) + query(id, (node << 1) | 1, mid + 1, end, l, r, k));
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n, k;
    cin >> n >> k;
    for(int i = 0; i < n; i++){
        radio yo;
        cin >> yo.x >> yo.r >> yo.f;
        tower[yo.f].push_back(yo);
    }
    for(int i = 0; i < N; i++){
        sort(tower[i].begin(), tower[i].end());
        tree[i].resize((((int)tower[i].size()) << 2) + 5);
        if((int)tower[i].size()){
            build(i, 1, 1, (int)tower[i].size());
        }
    }
    ll ans = 0;
    for(int i = 0; i < N; i++){
        int szi = (int)tower[i].size();
        for(int j = 0; j < szi; j++){
            int curX = tower[i][j].x;
            int curR = tower[i][j].r;
            int rX = curX + curR;
            for(int K = max(0, i - k); K <= min(N - 1, i + k); K++){
                int szk = (int)tower[K].size();
                if(szk == 0) continue;
                // first find range for x i.e. elements who's x is > curX && x <= rX
                // then after finding range, do range query for elements whose x - r <= curX
                int lo = -1, hi = szk;
                while(hi - lo > 1){
                    int mid = hi + lo >> 1;
                    if(tower[K][mid].x > curX){
                        hi = mid;
                    }
                    else{
                        lo = mid;
                    }
                }
                int L = hi;
                lo = -1, hi = szk;
                while(hi - lo > 1){
                    int mid = hi + lo >> 1;
                    if(tower[K][mid].x <= rX)
                        lo = mid;
                    else hi = mid;
                }
                int R = lo;
                int yo = query(K, 1, 1, szk, L + 1, R + 1, curX);
                ans += yo;
            }
        }
    }
    cout << ans;
return 0;
}


// Aggressive Play

#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
using namespace std;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> oset;

const int N = 1e4 + 5;
struct radio{
    int x, r, f;
    bool operator < (const radio & ra) const{
        return r > ra.r;
    }
};
oset radios[N];
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n, k;
    cin >> n >> k;
    vector<radio> v;
    for(int i = 0; i < n; i++){
        radio yo;
        cin >> yo.x >> yo.r >> yo.f;
        v.push_back(yo);
    }
    sort(v.begin(), v.end());
    ll ans = 0;
    for(auto i : v){
        int f = i.f;
        for(int j = max(1, f - k); j <= min(N - 1, f + k); j++){
            ans += radios[j].order_of_key(i.x + i.r + 1) - radios[j].order_of_key(i.x - i.r);
        }
        radios[f].insert(i.x);
    }
    cout << ans;
return 0;
}


#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define sz(a) ((int)(a).size())
#define rep(i, a, b) for(int (i) = (a); (i) < (b); (i)++)
#define dec(i, a, b) for(int (i) = (a); (i) >= (b); (i)--)
#define clr(a,v) memset(a, v, sizeof(a))
#define EPS 1e-6
#define all(a) (a).begin(),(a).end()
#define MAXN 101010
#define MAXM 10101
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

int bigrand(){ return ((rand() << 16) ^ rand()); }
struct Treap{
	struct Node{
	int val, pri, tam;
	Node *l, *r;
	Node(){}
	Node(int v): val(v), pri(bigrand()), tam(1), l(NULL), r(NULL){}
	} *root;
	Treap(): root(NULL){}
	int size(Node*node){return node==NULL?0:node->tam;}
	void upd(Node*node){
		if(node == NULL) return;
		node->tam = size(node->l) + size(node->r) + 1;
	}
	Node* merge(Node *l, Node *r){
		if(l == NULL) return r;
		if(r == NULL) return l;
		if(l->pri > r->pri){
			l->r = merge(l->r, r);
			upd(l);
			return l;
		}
			r->l = merge(l, r->l);
			upd(r);
			return r;
	}
	void split(Node *node, int v, Node *&a, Node *&b){
		if(node == NULL){ a = b = NULL; return; }
		if(node->val <= v){
			split(node->r, v, node->r, b);
			a = node; upd(a);
		}else{
			split(node->l, v, a, node->l);
			b = node; upd(b);
		}
	}
	void insert(int v){
		Node * a, * b;
		split(root, v, a, b);
		root = merge(merge(a, new Node(v)), b);
	}
	int getqt(Node * node, int v){
		if(node == NULL) return 0;
		if(node->val <= v) return size(node->l) + 1 + getqt(node->r, v);
		return getqt(node->r,v);
	}
	int query(int l, int r){ return getqt(root, r) - getqt(root, l-1); }
}bit[MAXM];

void upd(int x, int y){
	for(x++; x < MAXM; x+=x&-x)
		bit[x].insert(y);
}

int query(int x, int l, int r){
	int ret = 0;
	for(x++; x ; x-=x&-x)
		ret += bit[x].query(l,r);
	return ret;
}
int query(int xi, int xf, int l, int r){ return query(xf,l,r)-query(xi-1,l,r); }

struct radio{
	int x, r, f;
}vet[MAXN];
bool operator<(radio a, radio b){ return a.r > b.r; }
int n, k;

int main(){
	scanf("%d%d", &n, &k);
	rep(i,0,n) scanf("%d%d%d", &vet[i].x, &vet[i].r, &vet[i].f);
	sort(vet,vet+n);
	ll ans = 0;
	rep(i,0,n){
		int x = vet[i].x, r = vet[i].r, f = vet[i].f;
		ans += query(f-k, f+k, x-r, x+r);
		upd(f,x);
	}
	printf("%lld\n", ans);
}


#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define sz(a) ((int)(a).size())
#define rep(i, a, b) for(int (i) = (a); (i) < (b); (i)++)
#define dec(i, a, b) for(int (i) = (a); (i) >= (b); (i)--)
#define clr(a,v) memset(a, v, sizeof(a))
#define EPS 1e-6
#define all(a) (a).begin(),(a).end()
#define MAXN 101010
#define MAXM 10101
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

int bigrand(){ return ((rand() << 16) ^ rand()); }
struct Treap{
	struct Node{
	int val, pri, tam;
	Node *l, *r;
	Node(){}
	Node(int v): val(v), pri(bigrand()), tam(1), l(NULL), r(NULL){}
	} *root;
	Treap(): root(NULL){}
	int size(Node*node){return node==NULL?0:node->tam;}
	void upd(Node*node){
		if(node == NULL) return;
		node->tam = size(node->l) + size(node->r) + 1;
	}
	void modify(Node *&node, int v){
		if(node == NULL){ node = new Node(v); return; }
		if(node->val >= v){
			modify(node->l, v);
			if(node->pri < node->l->pri){
				Node *tmp = node->l;
				node->l = tmp->r;
				tmp->r = node;
				node = tmp;
				upd(node->r);
			}
		}else{
			modify(node->r, v);
			if(node->pri < node->r->pri){
				Node *tmp = node->r;
				node->r = tmp->l;
				tmp->l = node;
				node = tmp;
				upd(node->l);
			}
		}
		upd(node);
	}
	void modify(int v){modify(root,v);}
	int getqt(Node * node, int v){
		if(node == NULL) return 0;
		if(node->val <= v) return size(node->l) + 1 + getqt(node->r, v);
		return getqt(node->l,v);
	}
	int query(int l, int r){ return getqt(root, r) - getqt(root, l-1); }
}bit[MAXM];

void upd(int x, int y){
	for(x++; x < MAXM; x+=x&-x)
		bit[x].modify(y);
}

int query(int x, int l, int r){
	int ret = 0;
	for(x++; x > 0; x-=x&-x)
		ret += bit[x].query(l,r);
	return ret;
}
int query(int xi, int xf, int l, int r){ return query(xf,l,r)-query(xi-1,l,r); }

struct radio{
	int x, r, f;
}vet[MAXN];
bool operator<(radio a, radio b){ return a.r > b.r; }
int n, k;

int main(){
    srand(time(NULL));
	scanf("%d%d", &n, &k);
	rep(i,0,n) scanf("%d%d%d", &vet[i].x, &vet[i].r, &vet[i].f);
	sort(vet,vet+n);
	ll ans = 0;
	rep(i,0,n){
		int x = vet[i].x, r = vet[i].r, f = vet[i].f;
		ans += query(f-k, f+k, x-r, x+r);
		upd(f,x);
	}
	printf("%lld\n", ans);
}


#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define sz(a) ((int)(a).size())
#define rep(i, a, b) for(int (i) = (a); (i) < (b); (i)++)
#define dec(i, a, b) for(int (i) = (a); (i) >= (b); (i)--)
#define clr(a,v) memset(a, v, sizeof(a))
#define EPS 1e-6
#define all(a) (a).begin(),(a).end()
#define MAXN 101010
#define MAXM 10101
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

int bigrand(){ return ((rand() << 16) ^ rand()); }
struct Treap{
	struct Node{
	int val, pri, tam;
	Node *l, *r;
	Node(){}
	Node(int v): val(v), pri(bigrand()), tam(1), l(NULL), r(NULL){}
	} *root;
	Treap(): root(NULL){}
	int size(Node*node){return node==NULL?0:node->tam;}
	void upd(Node*node){
		if(node == NULL) return;
		node->tam = size(node->l) + size(node->r) + 1;
	}
	void modify(Node *&node, int v){
		if(node == NULL){ node = new Node(v); return; }
		if(node->val >= v){
			modify(node->l, v);
			if(node->pri < node->l->pri){
				Node *tmp = node->l;
				node->l = tmp->r;
				tmp->r = node;
				node = tmp;
				upd(node->r);
			}
		}else{
			modify(node->r, v);
			if(node->pri < node->r->pri){
				Node *tmp = node->r;
				node->r = tmp->l;
				tmp->l = node;
				node = tmp;
				upd(node->l);
			}
		}
		upd(node);
	}
	void modify(int v){modify(root,v);}
	int getqt(Node * node, int v){
		if(node == NULL) return 0;
		if(node->val <= v) return size(node->l) + 1 + getqt(node->r, v);
		return getqt(node->r,v);
	}
	int query(int l, int r){ return getqt(root, r) - getqt(root, l-1); }
}bit[MAXM];

void upd(int x, int y){
	for(x++; x < MAXM; x+=x&-x)
		bit[x].modify(y);
}

int query(int x, int l, int r){
	int ret = 0;
	for(x++; x > 0; x-=x&-x)
		ret += bit[x].query(l,r);
	return ret;
}
int query(int xi, int xf, int l, int r){ return query(xf,l,r)-query(xi-1,l,r); }

struct radio{
	int x, r, f;
}vet[MAXN];
bool operator<(radio a, radio b){ return a.r > b.r; }
int n, k;

int main(){
	scanf("%d%d", &n, &k);
	rep(i,0,n) scanf("%d%d%d", &vet[i].x, &vet[i].r, &vet[i].f);
	sort(vet,vet+n);
	ll ans = 0;
	rep(i,0,n){
		int x = vet[i].x, r = vet[i].r, f = vet[i].f;
		ans += query(f-k, f+k, x-r, x+r);
		upd(f,x);
	}
	printf("%lld\n", ans);
}


#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define sz(a) ((int)(a).size())
#define rep(i, a, b) for(int (i) = (a); (i) < (b); (i)++)
#define dec(i, a, b) for(int (i) = (a); (i) >= (b); (i)--)
#define clr(a,v) memset(a, v, sizeof(a))
#define EPS 1e-6
#define all(a) (a).begin(),(a).end()
#define MAXN 101010
#define MAXM 10101
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

int bigrand(){ return ((rand() << 16) ^ rand()); }
struct Treap{
	struct Node{
	int val, pri, tam;
	Node *l, *r;
	Node(){}
	Node(int v): val(v), pri(bigrand()), tam(1), l(NULL), r(NULL){}
	} *root;
	Treap(): root(NULL){}
	int size(Node*node){return node==NULL?0:node->tam;}
	void upd(Node*node){
		if(node == NULL) return;
		node->tam = size(node->l) + size(node->r) + 1;
	}
	void modify(Node *&node, int v){
		if(node == NULL){ node = new Node(v); return; }
		if(node->val >= v){
			modify(node->l, v);
			if(node->pri < node->l->pri){
				Node *tmp = node->l;
				node->l = tmp->r;
				tmp->r = node;
				node = tmp;
				upd(node->r);
			}
		}else{
			modify(node->r, v);
			if(node->pri < node->r->pri){
				Node *tmp = node->r;
				node->r = tmp->l;
				tmp->l = node;
				node = tmp;
				upd(node->l);
			}
		}
		upd(node);
	}
	void modify(int v){modify(root,v);}
	int getqt(Node * node, int v){
		if(node == NULL) return 0;
		if(node->val <= v) return size(node->l) + 1 + getqt(node->r, v);
		return getqt(node->r,v);
	}
	int query(int l, int r){ return getqt(root, r) - getqt(root, l-1); }
}bit[MAXM];

void upd(int x, int y){
	for(x++; x < MAXM; x+=x&-x)
		bit[x].modify(y);
}

int query(int x, int l, int r){
	int ret = 0;
	for(x++; x ; x-=x&-x)
		ret += bit[x].query(l,r);
	return ret;
}
int query(int xi, int xf, int l, int r){ return query(xf,l,r)-query(xi-1,l,r); }

struct radio{
	int x, r, f;
}vet[MAXN];
bool operator<(radio a, radio b){ return a.r > b.r; }
int n, k;

int main(){
	scanf("%d%d", &n, &k);
	rep(i,0,n) scanf("%d%d%d", &vet[i].x, &vet[i].r, &vet[i].f);
	sort(vet,vet+n);
	ll ans = 0;
	rep(i,0,n){
		int x = vet[i].x, r = vet[i].r, f = vet[i].f;
		ans += query(f-k, f+k, x-r, x+r);
		upd(f,x);
	}
	printf("%lld\n", ans);
}


#include <bits/stdc++.h>

#define SQ(a) (a)*(a)

#define F0R(i, a) for(int i = 0; i < (a); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define R0F(i, a) for(int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for(int i = (b) - 1; i >= (a); i--)

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()
#define MAXN 100000
#define MAXF 10000

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<ld> point;

struct RUSQ {

    int sz;
    ll *tree;

    RUSQ(int sz) {
        this->sz = sz;
        tree = new ll[sz + 1];
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }

    void update(int idx, ll v) {
        for(idx++; idx <= sz; idx += (idx & -idx)) tree[idx] += v;
    }

    void updateRange(int lo, int hi, int v) {
        update(lo, v);
        update(hi + 1, -v);
    }

    ll query(int idx) {
        ll total = 0;
        for(idx++; idx > 0; idx -= (idx & -idx)) total += tree[idx];
        return total;
    }

    void reset() {
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }
};

int n, k, x[MAXN], r[MAXN];
vi withFreq[MAXF];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> k;
    vi xValues;
    F0R(i, n) {
        int f;
        cin >> x[i] >> r[i] >> f;
        withFreq[--f].PB(i);
        xValues.PB(x[i]);
    }
    sort(xValues.begin(), xValues.end());
    ll res = 0;
    RUSQ rusq(MAXN);
    F0R(freq, MAXF) {
        vector<tuple<int, int, int>> toProcess;
        FOR(i, max(0, freq - k), freq) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        for(const int i : withFreq[freq]) toProcess.PB(MT(r[i], x[i], 1));
        FOR(i, freq + 1, min(MAXF, freq + k + 1)) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        sort(toProcess.begin(), toProcess.end());
        rusq.reset();
        for(const tuple<int, int, int> t : toProcess) {
            int range = get<0>(t);
            int place = get<1>(t);
            int task = get<2>(t);
            if(task == 1) res += rusq.query(LB(xValues.begin(), xValues.end(), place) - xValues.begin());
            int lo = LB(xValues.begin(), xValues.end(), place - range) - xValues.begin();
            int hi = UB(xValues.begin(), xValues.end(), place + range) - xValues.begin() - 1;
            rusq.updateRange(lo, hi, 1);
        }
    }
    cout << res << endl;
    return 0;
}


#include <bits/stdc++.h>

#define SQ(a) (a)*(a)

#define F0R(i, a) for(int i = 0; i < (a); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define R0F(i, a) for(int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for(int i = (b) - 1; i >= (a); i--)

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()
#define MAXN 100000
#define MAXF 10000

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<ld> point;

struct RUSQ {

    int sz;
    ll *tree;

    RUSQ(int sz) {
        this->sz = sz;
        tree = new ll[sz + 1];
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }

    void update(int idx, ll v) {
        for(idx++; idx <= sz; idx += (idx & -idx)) tree[idx] += v;
    }

    void updateRange(int lo, int hi, int v) {
        update(lo, v);
        update(hi + 1, -v);
    }

    ll query(int idx) {
        ll total = 0;
        for(idx++; idx > 0; idx -= (idx & -idx)) total += tree[idx];
        return total;
    }

    void reset() {
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }
};

int n, k, x[MAXN], r[MAXN];
vi withFreq[MAXF];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> k;
    vi xValues;
    F0R(i, n) {
        int f;
        cin >> x[i] >> r[i] >> f;
        withFreq[--f].PB(i);
        xValues.PB(x[i]);
    }
    sort(xValues.begin(), xValues.end());
    int res = 0;
    RUSQ rusq(MAXN);
    F0R(freq, MAXF) {
        vector<tuple<int, int, int>> toProcess;
        FOR(i, max(0, freq - k), freq) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        for(const int i : withFreq[freq]) toProcess.PB(MT(r[i], x[i], 1));
        FOR(i, freq + 1, min(MAXF, freq + k + 1)) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        sort(toProcess.begin(), toProcess.end());
        rusq.reset();
        for(const tuple<int, int, int> t : toProcess) {
            int range = get<0>(t);
            int place = get<1>(t);
            int task = get<2>(t);
            if(task == 1) res += rusq.query(LB(xValues.begin(), xValues.end(), place) - xValues.begin());
            int lo = LB(xValues.begin(), xValues.end(), place - range) - xValues.begin();
            int hi = UB(xValues.begin(), xValues.end(), place + range) - xValues.begin() - 1;
            rusq.updateRange(lo, hi, 1);
        }
    }
    cout << res << endl;
    return 0;
}


#include <bits/stdc++.h>

#define SQ(a) (a)*(a)

#define F0R(i, a) for(int i = 0; i < (a); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define R0F(i, a) for(int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for(int i = (b) - 1; i >= (a); i--)

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()
#define MAXN 100000
#define MAXF 10000

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<ld> point;

struct RUSQ {

    int sz;
    ll *tree;

    RUSQ(int sz) {
        this->sz = sz;
        tree = new ll[sz + 1];
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }

    void update(int idx, ll v) {
        for(idx++; idx <= sz; idx += (idx & -idx)) tree[idx] += v;
    }

    void updateRange(int lo, int hi, int v) {
        update(lo, v);
        update(hi + 1, -v);
    }

    ll query(int idx) {
        ll total = 0;
        for(idx++; idx > 0; idx -= (idx & -idx)) total += tree[idx];
        return total;
    }

    void reset() {
        tree = new ll[sz + 1];
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }
};

int n, k, x[MAXN], r[MAXN];
vi withFreq[MAXF];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> k;
    vi xValues;
    F0R(i, n) {
        int f;
        cin >> x[i] >> r[i] >> f;
        withFreq[--f].PB(i);
        xValues.PB(x[i]);
    }
    sort(xValues.begin(), xValues.end());
    int res = 0;
    F0R(freq, MAXF) {
        vector<tuple<int, int, int>> toProcess;
        FOR(i, max(0, freq - k), freq) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        for(const int i : withFreq[freq]) toProcess.PB(MT(r[i], x[i], 1));
        FOR(i, freq + 1, min(MAXF, freq + k + 1)) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        sort(toProcess.begin(), toProcess.end());
        RUSQ rusq(MAXN);
        for(const tuple<int, int, int> t : toProcess) {
            int range = get<0>(t);
            int place = get<1>(t);
            int task = get<2>(t);
            if(task == 1) res += rusq.query(LB(xValues.begin(), xValues.end(), place) - xValues.begin());
            int lo = LB(xValues.begin(), xValues.end(), place - range) - xValues.begin();
            int hi = UB(xValues.begin(), xValues.end(), place + range) - xValues.begin() - 1;
            rusq.updateRange(lo, hi, 1);
        }
        rusq = null;
    }
    cout << res << endl;
    return 0;
}


#include <bits/stdc++.h>

#define SQ(a) (a)*(a)

#define F0R(i, a) for(int i = 0; i < (a); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define R0F(i, a) for(int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for(int i = (b) - 1; i >= (a); i--)

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()
#define MAXN 100000
#define MAXF 10000

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<ld> point;

struct RUSQ {

    int sz;
    ll *tree;

    RUSQ(int sz) {
        this->sz = sz;
        tree = new ll[sz + 1];
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }

    void update(int idx, ll v) {
        for(idx++; idx <= sz; idx += (idx & -idx)) tree[idx] += v;
    }

    void updateRange(int lo, int hi, int v) {
        update(lo, v);
        update(hi + 1, -v);
    }

    ll query(int idx) {
        ll total = 0;
        for(idx++; idx > 0; idx -= (idx & -idx)) total += tree[idx];
        return total;
    }

    void reset() {
        tree = new ll[sz + 1];
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }
};

int n, k, x[MAXN], r[MAXN];
vi withFreq[MAXF];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> k;
    vi xValues;
    F0R(i, n) {
        int f;
        cin >> x[i] >> r[i] >> f;
        withFreq[--f].PB(i);
        xValues.PB(x[i]);
    }
    sort(xValues.begin(), xValues.end());
    int res = 0;
    F0R(freq, MAXF) {
        vector<tuple<int, int, int>> toProcess;
        FOR(i, max(0, freq - k), freq) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        for(const int i : withFreq[freq]) toProcess.PB(MT(r[i], x[i], 1));
        FOR(i, freq + 1, min(MAXF, freq + k + 1)) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        sort(toProcess.begin(), toProcess.end());
        RUSQ rusq(MAXN);
        for(const tuple<int, int, int> t : toProcess) {
            int range = get<0>(t);
            int place = get<1>(t);
            int task = get<2>(t);
            if(task == 1) res += rusq.query(LB(xValues.begin(), xValues.end(), place) - xValues.begin());
            int lo = LB(xValues.begin(), xValues.end(), place - range) - xValues.begin();
            int hi = UB(xValues.begin(), xValues.end(), place + range) - xValues.begin() - 1;
            rusq.updateRange(lo, hi, 1);
        }
    }
    cout << res << endl;
    return 0;
}


#include <bits/stdc++.h>

#define SQ(a) (a)*(a)

#define F0R(i, a) for(int i = 0; i < (a); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define R0F(i, a) for(int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for(int i = (b) - 1; i >= (a); i--)

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()
#define MAXN 100000
#define MAXF 10000

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<ld> point;

struct RUSQ {

    int sz;
    ll *tree;

    RUSQ(int sz) {
        this->sz = sz;
        tree = new ll[sz + 1];
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }

    void update(int idx, ll v) {
        for(idx++; idx <= sz; idx += (idx & -idx)) tree[idx] += v;
    }

    void updateRange(int lo, int hi, int v) {
        update(lo, v);
        update(hi + 1, -v);
    }

    ll query(int idx) {
        ll total = 0;
        for(idx++; idx > 0; idx -= (idx & -idx)) total += tree[idx];
        return total;
    }

    void reset() {
        tree = new ll[sz + 1];
        memset(tree, 0, (sz + 1) * sizeof(ll));
    }
};

int n, k, x[MAXN], r[MAXN];
vi withFreq[MAXF];
RUSQ rusq(MAXN);

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> k;
    vi xValues;
    F0R(i, n) {
        int f;
        cin >> x[i] >> r[i] >> f;
        withFreq[--f].PB(i);
        xValues.PB(x[i]);
    }
    sort(xValues.begin(), xValues.end());
    int res = 0;
    F0R(freq, MAXF) {
        vector<tuple<int, int, int>> toProcess;
        FOR(i, max(0, freq - k), freq) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        for(const int i : withFreq[freq]) toProcess.PB(MT(r[i], x[i], 1));
        FOR(i, freq + 1, min(MAXF, freq + k + 1)) {
            for(const int j : withFreq[i]) toProcess.PB(MT(r[j], x[j], 0));
        }
        sort(toProcess.begin(), toProcess.end());
        if(toProcess.size() > 0) rusq.reset();
        for(const tuple<int, int, int> t : toProcess) {
            int range = get<0>(t);
            int place = get<1>(t);
            int task = get<2>(t);
            if(task == 1) res += rusq.query(LB(xValues.begin(), xValues.end(), place) - xValues.begin());
            int lo = LB(xValues.begin(), xValues.end(), place - range) - xValues.begin();
            int hi = UB(xValues.begin(), xValues.end(), place + range) - xValues.begin() - 1;
            rusq.updateRange(lo, hi, 1);
        }
    }
    cout << res << endl;
    return 0;
}


#include <iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<set>
#include<map>
#include<array>
using namespace std;
#define mod 1000000007
#define test int t;scanf("%d", &t);while(t--)
#define pb push_back
#define all(x) x.begin(),x.end()
#define mpr make_pair
#define ll long long int
#define ull unsigned long long int
#define db double
#define vi vector<int>
#define vii vector<pair<int,int> >
#define pii pair<int,int>
#define vl vector<ll>
#define vll vector<pair<ll,ll> >
#define pll pair<ll,ll>
#define ub upper_bound
#define lb lower_bound

#define sc(x) scanf("%d",&x)
#define sc2(x,y) scanf("%d%d",&x,&y)
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define sc4(w,x,y,z) scanf("%d%d%d%d",&w,&x,&y,&z)

#define scll(x) scanf("%lld",&x)
#define scll2(x,y) scanf("%lld%lld",&x,&y)
#define scll3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define scll4(w,x,y,z) scanf("%lld%lld%lld%lld",&w,&x,&y,&z)

#define scdb(x) scanf("%lf",&x)
#define scdb2(x,y) scanf("%lf%lf",&x,&y)
#define scdb3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)
#define scdb4(w,x,y,z) scanf("%lf%lf%lf%lf",&w,&x,&y,&z)

#define scs(s) scanf("%s", s)

#define pr(x) printf("%d\n",x)
#define pr2(x,y) printf("%d %d\n",x,y)
#define pr3(x,y,z) printf("%d %d %d\n",x,y,z)
#define pr4(w,x,y,z) printf("%d %d %d %d\n",w,x,y,z)

#define prll(x) printf("%lld\n",x)
#define prll2(x,y) printf("%lld %lld\n",x,y)
#define prll3(x,y,z) printf("%lld %lld %lld\n",x,y,z)
#define prll4(w,x,y,z) printf("%lld %lld %lld %lld\n",w,x,y,z)

#define prdb(x) printf("%lf\n",x)
#define prdb2(x,y) printf("%lf %lf\n",x,y)
#define prdb3(x,y,z) printf("%lf %lf %lf\n",x,y,z)
#define prdb4(w,x,y,z) printf("%lf %lf %lf %lf\n",w,x,y,z)

#define prs(s) printf("%s\n", s)
#define prn() printf("\n")
#define prvec(v) for(int i=0;i<v.size();i++) cout << v[i] << " "
#define prpair(p) cout<<p.first<<" "<<p.second<<endl
#define F first
#define S second

#define maxf 10005
#define maxr 100005
vector<pair<int,pair<int,int> > > f[maxf];
int k, len;
int tree[maxr*20];
int pos, value;
void update(int node, int a, int b) {
  if(a > b)return;
  if(a == b) { // Leaf node
    tree[node] = value;
    return;
  }
  int tem = (node<<1);
  if(pos<=(a+b)/2)update(tem, a, (a+b)/2); // Updating left child
  else update(1+tem, 1+(a+b)/2, b); // Updating right child
  tree[node] = tree[tem]+tree[tem+1]; // Updating root with max value
}
int query(int node, int a, int b, int i, int j) {
  if(a > b || a > j || b < i) return 0; // Out of range
  if(a >= i && b <= j) // Current segment is totally within range [i, j]
    return tree[node];
  return query(node*2,a,(a+b)/2,i,j)+query(1+node*2, 1+(a+b)/2, b, i, j);

}
ll solve(int ind)
{
  ll ret = 0;
  int sz = 0;
  for(int i=max(0,ind-k);i<=min(maxf-1,ind+k);i++)
    for(int j=0;j<f[i].size();j++)sz++;
  vector<pair<pair<int,pair<int,int> >,int> > vec(sz);
  sz = 0;
  for(int i=max(0,ind-k);i<=min(maxf-1,ind+k);i++)
    for(int j=0;j<f[i].size();j++)vec[sz++] = mpr(f[i][j],i);
  sort(all(vec));
  //if(ind==1)for(int i=0;i<vec.size();i++)
    //cout<<vec[i].F<<" "<<vec[i].S.F<<" "<<vec[i].S.S<<" "<<fre[i]<<endl;
  set<pair<int,int> > s;
  for(int i=0;i<vec.size();i++)
  {
    int x = vec[i].F.F, back = vec[i].F.S.F, forw = vec[i].F.S.S, fre = vec[i].S;
    while(!s.empty())
    {
      if(s.begin()->F >= x)break;
      pos = s.begin()->S;
      value = 0;
      update(1,0,len-1);
      s.erase(s.begin());
    }
    if(fre==ind)ret+=query(1,0,len-1,back,x);
    pos = x;
    value = 1;
    update(1,0,len-1);
    s.insert(mpr(forw,x));
  }
  for(set<pair<int,int> >::iterator it=s.begin();it!=s.end();it++)
  {
    pos = it->S;
    value = 0;
    update(1,0,len-1);
  }
  s.clear();
  //if(ret>0)cout<<ind<<" "<<ret<<endl;
  return ret;
}
int main()
{
  int n;
  cin>>n>>k;
  set<int> s;
  for(int i=0;i<n;i++)
  {
    int x, r, ind;
    sc3(x,r,ind);
    //cin>>x>>r>>ind;
    s.insert(x);
    s.insert(x-r);
    s.insert(x+r);
    f[ind].pb(mpr(x,mpr(x-r,x+r)));
  }
  map<int,int> mp;
  for(set<int>::iterator it=s.begin();it!=s.end();it++)
    mp[*it] = len++;
  for(int i=0;i<maxf;i++)
    for(int j=0;j<f[i].size();j++)
    {
      f[i][j].F = mp[f[i][j].F];
      f[i][j].S.F = mp[f[i][j].S.F];
      f[i][j].S.S = mp[f[i][j].S.S];
    }
  /*for(int i=0;i<maxf;i++)
  {
    for(int j=0;j<f[i].size();j++)cout<<f[i][j].F<<" "<<f[i][j].S.F<<" "<<f[i][j].S.S<<" "<<i<<endl;
  }*/
  ll ans = 0;
  for(int i=0;i<maxf;i++)ans+=solve(i);
  cout<<ans<<endl;
  return 0;
}


#include <iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<set>
#include<map>
#include<array>
using namespace std;
#define mod 1000000007
#define test int t;scanf("%d", &t);while(t--)
#define pb push_back
#define all(x) x.begin(),x.end()
#define mpr make_pair
#define ll long long int
#define ull unsigned long long int
#define db double
#define vi vector<int>
#define vii vector<pair<int,int> >
#define pii pair<int,int>
#define vl vector<ll>
#define vll vector<pair<ll,ll> >
#define pll pair<ll,ll>
#define ub upper_bound
#define lb lower_bound

#define sc(x) scanf("%d",&x)
#define sc2(x,y) scanf("%d%d",&x,&y)
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define sc4(w,x,y,z) scanf("%d%d%d%d",&w,&x,&y,&z)

#define scll(x) scanf("%lld",&x)
#define scll2(x,y) scanf("%lld%lld",&x,&y)
#define scll3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define scll4(w,x,y,z) scanf("%lld%lld%lld%lld",&w,&x,&y,&z)

#define scdb(x) scanf("%lf",&x)
#define scdb2(x,y) scanf("%lf%lf",&x,&y)
#define scdb3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)
#define scdb4(w,x,y,z) scanf("%lf%lf%lf%lf",&w,&x,&y,&z)

#define scs(s) scanf("%s", s)

#define pr(x) printf("%d\n",x)
#define pr2(x,y) printf("%d %d\n",x,y)
#define pr3(x,y,z) printf("%d %d %d\n",x,y,z)
#define pr4(w,x,y,z) printf("%d %d %d %d\n",w,x,y,z)

#define prll(x) printf("%lld\n",x)
#define prll2(x,y) printf("%lld %lld\n",x,y)
#define prll3(x,y,z) printf("%lld %lld %lld\n",x,y,z)
#define prll4(w,x,y,z) printf("%lld %lld %lld %lld\n",w,x,y,z)

#define prdb(x) printf("%lf\n",x)
#define prdb2(x,y) printf("%lf %lf\n",x,y)
#define prdb3(x,y,z) printf("%lf %lf %lf\n",x,y,z)
#define prdb4(w,x,y,z) printf("%lf %lf %lf %lf\n",w,x,y,z)

#define prs(s) printf("%s\n", s)
#define prn() printf("\n")
#define prvec(v) for(int i=0;i<v.size();i++) cout << v[i] << " "
#define prpair(p) cout<<p.first<<" "<<p.second<<endl
#define F first
#define S second

#define maxf 10005
#define maxr 100005
vector<pair<int,pair<int,int> > > f[maxf];
int k, len;
int tree[maxr*10];
int pos, value;
void update(int node, int a, int b) {
  if(a > b)return;
  if(a == b) { // Leaf node
    tree[node] = value;
    return;
  }
  if(pos<=(a+b)/2)update(node*2, a, (a+b)/2); // Updating left child
  else update(1+node*2, 1+(a+b)/2, b); // Updating right child
  tree[node] = tree[node*2]+tree[node*2+1]; // Updating root with max value
}
int query(int node, int a, int b, int i, int j) {
  if(a > b || a > j || b < i) return 0; // Out of range
  if(a >= i && b <= j) // Current segment is totally within range [i, j]
    return tree[node];
  return query(node*2,a,(a+b)/2,i,j)+query(1+node*2, 1+(a+b)/2, b, i, j);

}
ll solve(int ind)
{
  ll ret = 0;
  int sz = 0;
  for(int i=max(0,ind-k);i<=min(maxf-1,ind+k);i++)
    for(int j=0;j<f[i].size();j++)sz++;
  vector<pair<pair<int,pair<int,int> >,int> > vec(sz);
  sz = 0;
  for(int i=max(0,ind-k);i<=min(maxf-1,ind+k);i++)
    for(int j=0;j<f[i].size();j++)vec[sz++] = mpr(f[i][j],i);
  sort(all(vec));
  //if(ind==1)for(int i=0;i<vec.size();i++)
    //cout<<vec[i].F<<" "<<vec[i].S.F<<" "<<vec[i].S.S<<" "<<fre[i]<<endl;
  set<pair<int,int> > s;
  for(int i=0;i<vec.size();i++)
  {
    int x = vec[i].F.F, back = vec[i].F.S.F, forw = vec[i].F.S.S, fre = vec[i].S;
    while(!s.empty())
    {
      if(s.begin()->F >= x)break;
      pos = s.begin()->S;
      value = 0;
      update(1,0,len-1);
      s.erase(s.begin());
    }
    if(fre==ind)ret+=query(1,0,len-1,back,x);
    pos = x;
    value = 1;
    update(1,0,len-1);
    s.insert(mpr(forw,x));
  }
  while(!s.empty())
  {
    pos = s.begin()->S;
    value = 0;
    update(1,0,len-1);
    s.erase(s.begin());
  }
  //if(ret>0)cout<<ind<<" "<<ret<<endl;
  return ret;
}
int main()
{
  int n;
  cin>>n>>k;
  set<int> s;
  for(int i=0;i<n;i++)
  {
    int x, r, ind;
    sc3(x,r,ind);
    //cin>>x>>r>>ind;
    s.insert(x);
    s.insert(x-r);
    s.insert(x+r);
    f[ind].pb(mpr(x,mpr(x-r,x+r)));
  }
  map<int,int> mp;
  for(set<int>::iterator it=s.begin();it!=s.end();it++)
    mp[*it] = len++;
  for(int i=0;i<maxf;i++)
    for(int j=0;j<f[i].size();j++)
    {
      f[i][j].F = mp[f[i][j].F];
      f[i][j].S.F = mp[f[i][j].S.F];
      f[i][j].S.S = mp[f[i][j].S.S];
    }
  /*for(int i=0;i<maxf;i++)
  {
    for(int j=0;j<f[i].size();j++)cout<<f[i][j].F<<" "<<f[i][j].S.F<<" "<<f[i][j].S.S<<" "<<i<<endl;
  }*/
  ll ans = 0;
  for(int i=0;i<maxf;i++)ans+=solve(i);
  cout<<ans<<endl;
  return 0;
}


#include <iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<set>
#include<map>
#include<array>
using namespace std;
#define mod 1000000007
#define test int t;scanf("%d", &t);while(t--)
#define pb push_back
#define all(x) x.begin(),x.end()
#define mpr make_pair
#define ll long long int
#define ull unsigned long long int
#define db double
#define vi vector<int>
#define vii vector<pair<int,int> >
#define pii pair<int,int>
#define vl vector<ll>
#define vll vector<pair<ll,ll> >
#define pll pair<ll,ll>
#define ub upper_bound
#define lb lower_bound

#define sc(x) scanf("%d",&x)
#define sc2(x,y) scanf("%d%d",&x,&y)
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define sc4(w,x,y,z) scanf("%d%d%d%d",&w,&x,&y,&z)

#define scll(x) scanf("%lld",&x)
#define scll2(x,y) scanf("%lld%lld",&x,&y)
#define scll3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define scll4(w,x,y,z) scanf("%lld%lld%lld%lld",&w,&x,&y,&z)

#define scdb(x) scanf("%lf",&x)
#define scdb2(x,y) scanf("%lf%lf",&x,&y)
#define scdb3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)
#define scdb4(w,x,y,z) scanf("%lf%lf%lf%lf",&w,&x,&y,&z)

#define scs(s) scanf("%s", s)

#define pr(x) printf("%d\n",x)
#define pr2(x,y) printf("%d %d\n",x,y)
#define pr3(x,y,z) printf("%d %d %d\n",x,y,z)
#define pr4(w,x,y,z) printf("%d %d %d %d\n",w,x,y,z)

#define prll(x) printf("%lld\n",x)
#define prll2(x,y) printf("%lld %lld\n",x,y)
#define prll3(x,y,z) printf("%lld %lld %lld\n",x,y,z)
#define prll4(w,x,y,z) printf("%lld %lld %lld %lld\n",w,x,y,z)

#define prdb(x) printf("%lf\n",x)
#define prdb2(x,y) printf("%lf %lf\n",x,y)
#define prdb3(x,y,z) printf("%lf %lf %lf\n",x,y,z)
#define prdb4(w,x,y,z) printf("%lf %lf %lf %lf\n",w,x,y,z)

#define prs(s) printf("%s\n", s)
#define prn() printf("\n")
#define prvec(v) for(int i=0;i<v.size();i++) cout << v[i] << " "
#define prpair(p) cout<<p.first<<" "<<p.second<<endl
#define F first
#define S second

#define maxf 10005
#define maxr 100005
vector<pair<int,pair<int,int> > > f[maxf];
int k, len;
int tree[maxr*10];
int pos, value;
void update(int node, int a, int b) {
  if(a > b || a > pos || b < pos)return;
  if(a == b) { // Leaf node
    tree[node] = value;
    return;
  }
  if(pos<=(a+b)/2)update(node*2, a, (a+b)/2); // Updating left child
  else update(1+node*2, 1+(a+b)/2, b); // Updating right child
  tree[node] = tree[node*2]+tree[node*2+1]; // Updating root with max value
}
int query(int node, int a, int b, int i, int j) {
  if(a > b || a > j || b < i) return 0; // Out of range
  if(a >= i && b <= j) // Current segment is totally within range [i, j]
    return tree[node];
  return query(node*2,a,(a+b)/2,i,j)+query(1+node*2, 1+(a+b)/2, b, i, j);

}
ll solve(int ind)
{
  ll ret = 0;
  int sz = 0;
  for(int i=max(0,ind-k);i<=min(maxf-1,ind+k);i++)
    for(int j=0;j<f[i].size();j++)sz++;
  vector<pair<pair<int,pair<int,int> >,int> > vec(sz);
  sz = 0;
  for(int i=max(0,ind-k);i<=min(maxf-1,ind+k);i++)
    for(int j=0;j<f[i].size();j++)vec[sz++] = mpr(f[i][j],i);
  sort(all(vec));
  //if(ind==1)for(int i=0;i<vec.size();i++)
    //cout<<vec[i].F<<" "<<vec[i].S.F<<" "<<vec[i].S.S<<" "<<fre[i]<<endl;
  set<pair<int,int> > s;
  for(int i=0;i<vec.size();i++)
  {
    int x = vec[i].F.F, back = vec[i].F.S.F, forw = vec[i].F.S.S, fre = vec[i].S;
    while(!s.empty())
    {
      if(s.begin()->F >= x)break;
      pos = s.begin()->S;
      value = 0;
      update(1,0,len-1);
      s.erase(s.begin());
    }
    if(fre==ind)ret+=query(1,0,len-1,back,x);
    pos = x;
    value = 1;
    update(1,0,len-1);
    s.insert(mpr(forw,x));
  }
  while(!s.empty())
  {
    pos = s.begin()->S;
    value = 0;
    update(1,0,len-1);
    s.erase(s.begin());
  }
  //if(ret>0)cout<<ind<<" "<<ret<<endl;
  return ret;
}
int main()
{
  int n;
  cin>>n>>k;
  set<int> s;
  for(int i=0;i<n;i++)
  {
    int x, r, ind;
    sc3(x,r,ind);
    //cin>>x>>r>>ind;
    s.insert(x);
    s.insert(x-r);
    s.insert(x+r);
    f[ind].pb(mpr(x,mpr(x-r,x+r)));
  }
  map<int,int> mp;
  for(set<int>::iterator it=s.begin();it!=s.end();it++)
    mp[*it] = len++;
  for(int i=0;i<maxf;i++)
    for(int j=0;j<f[i].size();j++)
    {
      f[i][j].F = mp[f[i][j].F];
      f[i][j].S.F = mp[f[i][j].S.F];
      f[i][j].S.S = mp[f[i][j].S.S];
    }
  /*for(int i=0;i<maxf;i++)
  {
    for(int j=0;j<f[i].size();j++)cout<<f[i][j].F<<" "<<f[i][j].S.F<<" "<<f[i][j].S.S<<" "<<i<<endl;
  }*/
  ll ans = 0;
  for(int i=0;i<maxf;i++)ans+=solve(i);
  cout<<ans<<endl;
  return 0;
}


#include <iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<set>
#include<map>
#include<array>
using namespace std;
#define mod 1000000007
#define test int t;scanf("%d", &t);while(t--)
#define pb push_back
#define all(x) x.begin(),x.end()
#define mpr make_pair
#define ll long long int
#define ull unsigned long long int
#define db double
#define vi vector<int>
#define vii vector<pair<int,int> >
#define pii pair<int,int>
#define vl vector<ll>
#define vll vector<pair<ll,ll> >
#define pll pair<ll,ll>
#define ub upper_bound
#define lb lower_bound

#define sc(x) scanf("%d",&x)
#define sc2(x,y) scanf("%d%d",&x,&y)
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define sc4(w,x,y,z) scanf("%d%d%d%d",&w,&x,&y,&z)

#define scll(x) scanf("%lld",&x)
#define scll2(x,y) scanf("%lld%lld",&x,&y)
#define scll3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define scll4(w,x,y,z) scanf("%lld%lld%lld%lld",&w,&x,&y,&z)

#define scdb(x) scanf("%lf",&x)
#define scdb2(x,y) scanf("%lf%lf",&x,&y)
#define scdb3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)
#define scdb4(w,x,y,z) scanf("%lf%lf%lf%lf",&w,&x,&y,&z)

#define scs(s) scanf("%s", s)

#define pr(x) printf("%d\n",x)
#define pr2(x,y) printf("%d %d\n",x,y)
#define pr3(x,y,z) printf("%d %d %d\n",x,y,z)
#define pr4(w,x,y,z) printf("%d %d %d %d\n",w,x,y,z)

#define prll(x) printf("%lld\n",x)
#define prll2(x,y) printf("%lld %lld\n",x,y)
#define prll3(x,y,z) printf("%lld %lld %lld\n",x,y,z)
#define prll4(w,x,y,z) printf("%lld %lld %lld %lld\n",w,x,y,z)

#define prdb(x) printf("%lf\n",x)
#define prdb2(x,y) printf("%lf %lf\n",x,y)
#define prdb3(x,y,z) printf("%lf %lf %lf\n",x,y,z)
#define prdb4(w,x,y,z) printf("%lf %lf %lf %lf\n",w,x,y,z)

#define prs(s) printf("%s\n", s)
#define prn() printf("\n")
#define prvec(v) for(int i=0;i<v.size();i++) cout << v[i] << " "
#define prpair(p) cout<<p.first<<" "<<p.second<<endl
#define F first
#define S second

#define maxf 10005
#define maxr 100005
vector<pair<int,pair<int,int> > > f[maxf];
int k, len;
int tree[maxr*10];
void update(int node, int a, int b, int i, int j, int value) {

  if(a > b || a > j || b < i) // Current segment is not within range [i, j]
    return;

  if(a == b) { // Leaf node
    tree[node] = value;
    return;
  }

  update(node*2, a, (a+b)/2, i, j, value); // Updating left child
  update(1+node*2, 1+(a+b)/2, b, i, j, value); // Updating right child

  tree[node] = tree[node*2]+tree[node*2+1]; // Updating root with max value
}
int query(int node, int a, int b, int i, int j) {

  if(a > b || a > j || b < i) return 0; // Out of range

  if(a >= i && b <= j) // Current segment is totally within range [i, j]
    return tree[node];

  int q1 = query(node*2, a, (a+b)/2, i, j); // Query left child
  int q2 = query(1+node*2, 1+(a+b)/2, b, i, j); // Query right child

  int res = q1+q2; // Return final result

  return res;
}
ll solve(int ind)
{
  ll ret = 0;
  int sz = 0;
  for(int i=max(0,ind-k);i<=min(maxf-1,ind+k);i++)
    for(int j=0;j<f[i].size();j++)sz++;
  vector<pair<pair<int,pair<int,int> >,int> > vec(sz);
  sz = 0;
  //dfjd
  for(int i=max(0,ind-k);i<=min(maxf-1,ind+k);i++)
    for(int j=0;j<f[i].size();j++)vec[sz++] = mpr(f[i][j],i);
  sort(all(vec));
  //if(ind==1)for(int i=0;i<vec.size();i++)
    //cout<<vec[i].F<<" "<<vec[i].S.F<<" "<<vec[i].S.S<<" "<<fre[i]<<endl;
  set<pair<int,int> > s;
  for(int i=0;i<vec.size();i++)
  {
    int x = vec[i].F.F, back = vec[i].F.S.F, forw = vec[i].F.S.S, fre = vec[i].S;
    while(!s.empty())
    {
      if(s.begin()->F >= x)break;
      update(1,0,len-1,s.begin()->S,s.begin()->S,0);
      s.erase(s.begin());
    }
    if(fre==ind)ret+=query(1,0,len-1,back,x);
    update(1,0,len-1,x,x,1);
    s.insert(mpr(forw,x));
  }
  while(!s.empty())
  {
    update(1,0,len-1,s.begin()->S,s.begin()->S,0);
    s.erase(s.begin());
  }
  /*for(int i=0;i<vec.size();i++)
  {
    int x = vec[i].F, back = vec[i].S.F, forw = vec[i].S.S;
    while(!s.empty())
    {
      if(s.begin()->F >= x)break;
      update(1,0,len-1,s.begin()->S,s.begin()->S,0);
      s.erase(s.begin());
    }
    if(fre[i]!=ind)ret+=query(1,0,len-1,back,x);
    else
    {
      update(1,0,len-1,x,x,1);
      s.insert(mpr(forw,x));
    }
  }
  while(!s.empty())
  {
    update(1,0,len-1,s.begin()->S,s.begin()->S,0);
    s.erase(s.begin());
  }*/
  //if(ret>0)cout<<ind<<" "<<ret<<endl;
  return ret;
}
int main()
{
  int n;
  cin>>n>>k;
  set<int> s;
  for(int i=0;i<n;i++)
  {
    int x, r, ind;
    cin>>x>>r>>ind;
    s.insert(x);
    s.insert(x-r);
    s.insert(x+r);
    f[ind].pb(mpr(x,mpr(x-r,x+r)));
  }
  map<int,int> mp;
  for(set<int>::iterator it=s.begin();it!=s.end();it++)
    mp[*it] = len++;
  for(int i=0;i<maxf;i++)
    for(int j=0;j<f[i].size();j++)
    {
      f[i][j].F = mp[f[i][j].F];
      f[i][j].S.F = mp[f[i][j].S.F];
      f[i][j].S.S = mp[f[i][j].S.S];
    }
  /*for(int i=0;i<maxf;i++)
  {
    for(int j=0;j<f[i].size();j++)cout<<f[i][j].F<<" "<<f[i][j].S.F<<" "<<f[i][j].S.S<<" "<<i<<endl;
  }*/
  ll ans = 0;
  for(int i=0;i<maxf;i++)ans+=solve(i);
  cout<<ans<<endl;
  return 0;
}