#include #include using namespace std; using namespace atcoder; using ll = long long; const ll INF = 1LL << 60; // 区間加算・区間最大値取得 ll op(ll a, ll b){ return max(a, b); } ll e(){ return -INF; } ll mapping(ll f, ll x){ return f+x; } ll composition(ll f, ll g){ return f+g; } ll id(){ return 0; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; ll A; cin >> N >> A; vector> P(N); for (int i = 0; i < N; i++) { ll x, y, v; cin >> x >> y >> v; P[i] = {x, y, v}; } sort(P.begin(), P.end()); auto compress = [](vector &vec) { vector S = vec; sort(S.begin(), S.end()); S.erase(unique(S.begin(), S.end()), S.end()); map D; for (int i = 0; i < (int)S.size(); i++) { D[S[i]] = i; } return make_pair(D, S); }; auto func = [&](ll B) { vector X, Y; for (auto &[x, y, v] : P) { X.push_back(x + B); X.push_back(x); X.push_back(x + B + 1); X.push_back(x - 1); Y.push_back(y); Y.push_back(y - A); Y.push_back(y - (A - 1)); Y.push_back(y + 1); Y.push_back(y - A - 1); Y.push_back(y - (A - 1) - 1); } sort(X.begin(), X.end()); X.erase(unique(X.begin(), X.end()), X.end()); auto [D, C] = compress(Y); int M = C.size(); vector L1(M), L2(M); for (int i = 0; i < M; i++) { L1[i] = lower_bound(C.begin(), C.end(), C[i] - A) - C.begin(); L2[i] = lower_bound(C.begin(), C.end(), C[i] - (A - 1)) - C.begin(); } vector def(M, 0); lazy_segtree seg1(def), seg2(def); int idxR = 0, idxL = 0; ll ans = 0; for (ll x : X) { while (idxR < N && get<0>(P[idxR]) <= x) { auto &[_, y, v] = P[idxR]; int dy = D[y]; seg1.apply(L1[dy], dy + 1, v); seg2.apply(L2[dy], dy + 1, v); idxR++; } while (idxL < N && get<0>(P[idxL]) < x - B) { auto &[_, y, v] = P[idxL]; int dy = D[y]; seg1.apply(L1[dy], dy + 1, -v); seg2.apply(L2[dy], dy + 1, -v); idxL++; } ans = max({ans, seg1.all_prod(), seg2.all_prod()}); } return ans; }; cout << max({func(A), func(A - 1), 0LL}) << '\n'; return 0; }