← Home
package main

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

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

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

	dist := make([][]uint16, k)
	for i := 0; i < k; i++ {
		dist[i] = make([]uint16, n+1)
		for j := 1; j <= n; j++ {
			scanner.Scan()
			val, _ := strconv.Atoi(scanner.Text())
			dist[i][j] = uint16(val)
		}
	}

	S := make([]int, k)
	for i := 0; i < k; i++ {
		zeros := 0
		src := -1
		for j := 1; j <= n; j++ {
			if dist[i][j] == 0 {
				zeros++
				src = j
			}
		}
		if zeros != 1 {
			fmt.Println("-1")
			return
		}
		S[i] = src
	}

	keyBuf := make([]byte, k*2)
	getVectorKey := func(v int) string {
		for j := 0; j < k; j++ {
			val := dist[j][v]
			keyBuf[j*2] = byte(val >> 8)
			keyBuf[j*2+1] = byte(val)
		}
		return string(keyBuf)
	}

	vecMap := make(map[string]int)
	for i := 1; i <= n; i++ {
		kStr := getVectorKey(i)
		if _, exists := vecMap[kStr]; !exists {
			vecMap[kStr] = i
		}
	}

	parent := make([]int, n+1)
	s1 := S[0]

	for i := 1; i <= n; i++ {
		if i == s1 {
			continue
		}

		for j := 0; j < k; j++ {
			val := int(dist[j][i])
			if int(dist[0][S[j]]) == int(dist[0][i])+int(dist[j][i]) {
				val++
			} else {
				val--
			}
			uval := uint16(val)
			keyBuf[j*2] = byte(uval >> 8)
			keyBuf[j*2+1] = byte(uval)
		}
		pKey := string(keyBuf)
		p, exists := vecMap[pKey]
		if !exists {
			fmt.Println("-1")
			return
		}
		parent[i] = p
	}

	adj := make([][]int, n+1)
	for i := 1; i <= n; i++ {
		if i == s1 {
			continue
		}
		p := parent[i]
		adj[i] = append(adj[i], p)
		adj[p] = append(adj[p], i)
	}

	bfsDist := make([]int, n+1)
	q := make([]int, n)

	for i := 0; i < k; i++ {
		src := S[i]
		for j := 1; j <= n; j++ {
			bfsDist[j] = -1
		}

		head, tail := 0, 0
		q[tail] = src
		tail++
		bfsDist[src] = 0

		for head < tail {
			curr := q[head]
			head++

			if bfsDist[curr] != int(dist[i][curr]) {
				fmt.Println("-1")
				return
			}

			for _, nxt := range adj[curr] {
				if bfsDist[nxt] == -1 {
					bfsDist[nxt] = bfsDist[curr] + 1
					q[tail] = nxt
					tail++
				}
			}
		}

		for j := 1; j <= n; j++ {
			if bfsDist[j] != int(dist[i][j]) {
				fmt.Println("-1")
				return
			}
		}
	}

	out := bufio.NewWriter(os.Stdout)
	for i := 1; i <= n; i++ {
		if i == s1 {
			continue
		}
		fmt.Fprintf(out, "%d %d\n", i, parent[i])
	}
	out.Flush()
}