```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())
}
```