#include using namespace std; using ll = long long; template struct SegmentTree { public: SegmentTree() : SegmentTree(0) {} explicit SegmentTree(const size_t n) : SegmentTree(vector(n, e())) {} explicit SegmentTree(const vector &v) : m_size(v.size()) { for (m_leafSize = 1; m_leafSize < m_size;) { m_leafSize <<= 1; } m_data.assign(2 * m_leafSize, e()); for (int i = 0; i < m_size; i++) { m_data[m_leafSize + i] = v[i]; } for (int i = m_leafSize - 1; i >= 1; i--) { m_data[i] = op(m_data[2 * i], m_data[2 * i + 1]); } } void set(size_t p, const S &x) { assert(0 <= p && p < m_size); p += m_leafSize; m_data[p] = x; update(p); } void add(size_t p, const S &x) { assert(0 <= p && p < m_size); p += m_leafSize; m_data[p] += x; update(p); } S prod(size_t l, size_t r) const { assert(0 <= l && l <= r && r <= m_size); auto sml = e(), smr = e(); for (l += m_leafSize, r += m_leafSize; l < r; l >>= 1, r >>= 1) { if (l & 1) { sml = op(sml, m_data[l++]); } if (r & 1) { smr = op(m_data[--r], smr); } } return op(sml, smr); } inline S allProd() const { return m_data[1]; } private: size_t m_size; size_t m_leafSize = 1; vector m_data; inline void update(size_t p) { while (p >>= 1) { m_data[p] = op(m_data[2 * p], m_data[2 * p + 1]); } } }; using RMQ = SegmentTree::lowest(); }>; int main() { int n, w, d; cin >> n >> w >> d; vector> t[2]; for (int i = 0; i < n; i++) { ll ti, wi, vi; cin >> ti >> wi >> vi; t[ti].emplace_back(wi, vi); } vector dp(2, vector(w + 1, -1ll)); dp[0][0] = dp[1][0] = 0; for (const auto p : {0, 1}) { const auto &v = t[p]; for (int i = 0; i < v.size(); i++) { const auto [wi, vi] = v[i]; auto nxt = vector(w + 1, -1ll); for (int j = 0; j <= w; j++) { if (j - wi >= 0) { if (dp[p][j - wi] == -1) { nxt[j] = dp[p][j]; continue; } nxt[j] = max(dp[p][j - wi] + vi, dp[p][j]); } else { nxt[j] = dp[p][j]; } } swap(dp[p], nxt); } } RMQ segtree(dp[1]); ll ans = 0; for (int i = 0; i <= w; i++) { if (dp[0][i] == -1) { continue; } const auto rw = w - i; if (rw < i - d) { continue; } // i - d <= rw const auto cur = segtree.prod(max(0, i - d), min(i + d, rw) + 1); if (cur == -1) { continue; } ans = max(ans, dp[0][i] + cur); } cout << ans << endl; return 0; }