#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;

class SegmentTree
{
private:
	vector<int> tree;
	const int INF = 99999999;
	int size;
	int init(int i)
	{
		if (i * 2 + 1 < tree.size()) tree[i] = init(i * 2 + 1);
		if (i * 2 + 2 < tree.size()) tree[i] = min(init(i * 2 + 2), tree[i]);
		return tree[i];
	}
	int get(int a, int b, int k, int l, int r)
	{
		if (r <= a || b <= l) return INF;
		if (a <= l && r <= b) return tree[k];
		int vl = get(a, b, k * 2 + 1, l, (l + r) / 2);
		int vr = get(a, b, k * 2 + 2, (l + r) / 2, r);
		return min(vl, vr);
	}
public:
	SegmentTree(vector<int>& v)
	{
		size = 1;
		while (size < v.size()) size *= 2;
		tree.resize(size * 2 - 1);
		fill(tree.begin(), tree.end(), INF);
		for (int i = 0; i < v.size(); i++) tree[size - 1 + i] = v[i];
		init(0);
	}
	int get(int begin, int end)
	{
		return get(begin, end, 0, 0, size);
	}
};
class GreaterSegmentTree
{
private:
	vector<int> tree;
	const int INF = -99999999;
	int size;
	int init(int i)
	{
		if (i * 2 + 1 < tree.size()) tree[i] = init(i * 2 + 1);
		if (i * 2 + 2 < tree.size()) tree[i] = max(init(i * 2 + 2), tree[i]);
		return tree[i];
	}
	int get(int a, int b, int k, int l, int r)
	{
		if (r <= a || b <= l) return INF;
		if (a <= l && r <= b) return tree[k];
		int vl = get(a, b, k * 2 + 1, l, (l + r) / 2);
		int vr = get(a, b, k * 2 + 2, (l + r) / 2, r);
		return max(vl, vr);
	}
public:
	GreaterSegmentTree(vector<int>& v)
	{
		size = 1;
		while (size < v.size()) size *= 2;
		tree.resize(size * 2 - 1);
		fill(tree.begin(), tree.end(), INF);
		for (int i = 0; i < v.size(); i++) tree[size - 1 + i] = v[i];
		init(0);
	}
	int get(int begin, int end)
	{
		return get(begin, end, 0, 0, size);
	}
};


class Star
{
public:
	long long int x, y;
	int b;
	int boundary;
};
bool operator > (Star s1, Star s2)
{
	return s1.b > s2.b;
}
bool operator < (Star s1, Star s2)
{
	return s1.b < s2.b;
}

int n, d;
Star star[200000];
long long int ans = 0;

void calcBoundary()
{
	int boundary = n - 1;
	star[n - 1].boundary = boundary;
	for (int i = n - 2; i >= 0; i--)
	{
		if (star[i + 1].b - star[i].b > d) boundary = i;
		star[i].boundary = boundary;
	}

	for (int i = 0; i < n; i++)
	{
		Star s;
		s.b = star[i].b + d;
		boundary = upper_bound(star + i, star + n, s) - star - 1;
		star[i].boundary = min(star[i].boundary, boundary);
	}
}

void solve()
{
	vector<int> vx;
	vector<int> vy;
	for (int i = 0; i < n; i++)
	{
		vx.push_back(star[i].x);
		vy.push_back(star[i].y);
	}
	SegmentTree segX(vx), segY(vy);
	GreaterSegmentTree gsegX(vx), gsegY(vy);

	int boundary = star[n-1].boundary;
	
	for (int i = n - 2; i >= 0; i--)
	{
		if (boundary != star[i].boundary)
		{
			long long int a = ((long long int)gsegX.get(i + 1, boundary + 1) - (long long int)segX.get(i + 1, boundary + 1)) * ((long long int)gsegY.get(i + 1, boundary + 1) - (long long int)segY.get(i + 1, boundary + 1));
			ans = max(a, ans);
			boundary = star[i].boundary;
		}
	}
	long long int a = ((long long int)gsegX.get(0, boundary + 1) - (long long int)segX.get(0, boundary + 1)) * ((long long int)gsegY.get(0, boundary + 1) - (long long int)segY.get(0, boundary + 1));
	ans = max(a, ans);
}

int main()
{
	cin >> n >> d;
	for (int i = 0; i < n; i++) cin >> star[i].x >> star[i].y >> star[i].b;

	sort(star, star + n);
	calcBoundary();
	solve();

	cout << ans << endl;

	return 0;
}

Measured memory_bytes: 17664