Go: package main

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

func getScanner(fp *os.File) *bufio.Scanner {
	scanner := bufio.NewScanner(fp)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 500001), 500000)
	return scanner
}

func getNextString(scanner *bufio.Scanner) string {
	scanner.Scan()
	return scanner.Text()
}

func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}

func main() {
	fp := os.Stdin
	if len(os.Args) > 1 {
		fp, _ = os.Open(os.Args[1])
	}

	scanner := getScanner(fp)
	writer := bufio.NewWriter(os.Stdout)

	n := getNextInt(scanner)
	nodes := make([]Node, n)

	for i := 0; i < n; i++ {
		nodes[i].list = make([]int, 0)
		nodes[i].d = -1
	}

	for i := 0; i < n; i++ {
		u := getNextInt(scanner)
		k := getNextInt(scanner)
		u--
		for ii := 0; ii < k; ii++ {
			v := getNextInt(scanner)
			v--
			nodes[u].list = append(nodes[u].list, v)
		}
	}

	queue := make([]int, n)
	queue[0] = 0
	nodes[0].d = 0
	d := 0
	i, j := 0, 1
	for i < j {
		d++
		prev := j
		for i < prev {
			for k, l := 0, len(nodes[queue[i]].list); k < l && i < n; k++ {
				if nodes[nodes[queue[i]].list[k]].d != -1 {
					continue
				}
				nodes[nodes[queue[i]].list[k]].d = d
				queue[j] = nodes[queue[i]].list[k]
				j++
			}
			i++
		}
	}

	for i := 0; i < n; i++ {
		fmt.Fprintln(writer, fmt.Sprintf("%d %d", i+1, nodes[i].d))
	}

	writer.Flush()
}

// Node ...
type Node struct {
	list []int
	d    int
}

Python: import sys, os, math, bisect, itertools, collections, heapq, queue, copy, array

# from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall
# from decimal import Decimal
# from collections import defaultdict, deque

sys.setrecursionlimit(10000000)

ii = lambda: int(sys.stdin.buffer.readline().rstrip())
il = lambda: list(map(int, sys.stdin.buffer.readline().split()))
fl = lambda: list(map(float, sys.stdin.buffer.readline().split()))
iln = lambda n: [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)]

iss = lambda: sys.stdin.buffer.readline().decode().rstrip()
sl = lambda: list(map(str, sys.stdin.buffer.readline().decode().split()))
isn = lambda n: [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)]

lcm = lambda x, y: (x * y) // math.gcd(x, y)

MOD = 10 ** 9 + 7
MAX = float('inf')


def main():
    if os.getenv("LOCAL"):
        sys.stdin = open("input.txt", "r")

    N = ii()
    visited = [-1] * N
    G = [[False] * N for _ in range(N)]
    for n in range(N):
        u, k, *V = il()
        for v in V:
            G[n][v - 1] = True

    que = queue.Queue()
    que.put(0)
    visited[0] = 0
    while not que.empty():
        now = que.get()
        for n in range(N):
            if G[now][n] and visited[n] == -1:
                visited[n] = visited[now] + 1
                que.put(n)

    for n in range(N):
        print(n + 1, visited[n])


if __name__ == '__main__':
    main()

Python: from collections import deque
n = int(input())
graph = [[] for _ in range(n)]
global Q, S, T
global visited, dis
Q = deque([0])
S = [0] #訪れた順
T = []
visited = [0 for _ in range(n)]
dis = [-1 for _ in range(n)] #初めからの距離
dis[0] = 0
def input_graph(n):
  for _ in range(n):
    node_id, num, *v = list(map(int, input().split()))
    for i in range(num):
      graph[node_id-1].append(v[i]-1)

def bfs(node_id):
  global Q, S
  while Q:
    node_id = Q.popleft()

    for ad_node in graph[node_id]:
      if visited[ad_node] == 1:
        continue
      visited[ad_node] = 1
      dis[ad_node] = dis[node_id] + 1
      S.append(ad_node)
      Q.append(ad_node)

if __name__ == "__main__":
  input_graph(n)
  bfs(0)
  for i, d in enumerate(dis):
    print(i+1, d)

Python: #!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
4
1 2 2 4
2 1 4
3 0
4 1 3

output:
1 0
2 1
3 2
4 1
"""

import sys
from collections import deque

UNVISITED, VISITED_IN_QUEUE, POPPED_OUT = 0, 1, 2


def graph_bfs(v_init):
    queue = deque()
    status[v_init] = VISITED_IN_QUEUE
    distance[v_init] = 0
    queue.appendleft(v_init)

    while queue:
        current = queue.popleft()
        for adj in adj_table[current]:
            if status[adj] is UNVISITED:
                status[adj] = VISITED_IN_QUEUE
                distance[adj] = distance[current] + 1
                queue.append(adj)
        status[current] = POPPED_OUT
    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    v_num = int(_input[0])
    vertices = list(map(lambda x: x.split(), _input[1:]))
    # assert len(vertex_info) == vertex_num

    status = [UNVISITED] * (v_num + 1)
    distance = [-1] * (v_num + 1)

    adj_table = tuple([] for _ in range(v_num + 1))
    for v_info in vertices:
        v_index, adj_num, *adj_list = map(int, v_info)
        # assert len(adj_list) == adj_num
        adj_table[v_index].extend(adj_list)

    graph_bfs(v_init=1)
    for index, v in enumerate(distance[1:], 1):
        print(index, v)

Python: #!/usr/bin/python3

def find(id, V, d, dist):
    i = id - 1
    dist[i] = d
    for v in V[i]:
        if dist[v - 1] == -1:
            find(v, V, d + 1, dist)
    
n = int(input())
# [isFind, d, f]
A = [[False, 0, 0] for i in range(n)]
U = []
V = []
dist = [-1] * n
for i in range(n):
    l = list(map(int, input().split()))
    U.append(l[0])
    V.append(l[2:])

find(1, V, 0, dist)

for u in U:
    print(u, dist[u - 1])

Python: import queue
from collections import namedtuple
T = namedtuple("T", "u d")

n = int(input())
path = dict()
ans = [-1] * (n + 1)

for i in range(n):
    a = [int(x) for x in input().split()]
    a.reverse()

    u, k = a.pop(), a.pop()
    path[u] = set()
    for j in range(k):
        path[u].add(a.pop())


def bfs(s):
    q = queue.Queue()
    q.put(s)

    while q.qsize() != 0:
        p = q.get()
        if p.d < ans[p.u] or ans[p.u] < 0:
            ans[p.u] = p.d
            for r in path[p.u]:
                q.put(T(r, p.d + 1))


bfs(T(1, 0))
for i in range(1, n + 1):
    print(i, ans[i])