#include <bits/stdc++.h>

//{{{ seg.hpp
#ifndef INCLUDE_SEG_HPP
#define INCLUDE_SEG_HPP
#include <functional>
#include <algorithm>
#include <iterator>
namespace orislib {
namespace ds {
constexpr int uprt(int k, int i=1){
  return i < k ? uprt(k, i + i) : i;
}
//{{{ SegT<T, S> update, query
template<typename T, int S>
struct SegT {
  typedef T seg_t;
  const seg_t OUT;
  static const int N = uprt(S);
  seg_t data[N * 2];
  std::function<seg_t(seg_t,seg_t)>ufunc;
  template<typename F>
  SegT(T initial, F f):OUT(initial),ufunc(f){std::fill(std::begin(data), std::end(data), initial);}
  void update(int x, seg_t v){
    for (data[x+=N-1]=v;x;data[x]=ufunc(data[x+x+1],data[x+x+2]))x=x-1>>1;
  }
  void add(int x,seg_t a){ update(x,data[x+N-1]+a); }
  seg_t query(int a=0,int b=N,int x=0,int l=0,int r=N){
    if (r<=a||b<=l) return OUT;
    if (a<=l&&r<=b) return data[x];
    return ufunc(query(a,b,x+x+1,l,l+r>>1),query(a,b,x+x+2,l+r>>1,r));
  }
};
//}}}
}
}
#endif
//}}}

using namespace std;
using namespace orislib::ds;

typedef long long ll;
typedef long double ld;
typedef tuple<int, int> duo;

const int dx[] = {0, 0, 1, -1, 1, 1, -1, -1};
const int dy[] = {1, -1, 0, 0, 1, -1, 1, -1};
const int Mod = 1000000000 + 0;
//{{{ templates
#define TT_ template<typename T>inline
#define TTF_ template<typename T,typename F>inline
TT_ T sq(T x){return x*x;}
TT_ T In(){T x;cin>>x;return x;}
TT_ void Out(T&x){cout<<x;}
TT_ void sort(T&v){sort(begin(v),end(v));}
TT_ void revs(T&v){reverse(begin(v),end(v));}
TT_ void uniq(T&v){sort(v);v.erase(unique(begin(v),end(v)),end(v));}
TT_ int ubnd(T&v,typename T::value_type x){return upper_bound(begin(v),end(v),x)-begin(v);}
TT_ int lbnd(T&v,typename T::value_type x){return lower_bound(begin(v),end(v),x)-begin(v);}
TTF_ void inpt(T&v,int n,F f){for(v.reserve(n);n--;v.emplace_back(f()));}
TTF_ void show(T&v,F f,string d=" ",string e="\n"){int i=0;for(auto&x:v)i++&&(cout<<d),f(x);cout<<e;}
TT_ typename T::iterator minel(T&v){return min_element(begin(v),end(v));}
TT_ typename T::iterator maxel(T&v){return max_element(begin(v),end(v));}

inline void fast_io(){ios_base::sync_with_stdio(0);cin.tie(0);}
inline int in(){int x;scanf("%d",&x);return x;}
inline ll pow_mod(ll a,ll k,ll m){ll r=1;for(;k>0;a=a*a%m,k>>=1)if(k&1)r=r*a%m;return r;}
inline ll mod_inv(ll a,ll p){return pow_mod(a,p-2,p);}
//}}} priority_queue queue deque front stringstream max_element min_element insert count make_tuple

#define int long long

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

SegT<int, 200200> xmax(INT_MIN, [](int a, int b){ return max(a, b); });
SegT<int, 200200> xmin(INT_MAX, [](int a, int b){ return min(a, b); });
SegT<int, 200200> ymax(INT_MIN, [](int a, int b){ return max(a, b); });
SegT<int, 200200> ymin(INT_MAX, [](int a, int b){ return min(a, b); });

signed main()
{

  int N = in();
  int d = in();
  vector<Star> vs;
  for (int i = 0; i < N; i++){
    int x = in();
    int y = in();
    int b = in();
    vs.emplace_back(x, y, b);
  }
  sort(vs);
  for (int i = 0; i < N; i++){
    xmin.update(i, vs[i].x);
    xmax.update(i, vs[i].x);
    ymin.update(i, vs[i].y);
    ymax.update(i, vs[i].y);
  }

  int maxi = 0;
  for (int i = 0; i < N; i++){
    int t = ubnd(vs, Star(0, 0, vs[i].b + d));
    int xmini = xmin.query(i, t);
    int xmaxi = xmax.query(i, t);
    int ymini = ymin.query(i, t);
    int ymaxi = ymax.query(i, t);
    maxi = max(maxi, abs(xmaxi - xmini) * abs(ymaxi - ymini));
  }
  cout << maxi << endl;

  return 0;
}

Measured memory_bytes: 25356