Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func nextInt() int {
	n, err := strconv.Atoi(nextString())
	if err != nil {
		fmt.Printf("strconv.Atoi failed: %v\n", err)
	}
	return n
}

func stringifyArray(arr []int) string {
	return strings.TrimRight(fmt.Sprintf("%+v", arr)[1:], "]")
}

var infty = 1000000000

type nodeKey int

type DirectedGraphNode struct {
	key       nodeKey
	adjacents []*DirectedGraphNode
	visited   bool
	d         int
	parent    *DirectedGraphNode
}

type DirectedGraph struct {
	nodes []DirectedGraphNode
}

func (g *DirectedGraph) setAdjacency(l, r nodeKey) {
	g.nodes[l].adjacents = append(g.nodes[l].adjacents, &g.nodes[r])
}

func newDirectedGraph(nNodes int) *DirectedGraph {
	graph := DirectedGraph{}
	graph.nodes = make([]DirectedGraphNode, nNodes)
	for iNodes := 0; iNodes < nNodes; iNodes++ {
		graph.nodes[iNodes].key = nodeKey(iNodes)

		graph.nodes[iNodes].visited = false
		graph.nodes[iNodes].d = infty
		graph.nodes[iNodes].parent = nil
	}
	return &graph
}

type QueueEntry struct {
	node *DirectedGraphNode
	next *QueueEntry
}

type Queue struct {
	head, tail *QueueEntry
}

func (q *Queue) enqueue(node *DirectedGraphNode) {
	entry := QueueEntry{}
	entry.node = node

	if q.tail == nil {
		q.head = &entry
		q.tail = &entry
		return
	}

	q.tail.next = &entry
	q.tail = q.tail.next
}

func (q *Queue) dequeue() *QueueEntry {
	if q.head == nil {
		return nil
	}
	poped := q.head
	q.head = q.head.next
	if q.head == nil {
		q.tail = nil
	}
	return poped
}

func (q *Queue) isEmpty() bool {
	return q.head == nil
}

func fillDistancesByBreadthFirstSearch(g *DirectedGraph, startNode *DirectedGraphNode) {
	startNode.visited = true
	startNode.d = 0

	queue := Queue{}
	queue.enqueue(startNode)
	for !queue.isEmpty() {
		u := queue.dequeue().node
		for _, adjacent := range u.adjacents {
			if !adjacent.visited {
				adjacent.visited = true
				adjacent.d = u.d + 1
				adjacent.parent = u
				queue.enqueue(adjacent)
			}
		}
		u.visited = true
	}
}

func main() {
	scanner.Split(bufio.ScanWords)

	nNodes := nextInt()
	g := newDirectedGraph(nNodes + 1)

	for iNode := 0; iNode < nNodes; iNode++ {
		nodeKeyLeft := nodeKey(nextInt())
		nAdj := nextInt()
		for iAdj := 0; iAdj < nAdj; iAdj++ {
			nodeKeyRight := nodeKey(nextInt())
			g.setAdjacency(nodeKeyLeft, nodeKeyRight)
		}
	}

	// fmt.Println(g)
	fillDistancesByBreadthFirstSearch(g, &g.nodes[1])
	// fmt.Println(g)

	for iNode := 1; iNode <= nNodes; iNode++ {
		node := g.nodes[iNode]
		distance := node.d
		if distance == infty {
			distance = -1
		}
		fmt.Println(node.key, distance)
	}
}

C++: #include<bits/stdc++.h>
using namespace std;

struct{
	int link;
	int stg;
}typedef LinkStage;

class Vertex{
	private:
		int* links;
		int index;
		int num;
		bool arrived;
		int id;
		int d;
	public:
		Vertex(int u,int k):id(u), num(k),links(new int[k]),index(0),arrived(false),d(-1){}
		void addLink(int);
		void enQueueLinks(queue<LinkStage>*,int);	
		void print();
};

void Vertex::addLink(int link){
	links[index] = link - 1;
	index++;
}

void Vertex::enQueueLinks(queue<LinkStage>* taskQueue,int dist){
	if(arrived)
		return;

	for(int i = 0; i < index;i++){
		LinkStage stage;
		stage.link = links[i];
		stage.stg = dist + 1;
		taskQueue->push(stage);
	}
	arrived = true;
	d = dist;
}

void Vertex::print(){
	cout << id << " " << d << endl;
}

int main(){
	int n;
	cin >> n;
	Vertex** vertexes = new Vertex*[n];
	for(int i = 0;i < n;i++){
		int u;
		cin >> u;
		int k;
		cin >> k;
		Vertex* vertex = new Vertex(u,k);
		for(int j = 0;j < k;j++){
			int v;
			cin >> v;
			vertex->addLink(v);
		}
		vertexes[u - 1] = vertex;
	}
	queue<LinkStage> task;
	vertexes[0]->enQueueLinks(&task,0);
	while(!task.empty()){
		LinkStage curr = task.front();
		task.pop();
		int nextI = curr.link;
		int d = curr.stg;
		vertexes[nextI]->enQueueLinks(&task,d);
	}
	for(int i = 0; i < n;i++){
		vertexes[i]->print();
	
	}
	
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <queue>
using namespace std;

int n;
vector<vector<int> > G;
vector<int> D;

void bfs(int src){
    queue<int> Q;
    Q.push(src);
    D[src] = 0; // ?????????
    while(!Q.empty()){
        int cur = Q.front(); // ??????????´???????????????????
        Q.pop();
        for(int dst = 0; dst < n; ++dst){ // ???????????? dst ????????????
            if(G[cur][dst] == 1 && D[dst] == -1){ // cur??????dst???????????????,dst???????¨??????????
                D[dst] = D[cur] + 1;
                Q.push(dst); // dst????¨??????????????????????
            }
        }
    }
}

int main(){
    cin >> n;
    G = vector<vector<int> >(n, vector<int>(n, 0));
    D = vector<int>(n, -1);
    for(int i=0; i<n; ++i){
        int u;
        cin >> u;
        // 1~n???index?????¨????????????????????????????????????1????????????0~n-1????????????
        u -= 1;
        int k;
        cin >> k;
        for(int j=0; j<k; ++j){
            int v;
            cin >> v;
            v -= 1;
            G[u][v] = 1;
        }
    }
    bfs(0);
    for(int i=0; i<n; ++i){
        cout << i+1 << " " << D[i] << endl;
    }
}

C++: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
#define pd(a,n) for(int i=0;i<n;i++)cout<<a[i]<<((i==n-1)?"\n":" ");cout<<endl;
#define pdd(a,n,m)for(int i=0;i<n;i++){for(int j=0;j<m;j++)cout<<a[i][j]<<" ";cout<<endl;}
#define mp make_pair
#define pb push_back
#define ll long long
//#define __int64 lng long
#define P pair<int,int>
#define PP pair<P,int>

vector<int>G[111];
int dist[111];
int n;

int main(){
  cin>>n;
  rep(i,n)dist[i]=-1;

  rep(i,n){
    int a,k;
    cin>>a>>k;
    a--;
    rep(i,k){
      int x;
      cin>>x;
      x--;
      G[a].pb(x);
    }
    sort(G[a].begin(),G[a].end());
  }
  queue<P>bfs;
  bfs.push(mp(0,0));

  while(!bfs.empty()){
    int now=bfs.front().first;
    int cost=bfs.front().second;
    bfs.pop();
    if(dist[now]!=-1)
      continue;
    dist[now]=cost;
    for(int i=0;i<G[now].size();i++){
      int next=G[now][i];
      bfs.push(mp(next,cost+1));
    }
  }
  rep(i,n)cout<<i+1<<" "<<dist[i]<<endl;
  return 0;
}

C++: #include <cmath>
#include <queue>
#include <iostream>
using namespace std;

int G[110][110] = {0};
int n;
int D[110] = {0};
void bfs(int src){
 queue<int> Q;
 Q.push(src);
 D[src] = 0;
 while(! Q.empty()){
  int cur = Q.front();
  Q.pop();
  for(int i=1; i<=n; i++){
   if(G[cur][i]==1 && D[i]==0){
    D[i] = D[cur]+1;
    Q.push(i);
   }
  }
 }

 for(int i=1; i<=n; i++){
  if(i!=1 && D[i]==0 && i!=1){
   D[i]=-1;
  }
  cout << i << " " << D[i] << endl;
 }
}

int main(){
 cin >> n;
 int u, k;
 int v[100000];
 for(int i=0; i<n; i++){
  cin >> u >> k;
  for(int j=0; j<k; j++){
   cin >> v[j];
   G[i+1][v[j]] = 1;
  }
 }
 bfs(1);
}

C++: #include<iostream>
#include<queue>
#include<vector>
using namespace std;
vector<vector<int>> G(100);
vector<int> d(100);
const int INF = 1<<28;
void bfs(){
    queue<int> Q;
    Q.push(0);
    fill(d.begin(),d.end(),INF);
    d[0]=0;
    while(!Q.empty()){
        int u=Q.front();
        Q.pop();
        for(auto a:G[u]){
            if(d[a]!=INF) continue;
            d[a]=d[u]+1;
            Q.push(a);
        }
    }
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i=0;i<n;++i){
        int u,k;
        cin>>u>>k;
        for(int j=0;j<k;++j){
            int v;
            cin>>v;
            G[u-1].push_back(v-1);
        }
    }
    bfs();
    for(int i=0;i<n;++i)
        cout<<i+1<<' '<<(d[i]==INF?-1:d[i])<<endl;
}