Go: package main

/*
グラフの表現 隣接行列による表現
*/

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

func main() {
	scanner := makeScanner(8192)
	n := eGetInt(scanner)
	g := make([][]int, n+1)
	for i := 1; i < n+1; i++ {
		g[i] = make([]int, n+1)
		ints := eGetInts(scanner)
		num := ints[0]
		for j := 0; j < ints[1]; j++ {
			g[num][ints[j+2]] = 1
		}
	}
	dist := make([]int, n+1)
	for i := 0; i < len(dist); i++ {
		dist[i] = -1
	}
	q := []int{}

	// 訪問する
	q = append(q, 1)
	dist[1] = 0

	// キューが空でない限り
	for len(q) > 0 {
		// 先頭を取り出す
		top := 0
		top, q = q[0], q[1:]
		// 隣接マスを入れる.
		for i := 1; i < n+1; i++ {
			// 辺がある
			if g[top][i] == 1 {
				if dist[i] == -1 {
					// 訪問済みでなければ
					q = append(q, i)
					dist[i] = dist[top] + 1
				}
			}
		}
	}
	for i := 1; i < n+1; i++ {
		fmt.Println(i, dist[i])
	}
}

////////////////////////////////////////////////////////////////////////////////
// ライブラリ
////////////////////////////////////////////////////////////////////////////////
func makeScanner(maxByte int) *bufio.Scanner {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Buffer(make([]uint8, 0, 8192), maxByte)
	return scanner
}
func makeWordScanner() *bufio.Scanner {
	scanner := makeScanner(8192)
	scanner.Split(bufio.ScanWords)
	return scanner
}
func eGetLine(r *bufio.Scanner) string {
	if r.Scan() {
		return r.Text()
	}
	err := r.Err()
	if err != nil {
		log.Fatal(err)
	}
	// EOF
	return ""
}
func eGetInt(r *bufio.Scanner) int {
	line := eGetLine(r)
	return eAtoi(line)
}
func eGetInt64(r *bufio.Scanner) int64 {
	line := eGetLine(r)
	return eAtoInt64(line)
}
func eGetFields(r *bufio.Scanner) []string {
	line := eGetLine(r)
	return strings.Fields(line)
}
func eGetInts(r *bufio.Scanner) []int {
	fields := eGetFields(r)
	ints := make([]int, len(fields))
	for i := 0; i < len(ints); i++ {
		ints[i] = eAtoi(fields[i])
	}
	return ints
}
func eGetInt64s(r *bufio.Scanner) []int64 {
	fields := eGetFields(r)
	ints := make([]int64, len(fields))
	for i := 0; i < len(ints); i++ {
		ints[i] = eAtoInt64(fields[i])
	}
	return ints
}
func eGetChars(r *bufio.Scanner) []string {
	line := eGetLine(r)
	return strings.Split(line, "")
}
func eAtoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		log.Fatal(err)
	}
	return n
}
func eAtoInt64(s string) int64 {
	n, err := strconv.ParseInt(s, 10, 64)
	if err != nil {
		log.Fatal(err)
	}
	return n
}

Python: from collections import deque

n = int(input())
vdata = [list(map(int,input().split())) for _ in range(n)]
d = [-1]*n
q = deque()
q.append(vdata[0])
d[0] = 0

while len(q) > 0:
  node = q.popleft()
  c = d[node[0]-1]
  a = node[1]
  for i in range(a):
    b = node[i+2]-1
    if d[b] == -1:
      d[b] = c+1
      q.append(vdata[b])
      
for i in range(n):
  print(i+1, d[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)]
d = [99999 for i in range(n)]
d[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 d[k] > d[s]+1:
         d[k] = d[s]+1
         bfs_visit(k)
 
for s in range(n):
    bfs_visit(s)
for s in range(s):
    if d[s] == 99999:
       d[s] = -1
for s in range(n):
    print (s+1,d[s])

Python: from collections import deque
def MAIN():
    n = int(input())
    li = [[] for _ in range(n + 1)]
    ans = [[i, -1] for i in range(n + 1)]
    ans[1][1] = 0
    for _ in range(n):
        u, k, *v = map(int, input().split())
        li[u] = v
    dp = deque([1])
    while dp:
        u = dp.popleft()
        for v in li[u]:
            if ans[v][1] == -1:
                ans[v][1] = ans[u][1] + 1
                dp.append(v)
    for d in ans[1:]:
        print(*d)
MAIN()

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

n = int(input())
graph = {i: deque() for i in range(1, n+1)}

for i in range(n):
    u, k, *v = map(int, input().split())
    v.sort()
    for vi in v:
        graph[u].append(vi)

seen = [0]*(n+1)
queue = deque()
dist = [-1]*(n+1)
def bfs(v):
    dist[v] = 0
    seen[v] = 1
    queue.append(v)
    while queue:
        q = queue[0]
        if not graph[q]:
            queue.popleft()
            continue
        g = graph[q].popleft()
        if seen[g]:
            continue
        seen[g] = 1
        dist[g] = dist[q] + 1
        queue.append(g)

bfs(1)
for id, d in enumerate(dist):
    if id == 0:
        continue
    print(id, d)

Python: from collections import deque
from enum import Enum, auto

class Color(Enum):
    WHITE = auto()
    GRAY = auto()
    BLACK = auto()

n = int(input())
d = [0 for i in range(n)]
f = [0 for i in range(n)]

colors = [] # 頂点の訪問状態
A = [[0 for j in range(n)] for i in range(n)] # 隣接行列
queue = deque([])

# 隣接行列の初期化
for i in range(n):
    arr = list(map(int, input().split(' ')))
    u, k, v = arr[0], arr[1], arr[2:]
    for j in range(k):
        A[u-1][v[j]-1] = 1

def bfs():
    global colors, queue, d
    colors = [Color.WHITE for i in range(n)]
    d = [-1 for i in range(n)] # INF

    colors[0] = Color.GRAY
    d[0] = 0
    queue.append(0)

    while len(queue) > 0:
        u = queue.pop()
        for v in range(n):
            if A[u][v] == 1 and colors[v] == Color.WHITE:
                colors[v] = Color.GRAY
                d[v] = d[u] + 1
                queue.append(v)
        colors[u] = Color.BLACK

bfs()

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

Python: import collections

n=int(input())
adj=[]
for i in range(n):
      adj.append(list(map(int, input().split())))

Q=[]
Q=collections.deque()
Q.append(0)

D=[-1 for i in range(n)]
D[0]=0

while len(Q)>0:
    current=Q.popleft()
    for dst in range(n):
        for i in range(2,len(adj[current])):
            if adj[current][i]==dst+1 and D[dst]==-1:
                D[dst]=D[current]+1
                Q.append(dst)
for i in range(n):
    print(i+1,D[i])

Python: from collections import deque
import sys


def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())


class Graph:
    def __init__(self, n, is_directed=False):
        """
        :param n: 頂点数
        :param is_directed: 有向グラフ(True)か無向グラフか(False)
        """
        self.n = n
        self.graph = [[] for _ in range(n)]
        self.is_directed = is_directed

    def add_edge(self, u, v):
        """uからvへの(有向な)辺をつなぐ"""
        self.graph[u].append(v)
        if not self.is_directed:
            self.graph[v].append(u)

    def search(self, start, mode):
        '''開始地点から各頂点まで幅/深さ優先探索を行って得られた距離のリストを返す
        Args:
          start(int): 開始地点となる頂点
          mode(str): 幅優先探索(b)か深さ優先探索(d)を指定

        Returns:
          List[int]: 開始地点からの距離(未到達の場合は-1)
        '''
        dists = [-1] * self.n
        que = deque([start])
        dists[start] = 0
        if mode == 'b':
            get_v = que.popleft
        else:
            get_v = que.pop
        while que:
            now_v = get_v()
            for next_v in self.graph[now_v]:
                if dists[next_v] != -1:
                    continue
                que.append(next_v)
                dists[next_v] = dists[now_v] + 1
        return dists


n = I()
g = Graph(n, is_directed=True)
for _ in range(n):
    u, k, *v = LI()
    u -= 1
    if v == []:
        continue
    for vi in v:
        vi -= 1
        g.add_edge(u, vi)
res = g.search(0, 'b')
for i in range(n):
    print(i + 1, res[i])