Go: package main

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

var distance []int

type queue struct {
	q    []int
	head int
	tail int
}

func (q *queue) push(n int) {
	q.q[q.tail] = n
	q.tail++
}

func (q *queue) pop() int {
	q.head++
	return q.q[q.head-1]
}

func (q *queue) isEmpty() bool {
	return q.head == q.tail
}

func makeAdjList() [][]int {
	var n int
	fmt.Scanf("%d", &n)

	adj := make([][]int, n)
	for i := 0; i < n; i++ {
		adj[i] = make([]int, n)
	}

	sc := bufio.NewScanner(os.Stdin)
	for i := 0; i < n; i++ {
		sc.Scan()
		nodeInfo := strings.Split(sc.Text(), " ")
		outDegree, _ := strconv.Atoi(nodeInfo[1])

		if outDegree > 0 {
			for k := 0; k < outDegree; k++ {
				j, _ := strconv.Atoi(nodeInfo[k+2])
				j-- // convert 1 based to 0 based
				adj[i][j] = 1
			}
		}
	}

	return adj
}

func bfs(graph [][]int, s int) {
	distance = make([]int, len(graph))

	infty := -1
	for i := 0; i < len(distance); i++ {
		distance[i] = infty
	}
	distance[s] = 0

	q := &queue{make([]int, 1000), 0, 0}
	q.push(s)

	for !q.isEmpty() {
		u := q.pop()
		for i := 0; i < len(graph); i++ {
			if graph[u][i] == 0 {
				continue // u, i間に辺がない場合
			}
			if distance[i] != infty {
				continue // 訪問済みの場合
			}
			// 訪問するnodeの始点からの距離を設定し、訪問キューに入れる
			distance[i] = distance[u] + 1
			q.push(i)
		}
	}

	// print distance
	for i, d := range distance {
		fmt.Printf("%d %d\n", i+1, d)
	}
}

func main() {
	adj := makeAdjList()
	bfs(adj, 0)
}

Python: n = int(input())
a = [[] for i in range(n)]

for i in range(n):
    v = list(map(int, input().split()))
    u = v[0] - 1
    for j in v[2:]:
        a[u].append(j-1)

d = [-1] * n
isDiscovered = [False] * n

def bfs(x):
    for i in a[x]:
        if not isDiscovered[i]:
            isDiscovered [i] = True
            d[i] = d[x] + 1

d_ = 0
isDiscovered [0] = True
d[0] = 0
bfs(0)

flag = True
while flag:
    flag = False
    for i in range(n):
        if d[i] is d_ :
            flag = True
            bfs(i)
    d_ += 1

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

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()
    visited[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 visited[adj] is UNVISITED:
                visited[adj] = VISITED_IN_QUEUE
                distance[adj] = distance[current] + 1
                queue.append(adj)
        visited[current] = POPPED_OUT
    return None


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

    visited = [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: 
def bfs(s):  # たぶんstartのs
    global n, M, color, d, q

    q.append(s)
    d[s] = 0

    while len(q) != 0:
        u = q.pop(0)

        for v in range(n):
            if M[u][v] != 1:
                continue

            if color[v] == 'WHITE':
                q.append(v)
                color[v] = 'GRAY'
                d[v] = d[u] + 1

        color[u] = 'BLACK'


n = int(input())

M = [[0 for i in range(n)] for j in range(n)]
color = ['WHITE'] * n  # 各頂点の色を記録。ホワイト（未探索）、グレイ（探索中）、ブラック（探索ずみ）
d = [-1] * n  # 始点0からvまでの距離
q = []

for i in range(n):
    _ = list(map(int, input().split()))
    u = _[0] - 1  # 0オリジンに変換

    degree = _[1]
    for j in range(degree):
        v = _[j+2] - 1  # 0オリジンに変換
        M[u][v] = 1

# for row in M:
#     print(' '.join(map(str, row)))

bfs(0)

for i in range(n):
    print('{} {}'.format(i+1, d[i]))

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: n = int(raw_input())
 
G = [0 for i in range(n)] 
a = [[0 for i in range(n)] for j in range(n)]
dis = [1000 for i in range(n)]
dis[0] = 0

for i in range(n):
    G = map(int, raw_input().split())
    for j in range(G[1]):
        a[G[0]-1][G[2+j]-1] = 1
 
def bfs_visit(s):
    for k in range(n):
      if a[s][k] == 1:
       if dis[k] > dis[s] + 1:
         dis[k] = dis[s] + 1
         bfs_visit(k)

for s in range(n):
    bfs_visit(s)
for s in range(n):
    if dis[s] == 1000:
       dis[s] = -1
for s in range(n):
    print (s+1,dis[s])

Python: from collections import deque
N = int(input())
#グラフ入力受取
G = [[] for _ in range(N)]
for _ in range(N):
    a = list(map(int, input().split()))
    for i in a[2:]:
        G[a[0]-1].append(i-1)

#頂点1をスタートとした探索
dist = [-1]*N
que = deque()
dist[0] = 0
que.append(0)
while len(que)!=0:
    v = que.popleft()
    for nv in G[v]:
        if dist[nv] == -1:
            dist[nv] = dist[v]+1
            que.append(nv)
        
for i in range(N):
    print(str(i+1) + ' ' + str(dist[i]))

Python: from collections import deque


INFINITY = 10 ** 10
WHITE = 0
GRAY = 1
BLACK = 2


def breadth_first_search(u_start = 0):
    color[u_start] = GRAY
    d[u_start] = 0
    que.append(u_start)

    while que:
        u = que.popleft()
        for v in range(n):
            if matrix[u][v] and color[v] == WHITE:
                color[v] = GRAY
                d[v] = d[u] + 1
                que.append(v)
        color[u] = BLACK


# INPUT
n = int(input())


matrix = [[0] * n for _ in range(n)]

for i in range(n):

    u, k, *V = map(int, input().split())

    for v in V:
        v -= 1
        matrix[i][v] = 1


color = [WHITE] * n
d = [INFINITY] * n
que = deque([])

# PROCESS
breadth_first_search()


# OUTPUT
for i in range(n):
    if d[i] == INFINITY:
        distance = -1
    else:
        distance = d[i]

    print(i + 1, 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]))