#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string.h>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

enum Type{
	Right,
	Left,
	Top,
	Bottom,
};

struct Info{
	bool operator<(const struct Info &arg) const{
			return Brightness < arg.Brightness;
	};
	ll x,y,Brightness;
};

struct RMQ{
	void set(ll arg_most_left,ll arg_most_right,ll arg_most_top,ll arg_most_bottom){
		most_left = arg_most_left;
		most_right = arg_most_right;
		most_top = arg_most_top;
		most_bottom = arg_most_bottom;
	}
	ll most_left,most_right,most_top,most_bottom;
};

#define NUM 2147483647

int N = 1;
Info* info;
RMQ* Tree;


void init(int first_N){
	while(N < first_N)N *= 2;
}

void update(int index, Info new_value){

	index += N-1;

	Tree[index].most_left = min(Tree[index].most_left,new_value.x);
	Tree[index].most_right = max(Tree[index].most_right,new_value.x);
	Tree[index].most_top = min(Tree[index].most_top,new_value.y);
	Tree[index].most_bottom = max(Tree[index].most_bottom,new_value.y);

	index = (index-1)/2;

	while(true){

		Tree[index].most_left = min(Tree[2*index+1].most_left,Tree[2*index+2].most_left);
		Tree[index].most_right = max(Tree[2*index+1].most_right,Tree[2*index+2].most_right);
		Tree[index].most_top = min(Tree[2*index+1].most_top,Tree[2*index+2].most_top);
		Tree[index].most_bottom = max(Tree[2*index+1].most_bottom,Tree[2*index+2].most_bottom);

		if(index == 0)break;
		else{
			index = (index-1)/2;
		}
	}
}


ll find(int search_left,int search_right,int node_id,int node_left,int node_right,Type type){

	if(search_right < node_left || search_left > node_right){
		if(type == Left || type == Top){
			return NUM;
		}else{ //type == Right || type == Bottom
			return -1;
		}
	}

	if(search_left <= node_left && search_right >= node_right){
		if(type == Left){
			return Tree[node_id].most_left;
		}else if(type == Right){
			return Tree[node_id].most_right;
		}else if(type == Top){
			return Tree[node_id].most_top;
		}else{
			return Tree[node_id].most_bottom;
		}
	}

	if(type == Left || type == Top){
		ll left_min = find(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2,type);
		ll right_min = find(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right,type);

		return min(left_min,right_min);
	}else{ //type == Right || type == Bottom
		ll left_max = find(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2,type);
		ll right_max = find(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right,type);

		return max(left_max,right_max);
	}
}


int main(){

	int first_N;
	ll Diff_Max;

	scanf("%d %lld",&first_N,&Diff_Max);

	init(first_N);

	info = (Info*)malloc(sizeof(Info)*(2*N));
	Tree = (RMQ*)malloc(sizeof(RMQ)*(2*N));

	for(int i = 0; i < 2*N-1; i++){
		Tree[i].set(BIG_NUM,-1,BIG_NUM,-1);
	}

	for(int i = 0; i < first_N; i++){
		scanf("%lld %lld %lld",&info[i].x,&info[i].y,&info[i].Brightness);
	}

	sort(info,info+first_N);

	for(int i = 0; i < first_N; i++){
		update(i,info[i]);
	}

	ll ans = 0;
	int left,right,m,pre_right = 0,loc;
	ll calc_left,calc_right,calc_top,calc_bottom;


	for(int start = 0; start < first_N; start++){

		left = pre_right,right = first_N-1;
		m = (left + right)/2;
		loc = -1;
		while(left <= right){
			if(info[m].Brightness-info[start].Brightness <= Diff_Max){
				loc = max(loc,m);
				left = m+1;
			}else{
				right = m-1;
			}
			m = (left+right)/2;
		}
		if(loc == -1)break;

		calc_left = find(start,loc,0,0,N-1,Left);
		calc_right = find(start,loc,0,0,N-1,Right);
		calc_top = find(start,loc,0,0,N-1,Top);
		calc_bottom = find(start,loc,0,0,N-1,Bottom);

		ans = max(ans,(calc_right-calc_left)*(calc_bottom-calc_top));

		pre_right = loc;
	}

	printf("%lld\n",ans);

	return 0;
}

Measured memory_bytes: 23852