← Home
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)
}