Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func nextInt() int {
	n, err := strconv.Atoi(nextString())
	if err != nil {
		fmt.Printf("strconv.Atoi failed: %v\n", err)
	}
	return n
}

func stringifyArray(arr []int) string {
	return strings.TrimRight(fmt.Sprintf("%+v", arr)[1:], "]")
}

var infty = 1000000000

type nodeKey int

type DirectedGraphNode struct {
	key       nodeKey
	adjacents []*DirectedGraphNode
	visited   bool
	d         int
	parent    *DirectedGraphNode
}

type DirectedGraph struct {
	nodes []DirectedGraphNode
}

func (g *DirectedGraph) setAdjacency(l, r nodeKey) {
	g.nodes[l].adjacents = append(g.nodes[l].adjacents, &g.nodes[r])
}

func newDirectedGraph(nNodes int) *DirectedGraph {
	graph := DirectedGraph{}
	graph.nodes = make([]DirectedGraphNode, nNodes)
	for iNodes := 0; iNodes < nNodes; iNodes++ {
		graph.nodes[iNodes].key = nodeKey(iNodes)

		graph.nodes[iNodes].visited = false
		graph.nodes[iNodes].d = infty
		graph.nodes[iNodes].parent = nil
	}
	return &graph
}

type QueueEntry struct {
	node *DirectedGraphNode
	next *QueueEntry
}

type Queue struct {
	head, tail *QueueEntry
}

func (q *Queue) enqueue(node *DirectedGraphNode) {
	entry := QueueEntry{}
	entry.node = node

	if q.tail == nil {
		q.head = &entry
		q.tail = &entry
		return
	}

	q.tail.next = &entry
	q.tail = q.tail.next
}

func (q *Queue) dequeue() *QueueEntry {
	if q.head == nil {
		return nil
	}
	poped := q.head
	q.head = q.head.next
	if q.head == nil {
		q.tail = nil
	}
	return poped
}

func (q *Queue) isEmpty() bool {
	return q.head == nil
}

func fillDistancesByBreadthFirstSearch(g *DirectedGraph, startNode *DirectedGraphNode) {
	startNode.visited = true
	startNode.d = 0

	queue := Queue{}
	queue.enqueue(startNode)
	for !queue.isEmpty() {
		u := queue.dequeue().node
		for _, adjacent := range u.adjacents {
			if !adjacent.visited {
				adjacent.visited = true
				adjacent.d = u.d + 1
				adjacent.parent = u
				queue.enqueue(adjacent)
			}
		}
		u.visited = true
	}
}

func main() {
	scanner.Split(bufio.ScanWords)

	nNodes := nextInt()
	g := newDirectedGraph(nNodes + 1)

	for iNode := 0; iNode < nNodes; iNode++ {
		nodeKeyLeft := nodeKey(nextInt())
		nAdj := nextInt()
		for iAdj := 0; iAdj < nAdj; iAdj++ {
			nodeKeyRight := nodeKey(nextInt())
			g.setAdjacency(nodeKeyLeft, nodeKeyRight)
		}
	}

	// fmt.Println(g)
	fillDistancesByBreadthFirstSearch(g, &g.nodes[1])
	// fmt.Println(g)

	for iNode := 1; iNode <= nNodes; iNode++ {
		node := g.nodes[iNode]
		distance := node.d
		if distance == infty {
			distance = -1
		}
		fmt.Println(node.key, distance)
	}
}

Python: import queue


def bfs(g, s=1):
    global q

    dist = [-1] * len(g)
    dist[1] = 0
    q = queue.Queue()
    q.put(s)

    while not q.empty():
        v = q.get()
        if not G[v][1]:
            continue
        for vi in G[v][2:]:
            if dist[vi] >= 0:
                continue
            q.put(vi)
            dist[vi] = dist[v] + 1

    return dist


n = int(input())
G = [None]
for i in range(n):
    G.append(list(map(int, input().split())))

d = bfs(G)
for i in range(1, n + 1):
    print('%d %d' % (i, d[i]))

Python: import queue
N=int(input())
M=[input().split()[2:]for _ in[0]*N]
q=queue.Queue();q.put(0)
d=[-1]*N;d[0]=0
while q.qsize()>0:
 u=q.get()
 for v in M[u]:
  v=int(v)-1
  if d[v]<0:d[v]=d[u]+1;q.put(v)
for i in range(N):print(i+1,d[i])

Python: # -*- coding: utf-8 -*-

import sys
import os
import math


N = int(input())

E = []
E.append([])
d = [-1] * (N + 1)

for i in range(N):
    lst = list(map(int, input().split()))
    nodes = lst[2:]
    E.append(nodes)
#print(E)

q = []
q.append(1)

visited = [False] * (N + 1)
d[1] = 0
visited[1] = True

while q:
    index = q.pop(0)

    # ???????????????????????´???
    for v in E[index]:
        if not visited[v]:
            q.append(v)
            d[v] = d[index] + 1
            visited[v] = True

#print(d)
for i in range(1, N + 1):
    print(i, d[i])

Python: 
import queue

WHITE = 0
GRAY = 1
BLACK = 2

NIL = -1
INF = 1000000000


def bfs(u):
    global Q
    Q.put(u)
    for i in range(n):
        d[i] = NIL
    d[u] = 0
    while not Q.empty():
        u = Q.get()
        for v in range(n):
            if (m[u][v] == 1) and (d[v] == NIL):
                d[v] = d[u] + 1
                Q.put(v)
n = int(input())

m = [[0 for i in range(n + 1)] for j in range(n + 1)]
vid = [0] * n
d = [0] * n
f = [0] * n
Q = queue.Queue()
color = [WHITE] * n
time = 0
nt = [0] * n

tmp = []
for i in range(n):
    nums=list(map(int,input().split()))
    tmp.append(nums)
    vid[i] = nums[0]

for i in range(n):
    for j in range(tmp[i][1]):
        m[i][vid.index(tmp[i][j + 2])] = 1

bfs(0)

for i in range(n):
    print(vid[i], d[i])

Python: from collections import deque
N = input()
d = [float('inf')] * N
m = [[0] * N for i in range(N)]
Q = deque([])

def bfs(s):
    Q.append(s)
    d[s] = 0

    while(len(Q) != 0):
        u = Q.popleft()
        for v in range(N):
            if (m[u][v] and  d[v] == float('inf')):
                d[v] = d[u] + 1
                Q.append(v)




if __name__ == '__main__':

    for i in range(N):
        v = map(int, raw_input().split())
        for j in v[2:]:
            m[i][j-1] = 1
    
    bfs(0)

    for i in range(N):
        if d[i] == float('inf'):
            d[i] = -1
        print (i+1), d[i]

Python: from collections import deque

N = 100
n = 0
M = None
WHITE = 0
GRAY = 1
BLACK = 2
INF = float('inf')
d = None


def main():
    global n, M, d
    M = [[0 for _ in range(N)] for _ in range(N)]
    n = int(input())
    d = [INF for _ in range(n)]

    for _ in range(n):
        u, k, *v_s = map(int, input().split(' '))
        for j in range(k):
            M[u-1][v_s[j-1]-1] = 1

    bfs()

    for i in range(n):
        print('{} {}'.format(i+1, d[i] if d[i] != INF else -1))


def bfs():
    q = deque()
    q.appendleft(0)
    d[0] = 0

    while len(q) > 0:
        u = q.pop()
        for v in range(n):
            if M[u][v] == WHITE:
                continue
            if d[v] != INF:
                continue
            d[v] = GRAY
            d[v] = d[u] + 1
            q.appendleft(v)


if __name__ == '__main__':
    main()

Python: # -*- coding: utf-8 -*-

import sys
import os
import math

N = int(input())

E = []
E.append([])
d = [None] * (N + 1)

for i in range(N):
    lst = list(map(int, input().split()))
    nodes = lst[2:]
    E.append(nodes)
#print(E)

q = []
q.append(1)

visited = [False] * (N + 1)
d[1] = 0
visited[1] = True

while q:
    index = q.pop(0)

    # ???????????????????????´???
    for v in E[index]:
        if not visited[v]:
            q.append(v)
            d[v] = d[index] + 1
            visited[v] = True

#print(d)
for i in range(1, N + 1):
    print(i, d[i])

Python: import collections
n= int(input())
g=[]
for _ in range(n):
    v,k,*varray= map(int,input().split())
    g.append(varray)
        

d= [-1]* (n+10)
d[0]=0
q= collections.deque()
q.append(0)
while len(q)>  0:
    cur = q.popleft()
    for next in g[cur]:
        if d[next-1]== -1:
            d[next-1]= d[cur]+1
            q.append(next-1)
            
for i in range(n):
    print(i+1,d[i])

Python: n=int(input())
d=[0]+[float('inf')]*(n-1)

v=[[]]*n
for i in range(n):
    tmp=list(map(int,input().split()))
    tmp=[i-1 for i in tmp[2:]]
    v[i]=tmp

que=[0]
while que!=[]:
    m=que.pop(0)
    for i in v[m]:
        if d[i]==float('inf'):
            que.append(i)
            d[i]=d[m]+1
for i in range(n):
    if d[i]==float('inf'):
        d[i]=-1
    print(i+1,d[i])