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)
}

C++: #include <bits/stdc++.h>
#include <iomanip>
#include <math.h>
#include <unistd.h>
#include <stdio.h>
#define rep(i,x) for(ll i = 0;i<x;i++)
#define all(a) (a).begin(),(a).end()
#define vecin(a) rep(i,a.size())cin >> a[i]
#define vecout(a) rep(i,a.size())cout << a[i] << " ";cout << "\n"
#define vecvec(a) vector<vector<(a)>>
using ll = long long;
using ld = long double;
using namespace std;
using dou = double;
const ll inf = 2147483647;
const ll INF = 1LL << 60;
const ld pi = 3.14159265358;
const ll mod = 1000000007;
typedef pair<ll,ll> P;
using graph = vector<vector<ll>>;
template<class T> inline bool chmax(T& a, T b){if(a < b){a = b; return true;}return false;}
template<class T> inline bool chmin(T& a, T b){if(a > b){a = b; return true;}return false;}
template<class T> inline bool change(T a,T b){if(a > b){swap(a,b);return true;}return false;}
ll gcd(ll a,ll b){
    if(a < b)swap(a,b);
    if(a % b == 0)return b;
    else return gcd(b,a%b);
}
//素数判定O(sqrt(N))
bool isp(ll n){
    bool res = true;
    if(n == 1)return false;
    else{
        for(ll i = 2;i * i <= n;i++){
            if(n % i == 0){
                res = false;
                break;
            }
        }
        return res;
    }
}
const ll cmax = 1000000;
ll fac[cmax], finv[cmax], inv[cmax];

// テーブルを作る前処理
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (ll i = 2; i < cmax; i++){
        fac[i] = fac[i - 1] * i % mod;
        inv[i] = mod - inv[mod%i] * (mod / i) % mod;
        finv[i] = finv[i - 1] * inv[i] % mod;
    }
}

// 二項係数計算
ll nCk(ll n, ll k){
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % mod) % mod;
}
//nのm乗をMODで割ったあまりO(logN)
ll modpow(ll n,ll m,ll MOD){
    ll res = 1;
    while(m){
        if(m & 1)res = (res * n) % MOD;
        m >>= 1;
        n *= n;
        n %= MOD;
    }
    return res;
}

//printf("%.10f\n", N);
/*  vector<ll> vec = {1,2,5,6,8,9,10};
    cout << binary_search(all(vec),5) << endl; -> true*/
/*
    vector<ll> vec = {1,2,5,6,8,9,10};
    auto n = upper_bound(all(vec),4);
    cout << *n << endl; -> 5*/

//    cout << fixed << setprecision(15);

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll N;
    cin >> N;
    graph G(N);
    ll ten,kazu,to;
    rep(i,N){
        cin >> ten;ten--;
        cin >> kazu;
        rep(j,kazu){
            cin >> to;to--;
            G[ten].push_back(to);
        }
    }
    queue<ll> que;
    vector<ll> dist(N,INF);
    dist[0] = 0;
    que.push(0);
    while(que.size()){
        ll n = que.front();que.pop();
        for(auto x : G[n]){
            if(dist[x] == INF){
                que.push(x);
                dist[x] = dist[n] + 1;
            }
        }
    }
    rep(i,N){
        if(dist[i] == INF){
            cout << i + 1 << " " << -1 << endl;
        }
        else cout << i + 1 << " " << dist[i] << endl;
    }
}

C++: #include <iostream>
#include <vector>
#include <cstring>
#include <utility>
#include <queue>

using namespace std;

int main()
{
    int n, u, k, v, dis[110];
    bool vis[110];
    memset(dis, -1, sizeof(dis));
    memset(vis, false, sizeof(vis));
    vector<int> adj[110];
    queue<pair<int, int>> que; //point, dis
    cin>>n;
    for (int i=0; i<n; i++)
    {
        cin>>u>>k;
        for (int j=0; j<k; j++)
        {
            cin>>v;
            adj[u].push_back(v);
        }
    }
    que.push({1, 0});
    vis[1]=true;
    dis[1]=0;
    while (!que.empty())
    {
        int a=que.front().first, b=que.front().second;
        que.pop();
        for (auto u : adj[a])
        {
            if (!vis[u])
            {
                vis[u]=true;
                dis[u]=b+1;
                que.push({u, b+1});
            }
        }
    }
    for (int i=1; i<=n; i++) cout<<i<<' '<<dis[i]<<'\n';
    return 0;
}

C++: #include <iostream>
#include <queue>
#include <vector>
#include <algorithm>

using namespace std;

int main(){
  int n;
  cin >> n;
  vector<vector<bool> > a(n+1, vector<bool>(n+1, false));
  for(int i = 1; i <= n; i++){
    int u;
    cin >> u;
    int k;
    cin >> k;
    for(int j = 0; j < k; j++){
      int v;
      cin >> v;
      a[i][v] = true;
    }
  }
  // ??????1??????????????¢???????????????
  // ?????????????????¨??????0??\???, ???????????????????????°-1
  vector<int> d(n+1, -1);
  d[1] = 0;

  queue<int> q;
  q.push(1);

  while(!q.empty()){
    int current = q.front();
    q.pop();
    for(int dst = 1; dst <= n; dst++){
      if(d[dst] < 0 && a[current][dst]){
        d[dst] = d[current] + 1;
        q.push(dst);
      }
    }
  }

  for(int i = 1; i <= n; i++){
    cout << i << " " << d[i] << endl;
  }
  return 0;
}