Go: package main

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

type AdjacentList struct {
	matrix [][]int
}

func NewEmptyAdjacentList(dim int) *AdjacentList {
	matrix := make([][]int, dim)
	for i := 0; i < dim; i++ {
		matrix[i] = make([]int, dim)
	}
	return &AdjacentList{matrix: matrix}
}

func (al *AdjacentList) set(node int, adjacent int) {
	al.matrix[node-1][adjacent-1] = 1
}

func (al *AdjacentList) findAdjacentsFor(node int) []int {
	adjacents := []int{}
	for i, v := range al.matrix[node-1] {
		if v == 1 {
			adjacents = append(adjacents, i+1)
		}
	}
	return adjacents
}

type DistanceList struct {
	list []int
}

func NewDistanceList(dim int) *DistanceList {
	list := make([]int, dim)
	for i := 0; i < dim; i++ {
		list[i] = -1
	}
	return &DistanceList{list: list}
}

func (dl *DistanceList) set(node int, distance int) {
	dl.list[node-1] = distance
}

func (dl *DistanceList) get(node int) int {
	return dl.list[node-1]
}

func (dl *DistanceList) isVisited(node int) bool {
	return dl.list[node-1] >= 0
}

type Position struct {
	node     int
	distance int
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	dim, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	al := NewEmptyAdjacentList(dim)

	for i := 1; i <= dim; i++ {
		node, err := nextInt(sc)
		if err != nil {
			panic(err)
		}

		adjacentNum, err := nextInt(sc)
		if err != nil {
			panic(err)
		}
		for j := 0; j < adjacentNum; j++ {
			adjacent, err := nextInt(sc)
			if err != nil {
				panic(err)
			}
			al.set(node, adjacent)
		}
	}

	dl := NewDistanceList(dim)

	bfs(al, dl)

	for i := 1; i <= dim; i++ {
		fmt.Printf("%d %d\n", i, dl.get(i))
	}
}

func bfs(al *AdjacentList, dl *DistanceList) {
	stack := []Position{Position{node: 1, distance: 0}}
	for len(stack) > 0 {
		currentPosition := stack[0]
		stack = stack[1:]
		if !dl.isVisited(currentPosition.node) {
			dl.set(currentPosition.node, currentPosition.distance)
		}
		for _, v := range al.findAdjacentsFor(currentPosition.node) {
			stack = append(stack, Position{node: v, distance: currentPosition.distance + 1})
		}
	}
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

Python: # vim: set fileencoding=utf-8:
import sys
import collections
INF = 10000000
queue = collections.deque()  # appendleft(), pop()
n = int(input())
graph = [[0] * (n+1) for _ in range(n+1)]
yet = [i for i in range(1, n+1)]
ans = [-1] * (n+1)
for i in range(1, n+1):
    tmp = [int(ele) for ele in input().split()]
    for adjc in tmp[2:]:
        graph[i][adjc] = 1

d = [INF] * (n+1)
d[1] = 0


def main():
    global queue, d
    queue.appendleft(1)
    bfs(queue)
    d = list(map(lambda x: -1 if x == INF else x, d))
    for i in range(1, n+1):
        print(str(i) + " " + str(d[i]))


def bfs(queue):
    global graph, yet
    if len(queue) == 0:
        return

    n = queue[-1]
    yet.remove(n)

    # 各ノードとの隣接状態をみていく
    for i, adjacency in enumerate(graph[n]):
        if adjacency == 1 and i in yet and i not in queue:  # 隣接 かつ 未探索 かつ queueにもない 待ち行列に加える
            queue.appendleft(i)
            # 隣接していれば、自分自身までの最短コストに1を加えたものとの min() を計算する
            d[i] = min(d[i], d[n] + 1)
    else:
        queue.pop()
        bfs(queue)


if __name__ == "__main__":
    main()

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

Python: from collections import deque
n = int(input())

g = [[] for _ in range(n)]
for i in range(n):
    _, _, *edge = map(lambda x: int(x)-1, input().split())

    g[i] = edge

q = deque()
q.append(0)
dist = [-1 for _ in range(n)]
dist[0] = 0

while(len(q) > 0):
    v = q.popleft()

    for nv in g[v]:
        if(dist[nv] != -1): continue
        
        dist[nv] = dist[v] + 1
        q.append(nv)

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

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

def BFS(adj, start):
    n = len(adj)
    d = [-1] * n
    flag = [0] * n
    Q = []

    Q.append(start)
    d[start] = 0
    flag[start] = 1

    while len(Q) != 0:
        u = Q.pop(0)
        v = [i for i, x in enumerate(adj[u]) if (x == 1) and (flag[i] == 0)] # v <= ??£??\???????????????????????¢?´¢??????????????????
        
        for i in v:
            Q.append(i)
            d[i] = d[u] + 1
            flag[i] = 1
    
    return d

def main():
    n = int(input())
    adj = [[0 for i in range(n)] for j in range(n)]
    
    for i in range(n):
        tmp = list(map(int, input().split()))
        u = tmp[0]
        u = u -1
        k = tmp[1]
        v = tmp[2:]
        for j in range(k):
            adj[u][v[j]-1] = 1
    
    d = BFS(adj, 0)
    for i in range(n):
        print(i+1, d[i])


if __name__ == "__main__":
    main()

Python: from collections import deque
N = int(input())
g = {i: deque() for i in range(1,N+1)} #1-index
for i in range(1, N+1):
    u, k, *v = map(int, input().split())
    for j in v:
        g[u].append(j)
        
seen = [0]*(N+1) #1-index
que = deque([])
dist = [-1]*(N+1) #1-index

seen[1] = 1
que.append(1)
dist[1] = 0

while que: #queが空になるまで
    q_no = que.popleft()
    if not g[q_no]: continue #点q-noから他の点に伸びていない
    
    for next_v in g[q_no]:
        if seen[next_v] == 1: continue #訪問済
        
        seen[next_v] = 1 #訪問済にする
        dist[next_v] = dist[q_no] + 1 #距離情報を格納
        que.append(next_v) #queに追加

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

Python: from collections import deque
n=int(input())
l=[0]+[list(map(int,input().split()))[2:] for _ in range(n)]

flg=["white"]*(n+1)
dist=[-1]*(n+1)

def BFS(x):

    queue = deque([x])
    dist[x]=0
    flg[x]="gray"

    while queue:
        current=queue.popleft()
        for i in l[current]:
            if flg[i]=="white":
                queue.append(i)
                flg[i]="gray"
                dist[i]=dist[current]+1
        flg[current]="black"

BFS(1)

for num,i in enumerate(dist[1:],1):
    print(num,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 not q.empty():
 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: cin = open(0).read().strip().split('\n')
n = int(cin[0])
v = [list(map(lambda x: int(x)-1, a.split(' ')[2:])) for a in cin[1:]]

import queue
q = queue.Queue()
q.put(0)

dist = [-1]*n
dist[0] = 0
seen = [False]*n
while not q.empty():
    num = q.get()
    seen[num] = True
    for a in v[num]:
        if dist[a] != -1: continue
        dist[a] = dist[num] + 1
        q.put(a)

for idx, num in enumerate(dist):
    print(idx+1, num)