package main
import (
"bufio"
"fmt"
"os"
"sort"
)
type FastScanner struct {
r *bufio.Reader
}
func NewFastScanner() *FastScanner {
return &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}
func (fs *FastScanner) NextInt64() (int64, error) {
var sign int64 = 1
var val int64 = 0
c, err := fs.r.ReadByte()
for err == nil && (c < '0' || c > '9') && c != '-' {
c, err = fs.r.ReadByte()
}
if err != nil {
return 0, err
}
if c == '-' {
sign = -1
c, err = fs.r.ReadByte()
if err != nil {
return 0, err
}
}
for err == nil && c >= '0' && c <= '9' {
val = val*10 + int64(c-'0')
c, err = fs.r.ReadByte()
}
return val * sign, nil
}
type item struct {
cost int64
isB bool
}
func main() {
in := NewFastScanner()
n64, err := in.NextInt64()
if err != nil {
return
}
d, _ := in.NextInt64()
S, _ := in.NextInt64()
n := int(n64)
var Zn int64 = 0
var G int64 = 0
A := make([]int64, 0) // c=0, l>=d
B := make([]int64, 0) // c>=1, l>=d
for i := 0; i < n; i++ {
ci, _ := in.NextInt64()
fi, _ := in.NextInt64()
li, _ := in.NextInt64()
if ci == 0 {
Zn++
} else {
G += (ci - 1)
}
if li >= d {
if ci == 0 {
A = append(A, fi)
} else {
B = append(B, fi)
}
}
}
sort.Slice(A, func(i, j int) bool { return A[i] < A[j] })
sort.Slice(B, func(i, j int) bool { return B[i] < B[j] })
pA := make([]int64, len(A)+1)
for i := 1; i <= len(A); i++ {
pA[i] = pA[i-1] + A[i-1]
}
combined := make([]item, 0, len(A)+len(B))
for _, c := range B {
combined = append(combined, item{cost: c, isB: true})
}
for _, c := range A {
combined = append(combined, item{cost: c, isB: false})
}
sort.Slice(combined, func(i, j int) bool {
if combined[i].cost != combined[j].cost {
return combined[i].cost < combined[j].cost
}
if combined[i].isB != combined[j].isB {
return combined[i].isB && !combined[j].isB
}
return false
})
sc := make([]int64, len(combined)+1)
cb := make([]int, len(combined)+1)
for i := 1; i <= len(combined); i++ {
sc[i] = sc[i-1] + combined[i-1].cost
cb[i] = cb[i-1]
if combined[i-1].isB {
cb[i]++
}
}
const INF int64 = 1<<62 - 1
minB := INF
if len(B) > 0 {
minB = B[0]
}
bestT := int64(0)
bestFuel := int64(0)
kA := 0
for i := 1; i <= len(A); i++ {
if pA[i] <= S {
kA = i
} else {
break
}
}
TA := int64(kA)
if TA > bestT || (TA == bestT && pA[kA] < bestFuel) {
bestT = TA
bestFuel = pA[kA]
}
if len(B) > 0 {
for m := 1; m <= len(combined); m++ {
var FM int64
if cb[m] > 0 {
FM = sc[m]
} else {
if minB == INF {
continue
}
FM = sc[m] - combined[m-1].cost + minB
}
if FM > S {
continue
}
def := Zn - G - int64(m)
if def < 0 {
def = 0
}
Tm := int64(n) - def
if Tm > bestT || (Tm == bestT && FM < bestFuel) {
bestT = Tm
bestFuel = FM
}
}
}
fmt.Printf("%d %d\n", bestT, bestFuel)
}