← Home
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	buf := make([]byte, 1024*1024)
	scanner.Buffer(buf, 10*1024*1024)

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))

	S := make([][]int, n+1)
	for i := 1; i <= n; i++ {
		S[i] = make([]int, n+1)
	}

	for i := 1; i <= n; i++ {
		if !scanner.Scan() {
			return
		}
		line := strings.TrimSpace(scanner.Text())
		lists := strings.Split(line, "-")
		for _, list := range lists {
			parts := strings.Split(list, ":")
			if len(parts) != 2 {
				continue
			}
			sz, _ := strconv.Atoi(parts[0])
			vertices := strings.Split(parts[1], ",")
			for _, vStr := range vertices {
				v, _ := strconv.Atoi(vStr)
				if v >= 1 && v <= n {
					S[i][v] = sz
				}
			}
		}
	}

	edges := [][2]int{}
	for i := 1; i <= n; i++ {
		for j := i + 1; j <= n; j++ {
			if S[i][j]+S[j][i] == n {
				edges = append(edges, [2]int{i, j})
			}
		}
	}

	if len(edges) != n-1 {
		fmt.Println("-1")
		return
	}

	parent := make([]int, n+1)
	for i := 1; i <= n; i++ {
		parent[i] = i
	}
	var find func(int) int
	find = func(i int) int {
		if parent[i] == i {
			return i
		}
		parent[i] = find(parent[i])
		return parent[i]
	}

	for _, e := range edges {
		u, v := e[0], e[1]
		pu, pv := find(u), find(v)
		if pu == pv {
			fmt.Println("-1")
			return
		}
		parent[pu] = pv
	}

	fmt.Println(n - 1)
	for _, e := range edges {
		fmt.Printf("%d %d\n", e[0], e[1])
	}
}