#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <array>
#include <climits>
#include <bitset>
#include <cassert>

// BEGIN CUT HERE
#ifdef _MSC_VER
#include <agents.h>
#define __float128 long double
#endif
// END CUT HERE 

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define UNIQUE(v) (v).erase(unique(ALL(v)), (v).end())
#define MP make_pair
#define MT make_tuple

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

vector<P> ord;

struct MinCostFlow{
	struct edge{
		int to, cost, rev, cap;
		edge(int to, int cost, int rev, int cap) :to(to), cost(cost), rev(rev), cap(cap){}
	};

	int n;
	vector<vector<edge>> G;

	void add(int from, int to, int cost, int cap){
		G[from].push_back(edge(to, cost, G[to].size(), cap));
		G[to].push_back(edge(from, -cost, G[from].size() - 1, 0));
	}
	vector<int> dist, h, prevv, preve;
	static const int INF = 1e9;

	MinCostFlow(int size){
		n = size;
		G.assign(n, vector<edge>());
		dist.assign(n, 0);
		h.assign(n, 0);
		prevv.assign(n, 0);
		preve.assign(n, 0);
	}

	void init(int s){
		fill(h.begin(), h.end(), INF);
		h[s] = 0;

		for(auto &p : ord){
			int v = p.second;
			for (auto &e : G[v]){
				if (e.cap <= 0) continue;
				if (h[v] + e.cost >= h[e.to]) continue;
				h[e.to] = h[v] + e.cost;
			}
		}
	}

	int min_cost_flow(int s, int t, int f){
		int res = 0;
		init(s);
		while (f){
			rep(i, n) dist[i] = INF;
			dist[s] = 0;
			priority_queue<P, vector<P>, greater<P> > q;
			q.push(MP(0, s));
			while (!q.empty()){
				int pos = q.top().second;
				int d = q.top().first;
				q.pop();

				if (dist[pos] < d) continue;

				rep(i, G[pos].size()){
					edge &e = G[pos][i];
					if (e.cap <= 0) continue;
					if (dist[pos] + e.cost + h[pos] - h[e.to] < dist[e.to]){
						dist[e.to] = dist[pos] + e.cost + h[pos] - h[e.to];
						prevv[e.to] = pos;
						preve[e.to] = i;
						q.push(MP(dist[e.to], e.to));
					}
				}

			}

			if (dist[t] == INF) return -1;

			rep(i, n) h[i] += dist[i];

			int d = f;
			for (int v = t; v != s; v = prevv[v]){
				d = min(d, G[prevv[v]][preve[v]].cap);
			}
			f -= d;
			res += d*h[t];
			for (int v = t; v != s; v = prevv[v]){
				edge &e = G[prevv[v]][preve[v]];
				e.cap -= d;
				G[e.to][e.rev].cap += d;
			}
		}

		return res;
	}
};


int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);

	int n, V;
	cin >> n >> V;

	n += 2;
	vector<int> x(n), t(n), p(n);
	cin >> x[0] >> x[1];
	FOR(i, 2, n) cin >> x[i] >> t[i] >> p[i];

	MinCostFlow mcf(n * 2 + 2);
	const int SRC = n * 2, SNK = SRC + 1;

	mcf.add(SRC, 0, 0, 1);
	mcf.add(SRC, 1, 0, 1);

	rep(i, n){
		mcf.add(i, i + n, 0, 1);
		mcf.add(i, i + n, -p[i], 1);
		mcf.add(i + n, SNK, 0, 2);
	}

	ord.emplace_back(-1e9, SRC);
	ord.emplace_back(1e9, SNK);
	rep(i, n){
		ord.emplace_back(t[i], i);
		ord.emplace_back(t[i], i+n);
	}
	sort(ALL(ord));

	rep(i, n) rep(j, n){
		if (t[i] >= t[j]) continue;
		if ((t[j] - t[i])*V >= abs(x[i] - x[j])){
			mcf.add(n + i, j, 0, 1);
			//cout << i << ' ' << j << endl;
		}
	}

	cout << -mcf.min_cost_flow(SRC, SNK, 2) << endl;

	return 0;
}

Measured memory_bytes: 240696