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: # https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/11/ALDS1_11_C
# 実家のような安心感
# 与えられるノード番号についてはすべて0based indexに治す

from collections import deque

# データの入力
N = int(input())
DG = {}
for i in range(N):
    tmp = input().split()
    if int(tmp[1]) != 0:
        DG[i] = [int(x)-1 for x in tmp[2:]]
    else:
        DG[i] = []


result = {}
is_visited = {key: False for key in range(N)}
# bfs
# 初期queue
que = deque([(0, 0)])  # 必要なものはnodeidと原点からの距離
while que:
    nodeid, cost = que.popleft()  # 先入れ先出し
    result[nodeid] = cost
    is_visited[nodeid] = True  # この文は最初の1for目しか意味ないんだけどなんかうまい方法ないのか
    for nextnode in DG[nodeid]:
        if is_visited[nextnode]:
            pass
        else:  # 未訪問のものについては探索候補に入れる
            que.append((nextnode, cost + 1))
            is_visited[nextnode] = True  # 探索候補に入れた瞬間に訪問管理しないと重複を生じる場合がある

for i in range(N):
    if is_visited[i]:
        print(i + 1, result[i])
    else:
        print(i+1, -1)

Python: N= int(input())
E = [input().split()[2:] for _ in range(N)]
frag, T, L,Q = [0]*N, [0]*N, [0]*N, [0]
a,frag[0] = 100, 1
def func(ide):
    for i in E[ide]:
        i = int(i) - 1
        if frag[i] != 1:frag[i] = 1;L[i] = L[ide] +1 ;Q.append(i) 
        else:return

while Q:top = Q[0];func(top);del Q[0]
for i in range(n):
    if L[i] == 0:
        L[i] == -1

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

Python: from collections import deque

N = int(input())

nodes = [tuple(map(int, input().split(' '))) for _ in range(N)]

distances = [-1] * (N + 1)

queue = deque()
queue.append((1, 0))

while len(queue) > 0:
    node, distance = queue.popleft()
    if distances[node] != -1:
        continue
    distances[node] = distance

    neighbors = nodes[node - 1][2:]
    for neighbor in neighbors:
        queue.append((neighbor, distance + 1))

for node in range(1, N + 1):
    print(node, distances[node])

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):
    if dis == inf:
        dis = -1
    print(i, dis)

Python: # coding: utf-8
import queue

q = queue.Queue()
A = [[]*101 for _ in range(101)]
d = [-1]*101
visited = [False]*101

n = int(input().rstrip())
for i in range(n):
    line = [int(j) for j in input().rstrip().split()]
    A[i+1].extend(line[2:])

d[1] = 0

q.put(1)
while not q.empty():
    v = q.get()
    if visited[v] == True:
        continue
    visited[v] = True
    for i in A[v]:
        if d[i] == -1:
            d[i] = d[v] + 1
        else:
            d[i] = min(d[i],d[v] + 1)
        q.put(i)
        
for i in range(n):
    print(str(i+1)+" "+str(d[i+1]))

Python: import queue

n = int(input())

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


# for i in range(n):
#     li = list(map(int, input().split()))
#     a = li[0]
#     a-=1
#     b = li[2:]
#     Graph[a].append(b)


dist = [-1]*n
q = queue.Queue()

dist[0] = 0
q.put(0)

while not q.empty():
    v = q.get()

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

        dist[nv] = dist[v] + 1
        q.put(nv)


for v in range(n):
    print(v+1, dist[v])

Python: INF = 10**18 + 7


def main():
    from collections import deque
    N = int(input())
    G = [[] for _ in range(N)]
    for _ in range(N):
        u, k, *A = (int(i)-1 for i in input().split())
        G[u] = A

    def bfs(s=0):
        que = deque([])
        dist = [INF]*N
        dist[s] = 0
        que.append(s)
        while que:
            pos = que.popleft()
            for v in G[pos]:
                if dist[v] != INF:
                    continue
                dist[v] = dist[pos] + 1
                que.append(v)
        return dist

    dist = bfs()
    for i, d in enumerate(dist, start=1):
        print(i, d if d != INF else -1)


if __name__ == '__main__':
    main()

C++: #include<bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using Graph = vector<vector<int>>;

int main(){
    int n; cin>>n;
    Graph G(n);
    rep(i,n){
        int u,k; cin>>u>>k;
        rep(j,k){
            int v; cin>>v;
            G[u-1].push_back(v-1);
        }
    }

    vector<int> dist(n,-1);
    queue<int> que;

    dist[0]=0;
    que.push(0);

    while(!que.empty()){
        int v = que.front();
        que.pop();

        for(auto nv : G[v]){
            if(dist[nv]!=-1)continue;
            dist[nv] = dist[v] + 1;
            que.push(nv);
        }
    }
    rep(i,n){
        cout<<i+1<<" "<<dist[i]<<endl;
    }
    return 0;
}