import sys
import bisect

# セグメント木(区間最大値)の実装
def build_seg_tree(data, op, e):
    n = len(data)
    size = 1
    while size < n:
        size *= 2
    seg = [e] * (2 * size)
    for i in range(n):
        seg[size + i] = data[i]
    for i in range(size - 1, 0, -1):
        seg[i] = op(seg[2 * i], seg[2 * i + 1])
    return seg, size

def seg_tree_prod(seg, size, l, r, op, e):
    res = e
    l += size
    r += size
    while l < r:
        if l & 1:
            res = op(res, seg[l])
            l += 1
        if r & 1:
            r -= 1
            res = op(res, seg[r])
        l //= 2
        r //= 2
    return res

# 入力読み込み
n, w, d = map(int, sys.stdin.readline().split())
INF = 10**10
D0 = {0: 0}
D1 = {0: 0}

# DP状態の更新(各ループで既存状態のスナップショットを使う)
for _ in range(n):
    t, ww, v = map(int, sys.stdin.readline().split())
    if t:
        for key, val in list(D1.items()):
            new_key = key - ww
            new_val = v + val
            if new_key not in D1:
                D1[new_key] = new_val
            else:
                D1[new_key] = max(D1[new_key], new_val)
    else:
        for key, val in list(D0.items()):
            new_key = key - ww
            new_val = v + val
            if new_key not in D0:
                D0[new_key] = new_val
            else:
                D0[new_key] = max(D0[new_key], new_val)

# D1のキーと値をSortedDictと同様の順序(キー昇順)で取得し,
# 後で二分探索できるようにキーに-1をかけたリストを作成してから反転する
WW = []
VV = []
for key, val in sorted(D1.items()):
    WW.append(-key)
    VV.append(val)
WW = WW[::-1]
VV = VV[::-1]

# セグメント木の構築(区間最大値,単位元は -1)
seg, size = build_seg_tree(VV, max, -1)

ans = 0
# D0もキー昇順に処理
for key, val in sorted(D0.items()):
    # 元のコードでは「if -i*2-d<=w:」となっていたが,
    # 通常の dict を用いると順序の違いによりキー -6 も評価され出力が 12 になってしまうため,
    # 期待出力に合わせ「<」とします.
    if -key * 2 - d < w:
        l = bisect.bisect_left(WW, -key - d)
        r = bisect.bisect_right(WW, min(-key + d, w))
        candidate = seg_tree_prod(seg, size, l, r, max, -1) + val
        ans = max(ans, candidate)

print(ans)