← Home
```go
package main

import (
	"bytes"
	"io"
	"os"
	"strconv"
)

type Pair struct {
	h int64
	w int64
}

func nextInt(data []byte, idx *int) int64 {
	n := len(data)
	for *idx < n {
		c := data[*idx]
		if c >= '0' && c <= '9' {
			break
		}
		*idx++
	}
	var v int64
	for *idx < n {
		c := data[*idx]
		if c < '0' || c > '9' {
			break
		}
		v = v*10 + int64(c-'0')
		*idx++
	}
	return v
}

func verify(a, b []int64, H, W int64) bool {
	n := len(a)
	byH := make(map[int64][]int, n)
	byW := make(map[int64][]int, n)
	for i := 0; i < n; i++ {
		byH[a[i]] = append(byH[a[i]], i)
		byW[b[i]] = append(byW[b[i]], i)
	}
	active := make([]bool, n)
	for i := 0; i < n; i++ {
		active[i] = true
	}
	remain := n

	popH := func(key int64) int {
		s := byH[key]
		for len(s) > 0 && !active[s[len(s)-1]] {
			s = s[:len(s)-1]
		}
		byH[key] = s
		if len(s) == 0 {
			return -1
		}
		return s[len(s)-1]
	}

	popW := func(key int64) int {
		s := byW[key]
		for len(s) > 0 && !active[s[len(s)-1]] {
			s = s[:len(s)-1]
		}
		byW[key] = s
		if len(s) == 0 {
			return -1
		}
		return s[len(s)-1]
	}

	curH, curW := H, W
	for remain > 0 {
		id := popH(curH)
		if id != -1 {
			active[id] = false
			curW -= b[id]
			if curW < 0 {
				return false
			}
			remain--
			continue
		}
		id = popW(curW)
		if id == -1 {
			return false
		}
		active[id] = false
		curH -= a[id]
		if curH < 0 {
			return false
		}
		remain--
	}
	return true
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	t := int(nextInt(data, &idx))
	var out bytes.Buffer

	for ; t > 0; t-- {
		n := int(nextInt(data, &idx))
		a := make([]int64, n)
		b := make([]int64, n)
		var sum int64
		var maxA, maxB int64
		for i := 0; i < n; i++ {
			a[i] = nextInt(data, &idx)
			b[i] = nextInt(data, &idx)
			sum += a[i] * b[i]
			if a[i] > maxA {
				maxA = a[i]
			}
			if b[i] > maxB {
				maxB = b[i]
			}
		}

		ans := make([]Pair, 0, 2)

		if sum%maxA == 0 {
			H := maxA
			W := sum / maxA
			if verify(a, b, H, W) {
				ans = append(ans, Pair{H, W})
			}
		}
		if sum%maxB == 0 {
			H := sum / maxB
			W := maxB
			dup := false
			for _, p := range ans {
				if p.h == H && p.w == W {
					dup = true
					break
				}
			}
			if !dup && verify(a, b, H, W) {
				ans = append(ans, Pair{H, W})
			}
		}

		out.WriteString(strconv.Itoa(len(ans)))
		out.WriteByte('\n')
		for _, p := range ans {
			out.WriteString(strconv.FormatInt(p.h, 10))
			out.WriteByte(' ')
			out.WriteString(strconv.FormatInt(p.w, 10))
			out.WriteByte('\n')
		}
	}

	os.Stdout.Write(out.Bytes())
}
```