package main
import (
"bufio"
"fmt"
"io"
"os"
)
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) int {
idx := len(d.g[fr])
d.g[fr] = append(d.g[fr], Edge{to: to, rev: len(d.g[to]), cap: cap})
d.g[to] = append(d.g[to], Edge{to: fr, rev: idx, cap: 0})
return idx
}
func (d *Dinic) bfs(s, t int) bool {
for i := range d.level {
d.level[i] = -1
}
q := make([]int, 1, len(d.g))
q[0] = s
d.level[s] = 0
for head := 0; head < len(q); head++ {
v := q[head]
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 {
const inf = int(1 << 30)
flow := 0
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 main() {
out := bufio.NewWriterSize(os.Stdout, 1<<20)
defer out.Flush()
data, _ := io.ReadAll(os.Stdin)
idx := 0
nextInt := func() int {
for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
idx++
}
n := 0
for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
n = n*10 + int(data[idx]-'0')
idx++
}
return n
}
N := nextInt()
K := nextInt()
U := make([]int, N)
V := make([]int, N)
edgeMats := make([][]int, N)
for i := 0; i < N; i++ {
a := nextInt() - 1
m := nextInt()
U[i] = i
V[i] = a
mats := make([]int, m)
for j := 0; j < m; j++ {
mats[j] = nextInt()
}
edgeMats[i] = mats
}
workersByMat := make(map[int][]int, K*2)
for i := 0; i < K; i++ {
c := nextInt()
workersByMat[c] = append(workersByMat[c], i)
}
g := make([][]int, N)
for e := 0; e < N; e++ {
u, v := U[e], V[e]
g[u] = append(g[u], e)
g[v] = append(g[v], e)
}
inCycle := make([]bool, N)
deg := make([]int, N)
q := make([]int, 0, N)
for i := 0; i < N; i++ {
inCycle[i] = true
deg[i] = len(g[i])
if deg[i] == 1 {
q = append(q, i)
}
}
for head := 0; head < len(q); head++ {
x := q[head]
if !inCycle[x] {
continue
}
inCycle[x] = false
for _, e := range g[x] {
y := U[e] + V[e] - x
if inCycle[y] {
deg[y]--
if deg[y] == 1 {
q = append(q, y)
}
}
}
}
mandatory := make([]bool, N)
optional := make([]bool, N)
mandatoryCount := 0
for e := 0; e < N; e++ {
if inCycle[U[e]] && inCycle[V[e]] {
optional[e] = true
} else {
mandatory[e] = true
mandatoryCount++
}
}
matID := make(map[int]int, len(workersByMat))
materials := make([]int, 0, len(workersByMat))
for m := range workersByMat {
matID[m] = len(materials)
materials = append(materials, m)
}
D := len(materials)
workersListByID := make([][]int, D)
for id, m := range materials {
workersListByID[id] = workersByMat[m]
}
s := 0
edgeBase := 1
matBase := edgeBase + N
t := matBase + D
dinic := NewDinic(t + 1)
sourcePos := make([]int, N)
for e := 0; e < N; e++ {
cap := 0
if mandatory[e] {
cap = 1
}
sourcePos[e] = dinic.AddEdge(s, edgeBase+e, cap)
}
for e := 0; e < N; e++ {
for _, m := range edgeMats[e] {
if id, ok := matID[m]; ok {
dinic.AddEdge(edgeBase+e, matBase+id, 1)
}
}
}
for id := 0; id < D; id++ {
dinic.AddEdge(matBase+id, t, len(workersListByID[id]))
}
flow := dinic.MaxFlow(s, t)
if flow < mandatoryCount {
fmt.Fprintln(out, -1)
return
}
for e := 0; e < N; e++ {
if optional[e] {
dinic.g[s][sourcePos[e]].cap = 1
}
}
flow += dinic.MaxFlow(s, t)
if flow < N-1 {
fmt.Fprintln(out, -1)
return
}
ansU := make([]int, K)
ansV := make([]int, K)
nextWorker := make([]int, D)
for e := 0; e < N; e++ {
edgeNode := edgeBase + e
rev := dinic.g[s][sourcePos[e]].rev
if dinic.g[edgeNode][rev].cap == 0 {
continue
}
matAssigned := -1
for _, ed := range dinic.g[edgeNode] {
if ed.to >= matBase && ed.to < t && dinic.g[ed.to][ed.rev].cap > 0 {
matAssigned = ed.to - matBase
break
}
}
w := workersListByID[matAssigned][nextWorker[matAssigned]]
nextWorker[matAssigned]++
ansU[w] = U[e] + 1
ansV[w] = V[e] + 1
}
for i := 0; i < K; i++ {
fmt.Fprintf(out, "%d %d\n", ansU[i], ansV[i])
}
}