← Home
```go
package main

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

type FastScanner struct {
	data []byte
	idx  int
	n    int
}

func NewFastScanner() *FastScanner {
	data, _ := io.ReadAll(os.Stdin)
	return &FastScanner{data: data, n: len(data)}
}

func (fs *FastScanner) NextInt() int {
	for fs.idx < fs.n && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	sign := 1
	if fs.data[fs.idx] == '-' {
		sign = -1
		fs.idx++
	}
	val := 0
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c < '0' || c > '9' {
			break
		}
		val = val*10 + int(c-'0')
		fs.idx++
	}
	return sign * val
}

type Edge struct {
	to  int
	rev int
	cap int
}

type Dinic struct {
	g     [][]Edge
	level []int
	it    []int
}

func NewDinic(n int) *Dinic {
	return &Dinic{
		g:     make([][]Edge, n),
		level: make([]int, n),
		it:    make([]int, n),
	}
}

func (d *Dinic) AddEdge(fr, to, cap int) {
	fwd := Edge{to: to, rev: len(d.g[to]), cap: cap}
	rev := Edge{to: fr, rev: len(d.g[fr]), cap: 0}
	d.g[fr] = append(d.g[fr], fwd)
	d.g[to] = append(d.g[to], rev)
}

func (d *Dinic) bfs(s, t int) bool {
	for i := range d.level {
		d.level[i] = -1
	}
	q := make([]int, 0, len(d.g))
	q = append(q, s)
	d.level[s] = 0
	for h := 0; h < len(q); h++ {
		v := q[h]
		for _, e := range d.g[v] {
			if e.cap > 0 && d.level[e.to] < 0 {
				d.level[e.to] = d.level[v] + 1
				q = append(q, e.to)
			}
		}
	}
	return d.level[t] >= 0
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func (d *Dinic) dfs(v, t, f int) int {
	if v == t {
		return f
	}
	for ; d.it[v] < len(d.g[v]); d.it[v]++ {
		i := d.it[v]
		e := &d.g[v][i]
		if e.cap > 0 && d.level[v] < d.level[e.to] {
			ret := d.dfs(e.to, t, min(f, e.cap))
			if ret > 0 {
				e.cap -= ret
				d.g[e.to][e.rev].cap += ret
				return ret
			}
		}
	}
	return 0
}

func (d *Dinic) MaxFlow(s, t int) int {
	flow := 0
	const inf = int(1 << 30)
	for d.bfs(s, t) {
		for i := range d.it {
			d.it[i] = 0
		}
		for {
			f := d.dfs(s, t, inf)
			if f == 0 {
				break
			}
			flow += f
		}
	}
	return flow
}

func writeInt(buf *bytes.Buffer, x int) {
	if x == 0 {
		buf.WriteByte('0')
		return
	}
	if x < 0 {
		buf.WriteByte('-')
		x = -x
	}
	var tmp [20]byte
	n := 0
	for x > 0 {
		tmp[n] = byte('0' + x%10)
		n++
		x /= 10
	}
	for i := n - 1; i >= 0; i-- {
		buf.WriteByte(tmp[i])
	}
}

func main() {
	fs := NewFastScanner()
	N := fs.NextInt()
	K := fs.NextInt()

	U := make([]int, N+1)
	V := make([]int, N+1)
	rawB := make([][]int, N+1)
	adjCity := make([][]int, N+1)

	for i := 1; i <= N; i++ {
		a := fs.NextInt()
		m := fs.NextInt()
		U[i] = i
		V[i] = a
		bs := make([]int, m)
		for j := 0; j < m; j++ {
			bs[j] = fs.NextInt()
		}
		rawB[i] = bs
		adjCity[i] = append(adjCity[i], i)
		adjCity[a] = append(adjCity[a], i)
	}

	matMap := make(map[int]int)
	workersByMat := make([][]int, 0)
	for i := 1; i <= K; i++ {
		c := fs.NextInt()
		idx, ok := matMap[c]
		if !ok {
			idx = len(workersByMat)
			matMap[c] = idx
			workersByMat = append(workersByMat, nil)
		}
		workersByMat[idx] = append(workersByMat[idx], i)
	}

	compList := make([][]int, N+1)
	for i := 1; i <= N; i++ {
		bs := rawB[i]
		list := make([]int, 0, len(bs))
		for _, x := range bs {
			if idx, ok := matMap[x]; ok {
				list = append(list, idx)
			}
		}
		compList[i] = list
	}

	deg := make([]int, N+1)
	for i := 1; i <= N; i++ {
		deg[U[i]]++
		deg[V[i]]++
	}

	alive := make([]bool, N+1)
	for i := 1; i <= N; i++ {
		alive[i] = true
	}

	q := make([]int, 0, N)
	for i := 1; i <= N; i++ {
		if deg[i] == 1 {
			q = append(q, i)
		}
	}

	for h := 0; h < len(q); h++ {
		v := q[h]
		if !alive[v] || deg[v] != 1 {
			continue
		}
		alive[v] = false
		for _, eid := range adjCity[v] {
			to := U[eid] + V[eid] - v
			if alive[to] {
				deg[to]--
				if deg[to] == 1 {
					q = append(q, to)
				}
			}
		}
	}

	cycleEdge := make([]bool, N+1)
	for i := 1; i <= N; i++ {
		if alive[U[i]] && alive[V[i]] {
			cycleEdge[i] = true
		}
	}

	D := len(workersByMat)
	S := 0
	matBase := N + 1
	dummy := N + D + 1
	T := N + D + 2

	dinic := NewDinic(T + 1)

	for i := 1; i <= N; i++ {
		dinic.AddEdge(S, i, 1)
		for _, mid := range compList[i] {
			dinic.AddEdge(i, matBase+mid, 1)
		}
		if cycleEdge[i] {
			dinic.AddEdge(i, dummy, 1)
		}
	}

	for mid := 0; mid < D; mid++ {
		dinic.AddEdge(matBase+mid, T, len(workersByMat[mid]))
	}
	dinic.AddEdge(dummy, T, 1)

	if dinic.MaxFlow(S, T) < N {
		var out bytes.Buffer
		out.WriteByte('-')
		out.WriteByte('1')
		out.WriteByte('\n')
		os.Stdout.Write(out.Bytes())
		return
	}

	assign := make([]int, N+1)
	for i := 1; i <= N; i++ {
		assign[i] = -2
		for _, e := range dinic.g[i] {
			if e.cap == 0 {
				if e.to >= matBase && e.to < dummy {
					assign[i] = e.to - matBase
					break
				}
				if e.to == dummy {
					assign[i] = -1
					break
				}
			}
		}
	}

	edgesByMat := make([][]int, D)
	for i := 1; i <= N; i++ {
		if assign[i] >= 0 {
			edgesByMat[assign[i]] = append(edgesByMat[assign[i]], i)
		}
	}

	ansU := make([]int, K+1)
	ansV := make([]int, K+1)

	for mid := 0; mid < D; mid++ {
		ids := workersByMat[mid]
		for _, eid := range edgesByMat[mid] {
			wid := ids[len(ids)-1]
			ids = ids[:len(ids)-1]
			ansU[wid] = U[eid]
			ansV[wid] = V[eid]
		}
	}

	var out bytes.Buffer
	for i := 1; i <= K; i++ {
		writeInt(&out, ansU[i])
		out.WriteByte(' ')
		writeInt(&out, ansV[i])
		out.WriteByte('\n')
	}
	os.Stdout.Write(out.Bytes())
}
```