← Home
```go
package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"sort"
)

type Candy struct {
	c, g int
}

type IntHeap []int

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var q int
	fmt.Fscan(in, &q)

	for k := 0; k < q; k++ {
		var n int
		fmt.Fscan(in, &n)

		cnts := make([]Candy, n+1)
		for j := 0; j < n; j++ {
			var a, f int
			fmt.Fscan(in, &a, &f)
			cnts[a].c++
			if f == 1 {
				cnts[a].g++
			}
		}

		types := make([]Candy, 0, n)
		for j := 1; j <= n; j++ {
			if cnts[j].c > 0 {
				types = append(types, cnts[j])
			}
		}

		sort.Slice(types, func(i, j int) bool {
			return types[i].c > types[j].c
		})

		var V []int
		var sumC int64
		last := 2000000000

		for _, t := range types {
			val := t.c
			if val >= last {
				val = last - 1
			}
			if val <= 0 {
				break
			}
			V = append(V, val)
			sumC += int64(val)
			last = val
		}

		pq := &IntHeap{}
		heap.Init(pq)
		var sumG int64
		idx := 0

		for _, v := range V {
			for idx < len(types) && types[idx].c >= v {
				heap.Push(pq, types[idx].g)
				idx++
			}
			if pq.Len() > 0 {
				g := heap.Pop(pq).(int)
				take := v
				if g < take {
					take = g
				}
				sumG += int64(take)
			}
		}

		fmt.Fprintln(out, sumC, sumG)
	}
}
```