#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

typedef long long ll;
const ll LLINF = LLONG_MAX;

struct Star {
  int x,y;
  ll b;
  bool operator < ( const Star &star ) const { return b < star.b; }
};

class RMXQ{
private:
  int limit,N;
  vector<ll> dat;
public:
  void init(int n_){
    N = n_;
    limit = 1;
    while(limit<n_)limit*=2;
    dat.clear();
    dat.resize(2*limit,-LLINF);
  }
  
  ll _build(int cur,int L,int R,const vector<ll> &buf){
    if( !( 0 <= cur && cur < 2*limit ) ) return -LLINF;
    if( L == R-1 ) {
      if( L >= N ) return -LLINF;
      dat[cur] = buf[L];
    } else {
      ll vl = _build(cur*2+1,L,(L+R)/2,buf);
      ll vr = _build(cur*2+2,(L+R)/2,R,buf);
      dat[cur] = max(vl,vr);
    }
    return dat[cur];
  }

  void build(const vector<ll> &buf){ _build(0,0,limit,buf); };

  ll _query(int a,int b,int k,int l,int r){
    if(r<=a || b<=l)return -LLINF;
    else if(a<=l && r<=b)return dat[k];
    ll vl = _query(a,b,k*2+1,l,(l+r)/2);
    ll vr = _query(a,b,k*2+2,(l+r)/2,r);
    return max(vl,vr);
  }

  ll query(int a,int b){ return _query(a,b,0,0,limit); }
};

class RMNQ{
private:
  int limit,N;
  vector<ll> dat;
public:
  void init(int n_){
    N = n_;
    limit = 1;
    while(limit<n_)limit*=2;
    dat.clear();
    dat.resize(2*limit,LLINF);
  }
  
  ll _build(int cur,int L,int R,const vector<ll> &buf){
    if( !( 0 <= cur && cur < 2*limit ) ) return LLINF;
    if( L == R-1 ) {
      if( L >= N ) return LLINF;
      dat[cur] = buf[L];
    } else {
      ll vl = _build(cur*2+1,L,(L+R)/2,buf);
      ll vr = _build(cur*2+2,(L+R)/2,R,buf);
      dat[cur] = min(vl,vr);
    }
    return dat[cur];
  }

  void build(const vector<ll> &buf){ _build(0,0,limit,buf); };

  ll _query(int a,int b,int k,int l,int r){
    if(r<=a || b<=l)return LLINF;
    else if(a<=l && r<=b)return dat[k];
    ll vl = _query(a,b,k*2+1,l,(l+r)/2);
    ll vr = _query(a,b,k*2+2,(l+r)/2,r);
    return min(vl,vr);
  }

  ll query(int a,int b){ return _query(a,b,0,0,limit); }
};

int n;
ll d;

RMXQ rmxq_x,rmxq_y;
RMNQ rmnq_x,rmnq_y;

ll getArea(int L,int R){
  ll maxi_x = rmxq_x.query(L,R);
  ll mini_x = rmnq_x.query(L,R);
  ll maxi_y = rmxq_y.query(L,R);
  ll mini_y = rmnq_y.query(L,R);
  return ( maxi_x - mini_x ) * ( maxi_y - mini_y );
}

void compute(vector<Star> &vec){
  vector<ll> arr,xs,ys;
  rep(i,n) {
    arr.push_back(vec[i].b);
    xs.push_back(vec[i].x);
    ys.push_back(vec[i].y);
  }


  rmxq_x.init(n);
  rmxq_y.init(n);
  rmnq_x.init(n);
  rmnq_y.init(n);
  rmxq_x.build(xs);
  rmxq_y.build(ys);
  rmnq_x.build(xs);
  rmnq_y.build(ys);
  /*
  rep(i,n) cout << arr[i] << " "; puts("");
  rep(i,n) cout << vec[i].x << " "; puts("");
  rep(i,n) cout << vec[i].y << " "; puts("");
  */
  ll maxi = 0;
  int L = 0, R = 0;

  while( R <= n ){
    while( R < n && arr[R] - arr[L] <= d ) ++R;
    //cout << arr[R-1] - arr[L] << " : " << getArea(L,R) << endl;
    if( arr[R-1] - arr[L] <= d ) maxi = max(maxi,getArea(L,R));
    /*
    while( L < R && arr[R] - arr[L] <= d ) ++L;
    */
    ++L;
    if( L < R && arr[R-1] - arr[L] <= d ) maxi = max(maxi,getArea(L,R));
    if( L == R ) ++R;
  }
  cout << maxi << endl;
}

int main(){
  cin >> n >> d;
  vector<Star> vec(n);
  rep(i,n) cin >> vec[i].x >> vec[i].y >> vec[i].b;
  sort(vec.begin(),vec.end());
  compute(vec);
  return 0;
}

Measured memory_bytes: 25580