#include <iostream>
#include <vector>
#include <cassert>
#include <algorithm>
#include <limits>
#include <queue>

using namespace std;
using ll = long long;
template <typename T>
T INF = numeric_limits<T>::max() / 2;

class CostFlow
{
public:
    using Cost = int;
    using Ind = short;
    using Capacity = char;
    using T = int;
    // using Cost = ll;
    // using Ind = int;
    // using Capacity = ll;
    // using T = ll;

    struct Edge {
        Edge(const Ind from_, const Ind to_, const Ind reverse_, const Capacity capacity_, const Cost cost_, const bool is_reverse_ = false) : from{from_}, to{to_}, reverse{reverse_}, capacity{capacity_}, flow{0}, cost{cost_}, is_reverse{is_reverse_} {}
        Ind from;
        Ind to;
        Ind reverse;
        Capacity capacity;
        Capacity flow;
        Cost cost;
        bool is_reverse;
    };

    CostFlow(const Ind v) : V{v}
    {
        edge.resize(v);
        m_dist.resize(v);
        m_potential.resize(v);
        m_prev_v.resize(v);
        m_prev_e.resize(v);
    }

    void addEdge(const Ind from, const Ind to, const Capacity capacity, const Cost cost)
    {
        edge[from].push_back(Edge{from, to, (Ind)edge[to].size(), (Capacity)capacity, (Cost)cost, false});
        edge[to].push_back(Edge{to, from, (Ind)(edge[from].size() - 1), (Capacity)0, (Cost)(-cost), true});
    }

    T minCostFlow(const Ind s, const Ind t, T f)
    {
        using P = pair<Cost, Ind>;
        T res = 0;
        fill(m_potential.begin(), m_potential.end(), INF<Cost>);
        m_potential[s] = 0;
        for (int i = 0; i < V; i++) {
            if (m_potential[i] != INF<Cost>) {
                for (const auto& e : edge[i]) {
                    if (not e.is_reverse) {
                        m_potential[e.to] = min(m_potential[e.to], m_potential[i] + e.cost);
                    }
                }
            }
        }

        while (f > 0) {
            // Dijkstra
            priority_queue<P, vector<P>, greater<P>> q;
            fill(m_dist.begin(), m_dist.end(), INF<Cost>);
            m_dist[s] = 0;
            q.push(make_pair(0, s));
            while (not q.empty()) {
                const P p = q.top();
                q.pop();
                const Ind v = p.second;
                if (m_dist[v] < p.first) {
                    continue;
                }
                for (Ind i = 0; i < edge[v].size(); i++) {
                    const auto& e = edge[v][i];
                    if (e.capacity > e.flow and m_dist[e.to] > m_dist[v] + e.cost + m_potential[v] - m_potential[e.to]) {
                        m_dist[e.to] = m_dist[v] + e.cost + m_potential[v] - m_potential[e.to];
                        m_prev_v[e.to] = v;
                        m_prev_e[e.to] = i;
                        q.push(make_pair(m_dist[e.to], e.to));
                    }
                }
            }

            if (m_dist[t] == INF<Cost>) {
                return res;
            }
            for (Ind v = 0; v < V; v++) {
                m_potential[v] += m_dist[v];
            }

            Capacity d = f;
            for (Ind v = t; v != s; v = m_prev_v[v]) {
                const auto& e = edge[m_prev_v[v]][m_prev_e[v]];
                d = min(d, (Capacity)(e.capacity - e.flow));
            }
            f -= d;
            res += (Cost)d * m_potential[t];
            for (Ind v = t; v != s; v = m_prev_v[v]) {
                auto& e = edge[m_prev_v[v]][m_prev_e[v]];
                e.flow += d;
                edge[v][e.reverse].flow -= d;
            }
        }
        return res;
    }

    const Ind V;
    vector<vector<Edge>> edge;

private:
    vector<Cost> m_dist;
    vector<Cost> m_potential;
    vector<Ind> m_prev_v;
    vector<Ind> m_prev_e;
};

struct Point {
    int X;
    int T;
    int P;
    bool operator<(const Point& p) const
    {
        return T < p.T;
    }
};

int main()
{
    CostFlow::Ind N;
    cin >> N;
    int V, L, R;
    cin >> V >> L >> R;
    vector<Point> point(N);
    for (CostFlow::Ind i = 0; i < N; i++) {
        cin >> point[i].X >> point[i].T >> point[i].P;
    }
    sort(point.begin(), point.end());
    CostFlow flow(2 * N + 4);
    const CostFlow::Ind s = 0;
    const CostFlow::Ind t = 2 * N + 3;
    const CostFlow::Ind l = 1;
    const CostFlow::Ind r = 2;
    flow.addEdge(s, l, 1, 0);
    flow.addEdge(s, r, 1, 0);
    for (CostFlow::Ind i = 0; i < N; i++) {
        flow.addEdge(2 * i + 3, 2 * i + 4, 1, 0);
        flow.addEdge(2 * i + 4, t, 1, -point[i].P);
        if (abs(point[i].X - L) <= V * point[i].T) {
            flow.addEdge(l, 2 * i + 3, 1, 0);
        }
        if (abs(point[i].X - R) <= V * point[i].T) {
            flow.addEdge(r, 2 * i + 3, 1, 0);
        }
    }
    for (CostFlow::Ind i = 0; i < N; i++) {
        for (CostFlow::Ind j = i + 1; j < N; j++) {
            if (abs(point[i].X - point[j].X) <= V * (point[j].T - point[i].T)) {
                flow.addEdge(2 * i + 4, 2 * j + 3, 1, -point[i].P);
            }
        }
    }
    cout << -flow.minCostFlow(s, t, 2) << endl;

    return 0;
}