Go: package main

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

// I/O
type Scanner struct {
	sc *bufio.Scanner
}

func NewScanner() *Scanner {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, 1024), int(1e+9))
	return &Scanner{sc}
}

func (s *Scanner) nextStr() string {
	s.sc.Scan()
	return s.sc.Text()
}

func (s *Scanner) nextInt() int {
	i, e := strconv.Atoi(s.nextStr())
	if e != nil {
		panic(e)
	}
	return i
}

func (s *Scanner) nextFloat() float64 {
	f, e := strconv.ParseFloat(s.nextStr(), 64)
	if e != nil {
		panic(e)
	}
	return f
}

func (s *Scanner) nextRuneSlice() []rune {
	return []rune(s.nextStr())
}

func (s *Scanner) nextIntSlice(n int) []int {
	res := make([]int, n)
	for i := 0; i < n; i++ {
		res[i] = s.nextInt()
	}
	return res
}

func (s *Scanner) nextFloatSlice(n int) []float64 {
	res := make([]float64, n)
	for i := 0; i < n; i++ {
		res[i] = s.nextFloat()
	}
	return res
}

// Arithmetic
func max(nums ...int) int {
	m := nums[0]
	for _, i := range nums {
		if m < i {
			m = i
		}
	}
	return m
}

func min(nums ...int) int {
	m := nums[0]
	for _, i := range nums {
		if m > i {
			m = i
		}
	}
	return m
}

func abs(x int) int {
	if x > 0 {
		return x
	}
	return -x
}

func pow(x, y int) int {
	res := 1
	for i := 0; i < y; i++ {
		res *= x
	}
	return res
}

func ceil(a, b int) int {
	if a%b == 0 {
		return a / b
	} else {
		return a/b + 1
	}
}

// Sort
type RuneSlice []rune

func (a RuneSlice) Len() int           { return len(a) }
func (a RuneSlice) Less(i, j int) bool { return a[i] < a[j] }
func (a RuneSlice) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

// Main
type Queue struct {
	arr []int
}

func (q *Queue) push(v int) {
	q.arr = append(q.arr, v)
}

func (q *Queue) pop() int {
	res := q.arr[0]
	q.arr = q.arr[1:]
	return res
}

func (q *Queue) isEmpty() bool {
	return len(q.arr) == 0
}

func main() {
	sc := NewScanner()
	wtr := bufio.NewWriter(os.Stdout)
	N := sc.nextInt()
	G := make([][]int, N)
	for i := 0; i < N; i++ {
		u, k := sc.nextInt()-1, sc.nextInt()
		for j := 0; j < k; j++ {
			G[u] = append(G[u], sc.nextInt()-1)
		}
	}
	var q Queue
	seen := make([]int, N)
	for i := 0; i < N; i++ {
		seen[i] = -1
	}
	var search func(cur int)
	search = func(cur int) {
		for i := 0; i < len(G[cur]); i++ {
			next := G[cur][i]
			if seen[next] == -1 {
				q.push(next)
				seen[next] = seen[cur] + 1
			}
		}
	}
	q.push(0)
	seen[0] = 0
	for !q.isEmpty() {
		search(q.pop())
	}

	for i := 0; i < N; i++ {
		fmt.Fprintln(wtr, i+1, seen[i])
	}
	wtr.Flush()
}

C++: #include <bits/stdc++.h>

using namespace std;
int graph[125][125];
int d[125];
void bfs(int s, int n){
	queue<int> Q;
	int color[125];	
	for(int i=1;i<=n;i++){
		color[i] =0;
		d[i] = 2e9;
	}
	color[s] = 1;
	d[s] = 0;
	Q.push(s);
	while(Q.size()!=0){
		int u = Q.front();
		Q.pop();
		for(int v=1;v<=n;v++){
			if(graph[u][v] == 0) continue;
			if(color[v] == 0){
				color[v] = 1;
				d[v] = d[u] +1;
				Q.push(v);
			}
		}
		color[u] = 2;
	}
}

int main(){
	int n;
	cin >> n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			graph[i][j] = 0;
		}
	}
	for(int i=1;i<=n;i++){
		int num;
		int k;
		int tmp;
		cin >> num >> k;
		if(k !=0){
			for(int j=0;j<k;j++){
				cin >> tmp;
				graph[num][tmp] = 1;
			}
		}
	}
	bfs(1, n);
	for(int i=1;i<=n;i++){
		cout << i << " "<<((d[i] == 2e9)? (-1) :d[i]) << endl;
	}
}

C++: #define scanf_s scanf
#include <string>
#include <stdio.h>
#include <math.h>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <iostream>
using namespace std;

#define MAX 100
//#define MAX_ 1000
struct Graph
{
	int id, k;
	list<int> node;
	int d = -1;
};
Graph G[MAX];
//int cou = 0;
void Breadth_cou(Graph *g,int cou)
{
	for (auto i = g->node.begin(); i != g->node.end(); ++i) {
		if (G[*i].d == -1 || G[*i].d > cou)
			G[*i].d = cou;	
	}
	g->k = 0;
}
void Breadth(Graph *g)
{
	if (g->k > 0) {
		Breadth_cou(g, g->d + 1);
		for (auto i = g->node.begin(); i != g->node.end(); ++i) {
			Breadth(&G[*i]);
		}
	}
}
int n;
int main(void)
{
	int u, xk, v;//, n;
	scanf_s("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf_s("%d %d", &u, &xk);
		G[u - 1].id = u - 1;
		G[u - 1].k = xk;
		for (int j = 0; j < xk; ++j) {
			scanf_s("%d", &v);
			G[u - 1].node.push_back(v - 1);
		}
	}
	G[0].d = 0;
	Breadth(&G[0]);
	for (int i = 0; i < n; ++i) {
		printf("%d %d\n", G[i].id + 1, G[i].d);
	}
}

C++: #include <stdio.h>
#include <iostream>
#include <queue>
using namespace std;

#define NODE_NUM 100

queue<int> que;

class Node
{
private:
	int next_num;
	int next_node_list[NODE_NUM];
public:
	Node();
	void AddNextNode(int id);
	bool Search(int id);
	int dist;
	int check[NODE_NUM];
};

Node::Node()
{
	next_num = 0;
	dist = -1;
	for (int i = 1; i <= NODE_NUM; i++) {
		check[i] = 0;
	}
}

void Node::AddNextNode(int id)
{
	next_node_list[next_num] = id;
	next_num++;
}

Node Node_list[NODE_NUM + 1];

bool Node::Search(int id)
{
	for (int k = 0; k < next_num; k++) {
		if (Node_list[next_node_list[k]].dist == -1) {
			Node_list[next_node_list[k]].dist = dist + 1;
		}
	}

	for (int i = 0; i < next_num; i++) {
		if (next_node_list[i] == id) return true;
	}
	
	for (int j = 0; j < next_num; j++) {
		if (Node_list[next_node_list[j]].check[id] == 0) {
			Node_list[next_node_list[j]].check[id] = 1;
			que.push(next_node_list[j]);
		}
	}
	
	return false;
}

int main(void)
{
	//input
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		int u, k;
		cin >> u;
		cin >> k;
		Node_list[u] = Node();
		for (int j = 0; j < k; j++) {
			int v;
			cin >> v;
			Node_list[u].AddNextNode(v);
		}
	}
	
	//dist
	Node_list[1].dist = 0;
	for (int i = 2; i <= n; i++) {
		bool ret = Node_list[1].Search(i);
		while (!ret && !que.empty()) {
			ret = Node_list[que.front()].Search(i);
			que.pop();
		};
		while (!que.empty()) {
			que.pop();
		}
	}

	//output
	for (int i = 1; i <= n; i++) {
		cout << i << " " << Node_list[i].dist << "\n";
	}
	
	return 0;
}

C++: #include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <memory>
#include <string>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define MAX 105

struct Vtx{
    int id;
    int path;
    Vtx(){path=id=-1;}
    bool operator <(Vtx &b){
        return id<b.id;
    }
};

Vtx V[MAX];

set<int> adj[MAX];

int n,u,k,v;

void bfs(){
     queue<int> q;
     q.push(1);
     V[1].path=0;
     set<int> e;
     set<int>::iterator it;
     while(!q.empty()){
        e = adj[q.front()];
        it = e.begin();
        while(it!=e.end()){
            if(V[*it].path==-1){
                V[*it].path = V[q.front()].path+1;
                q.push(*it);
            }
            it++;
        }
        q.pop();
     }

}

void print(){
    for(int i=1;i<=n;i++){
        printf("%d %d\n",i,V[i].path);
    }
}


void solve(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&u,&k);
        V[u].id=i;
        for(int j=0;j<k;j++){
            scanf("%d",&v);
            adj[u].insert(v);
        }
    }
    bfs();
    print();
}

int main(){

   // freopen("in","r",stdin);
    solve();
    return 0;
}