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: # -*- coding: utf-8 -*-

import sys
from collections import deque

sys.setrecursionlimit(10 ** 9)
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
INF=float('inf')

N=INT()
nodes=[[] for i in range(N)]
for i in range(N):
    l=LIST()
    u=l[0]
    l=l[2:]
    for v in l:
        nodes[u-1].append(v-1)
    nodes[u-1].sort()

que=deque()
que.append((0, 0))
costs=[-1]*N
while len(que):
    cost,node=que.popleft()
    if costs[node]==-1:
        costs[node]=cost
        for v in nodes[node]:
            que.append((cost+1, v))

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

Python: N = int(input())
E = [[] for _ in range(N+1)]
for _ in range(N):
	tmp = list(map(int, input().split()))
	if tmp[1] == 0:
		continue
	E[tmp[0]] = tmp[2:]

cnt = [0 for _ in range(N+1)]
q = [1]

while q:
	cp = q.pop(0)
	for np in E[cp]:
		if cnt[np] != 0:
			continue
		
		cnt[np] = cnt[cp] + 1
		q.append(np)

for ind, cost in enumerate(cnt):
	if ind == 0:
		continue
	if ind == 1:
		print(ind, 0)
	else:
		if cost == 0:
			print(ind, -1)
		else:
			print(ind, cost)

Python: #coding: utf-8
inf = 100000000
n = int(input())

List = [0] + [list(map(int,input().split())) for i in range(n)]
color = [0] + ["white" for  i in range(n)]
d = [inf for i in range(n+1)]

s = 1
Q = [s]
d[s] = 0
while Q != []:
    q = Q.pop()
    if color[q] == "white":
        k = List[q][1]
        if k != 0:
            Q += List[q][2:2+k]
            for i in List[q][2:2+k]:
                d[i] = min(d[q] + 1, d[i])
    
    color[q] = "black"


for i, dis in enumerate(d[1:], 1):
    print(i, dis)

Python: from collections import deque

N = int(input())
nodes = []
G ={}
is_visited = {}
q = deque()

for _ in range(N):
    lst = list(map(int, input().split()))
    idx = lst[0]
    nodes.append(idx)
    is_visited[idx] = False
    degree = lst[1]
    if degree > 0:
        G[idx] = lst[2:]
    else:
        G[idx] = []

INF = 10**12
costs = [INF]*N
# bfs
# 初期queue
que = deque()  # 必要なものはnodeidと原点からの距離
que.append(1)
costs[0] = 0
while que:
    node_id = que.popleft()  # 先入れ先出し
    cost = costs[node_id-1]
    for next_id in G[node_id]:
        if (costs[next_id-1] == INF):
            que.append(next_id)
            costs[next_id-1] = cost + 1
        
for i in range(N):
    if costs[i] != INF:
        print(i+1, costs[i])
    else:
        print(i+1, -1)

Python: from collections import deque


def bfs(start):
    Q = deque()
    Q.append(start)
    dist[start] = 0

    while Q:
        v = Q.popleft()

        for nv in G[v]:
            if dist[nv] != -1:
                continue

            # print(Q)
            dist[nv] = dist[v] + 1
            Q.append(nv)


N = int(input())

G = [[]] + [list(map(int, input().split())) for _ in range(N)]
for a in range(1, N + 1):
    b = G[a][2:]
    G[a] = b

# print(G)
dist = [-1 for _ in range(N + 1)]

start = 1
bfs(start)
# print(dist[1:])
for i in range(1, N + 1):
    print(i, dist[i])

Python: from queue import Queue

n = int(input())
A = [[0 for i in range(n)] for j in range(n)]
d = [-1 for i in range(n)]

for i in range(n):
    u, k, *v = list(map(int, input().split()))
    for j in v:
        A[int(u)-1][int(j)-1] = 1

q = Queue()
q.put(0)
d[0] = 0

while not q.empty():
    u = q.get()
    # print('visited:', u)
    for v in range(n):
        # print(u, v)
        if A[u][v] == 1 and d[v] == -1:
            q.put(v)
            d[v] = d[u] + 1

# print('-========')
for i in range(n):
    print(i, d[i])

Python: import sys
input = sys.stdin.readline
from collections import deque

def main():
	n = int(input().strip())
	v = [[] for _ in range(n)]
	for i in range(n):
		v[i] = list(map(int, input().strip().split()))
	l = [-1] * (n+1)
	q = deque()
	q.append((1, 0))
	while len(q) != 0:
		id, d = q.popleft()
		# print("id", id)
		if l[id] != -1:
			# print("b")
			continue
		l[id] = d
		# l[id] = min(d, l[id])
		# print(id, d)
		for i in range(v[id-1][1]):
			q.append((v[id-1][2+i], d+1))
			# if id == 8:
				# print("##", id, v[id-1][2+i])
				# print(repr(q))
	for i in range(1, n+1):
		print(i, l[i])

if __name__ == '__main__':
	main()

Python: from sys import stdin
from collections import deque
n = int(input())
d = [-1] * (n + 1)
G = [0] + [list(map(int, input().split()[2:])) for _ in range(n)]
def bfs():
    d[1] = 0
    dq = deque([1])
    while len(dq) != 0:
        v = dq.popleft()
        for c in G[v]:
            if d[c] == -1 :
                d[c] = d[v] + 1
                dq.append(c)
    for i, x in enumerate(d[1:], start=1):
        print(i, x)
bfs()

Python: from collections import deque

N = int(input())
graph = [[] for _ in range(N)]
for i in range(N):
  X = list(map(int, input().split()))
  for j in range(2, len(X)):
    graph[i].append(X[j]-1)
    
dist = [-1] * N
dist[0] = 0

q = deque([])
q.append(0)

while q:
  x = q.popleft()
  for next_x in graph[x]:
    if(dist[next_x] > -1):
      continue
    dist[next_x] = dist[x] + 1
    q.append(next_x)
    
for i in range(N):
  print(i+1, dist[i])