← Home
package main

import (
	"bufio"
	"container/heap"
	"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 {
	var sign int64 = 1
	var val int64 = 0
	b, _ := fs.r.ReadByte()
	for (b < '0' || b > '9') && b != '-' {
		b, _ = fs.r.ReadByte()
	}
	if b == '-' {
		sign = -1
		b, _ = fs.r.ReadByte()
	}
	for b >= '0' && b <= '9' {
		val = val*10 + int64(b-'0')
		b, _ = fs.r.ReadByte()
	}
	return val * sign
}

type Robot struct {
	c    int64
	f    int64
	w    int64
	good bool
}

type MinHeap []int64
func (h MinHeap) Len() int           { return len(h) }
func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h MinHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *MinHeap) Push(x interface{}) {
	*h = append(*h, x.(int64))
}
func (h *MinHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[:n-1]
	return x
}

type MaxHeap []int64
func (h MaxHeap) Len() int           { return len(h) }
func (h MaxHeap) Less(i, j int) bool { return h[i] > h[j] }
func (h MaxHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *MaxHeap) Push(x interface{}) {
	*h = append(*h, x.(int64))
}
func (h *MaxHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[:n-1]
	return x
}

func main() {
	fs := NewFastScanner()
	n := int(fs.nextInt64())
	d := fs.nextInt64()
	S := fs.nextInt64()

	robots := make([]Robot, n)
	for i := 0; i < n; i++ {
		ci := fs.nextInt64()
		fi := fs.nextInt64()
		li := fs.nextInt64()
		good := li >= d
		w := ci
		if good {
			w++
		}
		robots[i] = Robot{c: ci, f: fi, w: w, good: good}
	}

	sort.Slice(robots, func(i, j int) bool {
		if robots[i].w != robots[j].w {
			return robots[i].w > robots[j].w
		}
		if robots[i].good != robots[j].good {
			return !robots[i].good && robots[j].good
		}
		if robots[i].c != robots[j].c {
			return robots[i].c > robots[j].c
		}
		if robots[i].good && robots[j].good && robots[i].f != robots[j].f {
			return robots[i].f < robots[j].f
		}
		return i < j
	})

	var prefixC int64 = 0
	var sumChosen int64 = 0
	chosen := &MaxHeap{}
	others := &MinHeap{}
	heap.Init(chosen)
	heap.Init(others)

	bestCount := int64(0)
	bestFuel := int64(0)

	for i := 0; i < n; i++ {
		r := robots[i]
		prefixC += r.c
		if r.good {
			heap.Push(others, r.f)
		}
		D := int64(i+1) - prefixC
		if D < 0 {
			D = 0
		}

		// Adjust sizes
		for int64(chosen.Len()) > D {
			x := heap.Pop(chosen).(int64)
			sumChosen -= x
			heap.Push(others, x)
		}
		for int64(chosen.Len()) < D {
			if others.Len() == 0 {
				break
			}
			y := heap.Pop(others).(int64)
			sumChosen += y
			heap.Push(chosen, y)
		}
		// Balance to ensure chosen has the smallest D
		for chosen.Len() > 0 && others.Len() > 0 {
			maxChosen := (*chosen)[0]
			minOthers := (*others)[0]
			if maxChosen <= minOthers {
				break
			}
			heap.Pop(chosen)
			heap.Pop(others)
			sumChosen += minOthers - maxChosen
			heap.Push(chosen, minOthers)
			heap.Push(others, maxChosen)
		}

		if int64(chosen.Len()) == D {
			if sumChosen <= S {
				curCount := int64(i + 1)
				if curCount > bestCount {
					bestCount = curCount
					bestFuel = sumChosen
				} else if curCount == bestCount && sumChosen < bestFuel {
					bestFuel = sumChosen
				}
			}
		}
	}

	if bestCount == 0 {
		fmt.Println("0 0")
	} else {
		fmt.Printf("%d %d\n", bestCount, bestFuel)
	}
}