Go: package main

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

type AdjacentList struct {
	matrix [][]int
}

func NewEmptyAdjacentList(dim int) *AdjacentList {
	matrix := make([][]int, dim)
	for i := 0; i < dim; i++ {
		matrix[i] = make([]int, dim)
	}
	return &AdjacentList{matrix: matrix}
}

func (al *AdjacentList) set(node int, adjacent int) {
	al.matrix[node-1][adjacent-1] = 1
}

func (al *AdjacentList) findAdjacentsFor(node int) []int {
	adjacents := []int{}
	for i, v := range al.matrix[node-1] {
		if v == 1 {
			adjacents = append(adjacents, i+1)
		}
	}
	return adjacents
}

type DistanceList struct {
	list []int
}

func NewDistanceList(dim int) *DistanceList {
	list := make([]int, dim)
	for i := 0; i < dim; i++ {
		list[i] = -1
	}
	return &DistanceList{list: list}
}

func (dl *DistanceList) set(node int, distance int) {
	dl.list[node-1] = distance
}

func (dl *DistanceList) get(node int) int {
	return dl.list[node-1]
}

func (dl *DistanceList) isVisited(node int) bool {
	return dl.list[node-1] >= 0
}

type Position struct {
	node     int
	distance int
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	dim, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	al := NewEmptyAdjacentList(dim)

	for i := 1; i <= dim; i++ {
		node, err := nextInt(sc)
		if err != nil {
			panic(err)
		}

		adjacentNum, err := nextInt(sc)
		if err != nil {
			panic(err)
		}
		for j := 0; j < adjacentNum; j++ {
			adjacent, err := nextInt(sc)
			if err != nil {
				panic(err)
			}
			al.set(node, adjacent)
		}
	}

	dl := NewDistanceList(dim)

	bfs(al, dl)

	for i := 1; i <= dim; i++ {
		fmt.Printf("%d %d\n", i, dl.get(i))
	}
}

func bfs(al *AdjacentList, dl *DistanceList) {
	stack := []Position{Position{node: 1, distance: 0}}
	for len(stack) > 0 {
		currentPosition := stack[0]
		stack = stack[1:]
		if !dl.isVisited(currentPosition.node) {
			dl.set(currentPosition.node, currentPosition.distance)
		}
		for _, v := range al.findAdjacentsFor(currentPosition.node) {
			if !dl.isVisited(v) {
				stack = append(stack, Position{node: v, distance: currentPosition.distance + 1})
			}
		}
	}
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;

static const int N = 100;
static const int INFTY = (1<<21);

int n,M[N][N];
int d[N];

void bfs(int s){
  queue<int> q;
  q.push(s);
  for(int i=0;i<n;i++) d[i] = INFTY;
  d[s] = 0;
  int u;
  while(!q.empty()){
    u = q.front();
    q.pop();
    for(int v=0;v<n;v++){
      if(M[u][v] == 0) continue;
      if(d[v] != INFTY) continue;
      d[v] = d[u] + 1;
      q.push(v);
    }
  }
  for(int i=0;i<n;i++){
    cout << i+1 << " " << ( (d[i] == INFTY) ? (-1) : d[i] ) << endl;
  }
}

int main(){
  int u,k,v;

  cin >> n;
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++) M[i][j] = 0;
  }

  for(int i=0;i<n;i++){
    cin >> u >> k;
    u--;
    for(int j=0;j<k;j++){
      cin >> v;
      v--;
      M[u][v] = 1;
    }
  }

  bfs(0);
  return 0;
}

C++: #include <iostream>
#include <limits>

using namespace std;

bool adjmatrix[101 * 101];
int costs[101];



void BFS(int vertex, int cur_cost, int N) {
  if (costs[vertex] < cur_cost) return;
  costs[vertex] = cur_cost;
  for (int i =1; i<= N; i++) {
    if(adjmatrix[vertex*101 + i]) {
      BFS(i, cur_cost + 1, N);
    }
  }
}
  

int main() {
  for (int i = 0; i < 101; i++) {
    costs[i] = INT_MAX;
  }
  int N;
  cin >> N;

  for (int i = 0; i < N; i++) {
    int vertex, degree;
    cin >> vertex >> degree;

    for (int j = 0; j < degree; j++) {
      int outvertex;
      cin >> outvertex;
      adjmatrix[vertex * 101 + outvertex] = true;
    }
  }


  /*
  //function to print adjmatrix
  for (int i = 0; i <= N; i++) {
    for (int j= 0; j <= N; j++) {
      if (adjmatrix[i * 101 + j]) {
	cout << "1 ";
      } else {
	cout << "0 ";
      }
    }
    cout << endl;
    }*/

  BFS(1, 0, N);

  for (int i =1; i<=N; i++) {
    cout << i << " " << costs[i] << endl;
  }

 

}

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

int k[1000][1000], n, a, b, c, t, x[1000];
queue<int>Q;
queue<int>R;

int main() {
	memset(x, -1, sizeof(x));
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a >> b;
		for (int j = 0; j < b; j++) {
			cin >> c;
			k[i][c] = 1;
		}
	}
	Q.push(1);
	x[1] = 0;
	while (!Q.empty()) {
		t++;
		while (!Q.empty()) {
			for (int i = 1; i <= n; i++) {
				if (x[i] == -1 && k[i][c] == 1) {
					x[i] = t;
					R.push(i);
				}
			}
			Q.pop();
		}
		while (!R.empty()) {
			Q.push(R.front());
			R.pop();
		}
	}
	for (int i = 1; i <= n; i++) {
		cout << i << ' ' << x[i] << endl;
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <unordered_map>
#include <queue>
//#include "../cxx-prettyprint/prettyprint.hpp"


int main() {
    int n;
    std::cin >> n;

    std::unordered_map<int, std::vector<int>> Adj(n);

    for (int i = 0; i < n; i ++) {
        int u, k;
        std::cin >> u >> k;
        std::vector<int> V(k);
        for (int& v : V) {
            std::cin >> v;
        }
        Adj[u] = V;
    }

    std::set<int> nodes_unvisited;
    std::unordered_map<int, int> distances;

    for (int i = 1; i <= n; i ++) {
        nodes_unvisited.insert(i);
    }

    nodes_unvisited.erase(1);
    distances[1] = 0;
    std::queue<int> queue;
    queue.push(1);

    while (!queue.empty()) {
        int u = queue.front();
        queue.pop();
        for (int v : Adj[u]) {
            if (nodes_unvisited.find(v) != nodes_unvisited.end()) {
                nodes_unvisited.erase(v);
                distances[v] = distances[u] + 1;
                queue.push(v);
            }
        }
    }

    for (int i = 1; i <= n; i ++) {
        std::cout << i << " " << distances[i] << std::endl;
    }
}

C++: #include<cstdio>
#include<algorithm>

using namespace std;

class Graph{
    int n;
    int **G;
    int *seen;
    int *todo;
    int *next;
    int *dist;
    const int MAX = 101;
    public: Graph(int _n){
        n = _n;
        G = new int*[n+1];
        seen = new int[n+1];
        todo = new int[n+1];
        next = new int[n+1];
        dist= new int[n+1];
        for(int i = 0;i <=n;++i){
            G[i] = new int[n+1];
            seen[i] = 0;
            todo[i] = 0;
            next[i] = 0;
            dist[i] = MAX;
        }
        for(int i = 0;i <= n;++i){
            for(int j = 0;j <= n;++j){
                G[i][j] = 0;
            }
        }
    }
    
    public: void BuildMatrix(){
        int u,k,v;
        for(int i = 0;i < n;++i){
            scanf("%d %d",&u,&k);
            for(int j = 0;j < k;++j){
                scanf("%d",&v);
                G[u][v] = 1;
            }
        }
    }
    
    public: void PrintMatrix(){
        for(int i = 1;i <= n;++i){
            for(int j = 1;j <n;++j){
                printf("%d ",G[i][j]);
            }
            printf("%d\n",G[i][n]);
        }
    }
    
    
   public: void DoBFS(){
        dist[1] = 0;
        todo[1] = 1;
        while(!isEmpty(todo)){
            for(int i = 1;i <= n;++i){
                if(todo[i] == 1) BFS(i,dist[i]);
            }
            for(int i = 1;i <= n;++i) swap(todo[i],next[i]);
        }
        for(int i = 1;i <= n;++i) printf("%d %d\n",i,(dist[i] != MAX) ? dist[i]:-1);
    }
    void BFS(int s,int cnt){
        cnt++;
        todo[s] = 0;
        seen[s] = 1;
        for(int i = 1;i <= n;++i){
            if(G[s][i]  == 1){
                dist[i] = std::min(dist[i],cnt);
                if(seen[i] != 1) next[i] = 1;
            }
        }
    }
    
    bool isEmpty(int* l){
        for(int i = 1;i <= n;++i){
            if(l[i] != 0) return false;
        }
        return true;
    }
    
};

int main(){
    int n;
    scanf("%d",&n);
    Graph G(n);
    G.BuildMatrix();
    G.DoBFS();
}