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])
}
}