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++: #pragma region kyomukyomupurin

/**
 *    author  : 𝒌𝒚𝒐𝒎𝒖𝒌𝒚𝒐𝒎𝒖𝒑𝒖𝒓𝒊𝒏
 *    created : 2020-06-07 22:12:03
 **/

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

using int64 = long long;

template<class T>
inline void eraque(std::vector<T>& vec) {
  vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
  return;
}

template<class T>
inline int lower_position(const std::vector<T>& vec, T value) {
  return static_cast<int>(distance(vec.begin(), std::lower_bound(vec.begin(), vec.end(), value)));
}

template<class T>
inline int upper_position(const std::vector<T>& vec, T value) {
  return static_cast<int>(distance(vec.begin(), std::upper_bound(vec.begin(), vec.end(), value)));
}

template <class T>
using binary_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template <class T, class U>
std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& p) {
  return os << '(' << p.first << ", " << p.second << ')';
}

#if __cplusplus >= 201703L
template <class Ch, class Tr, class Tuple, std::size_t... Is>
void tuple_out(std::basic_ostream<Ch, Tr>& os, const Tuple& tp, std::index_sequence<Is...>) {
  ((os << (Is ? ", " : "(") << std::get<Is>(tp)), ...) << ")";
}

template <class Ch, class Tr, class... Args>
auto& operator<<(std::basic_ostream<Ch, Tr>& os, const std::tuple<Args...>& tp) {
  tuple_out(os, tp, std::index_sequence_for<Args...>{});
  return os;
}
#endif

template <class T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
  int n = 0;
  for (auto e : vec) os << (n++ ? ", " : "{") << e;
  return os << (n ? "}" : "{}");
}

template <class T, class Compare>
std::ostream& operator<<(std::ostream& os, const std::set<T, Compare>& st) {
  int n = 0;
  for (auto e : st) os << (n++ ? ", " : "{") << e;
  return os << (n ? "}" : "{}");
}

template <class T, class U, class Compare>
std::ostream& operator<<(std::ostream& os, const std::map<T, U, Compare>& mp) {
  int n = 0;
  for (auto e : mp) os << (n++ ? ", " : "{") << e;
  return os << (n ? "}" : "{}");
}

template <class T>
std::istream& operator>>(std::istream& is, std::vector<T>& vec) {
  for (T& e : vec) is >> e;
  return is;
}

#define all(_) begin(_), end(_)
#define rall(_) rbegin(_), rend(_)

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() { std::cerr << '\n'; }

template <class Head, class... Tail>
void debug_out(Head&& head, Tail&&... tail) {
  std::cerr << head;
  if (sizeof...(Tail) != 0) std::cerr << ", ";
  debug_out(std::forward<Tail>(tail)...);
}

#pragma endregion kyomukyomupurin

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  int n; cin >> n;
  vector<vector<int>> g(n);
  for (int i = 0; i < n; ++i) {
    int id, k; cin >> id >> k;
    for (int j = 0; j < k; ++j) {
      int v; cin >> v; --v;
      g[i].emplace_back(v);
    }
  }

  vector<int> dis(n, -1);
  dis[0] = 0;

  queue<int> que;
  que.emplace(0);
  vector<bool> visited(n, false);
  visited[0] = true;

  while (!que.empty()) {
    int cur = que.front(); que.pop();
    for (int nxt : g[cur]) {
      if (visited[nxt]) continue;
      dis[nxt] = dis[cur] + 1;
      visited[nxt] = true;
      que.emplace(nxt);
    }
  }

  for (int i = 0; i < n; ++i) {
    cout << i + 1 << " " << dis[i] << '\n';
  }

  return 0;
}

C++: #include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef pair< int, int > Pi;
const int INF = 1 << 30;
struct edge: vector< Pi > {
  void add_edge(int to, int cost){
    push_back(Pi(to,cost));
  }
} info[100000];
int hoge[100000];
 
void bfs(const int& st, const int& V){
  fill_n( hoge, V, INF);
  queue< int > que;
  que.push(st);
  hoge[st] = 0;
  while(!que.empty()){
    int p = que.front();
    que.pop();
    for(int i = 0 ; i < info[p].size() ; i++){
      int cost = info[p][i].second;
      int to = info[p][i].first;
      if( cost + hoge[p] < hoge[to]){
        que.push(to);
        hoge[to] = cost + hoge[p];
      }
    }
  }
}
 
int main(){
  int N;
  scanf("%d", &N);
  for(int i = 0; i < N; i++){
    int u, k;
    scanf("%d %d", &u, &k);
    u--;
    while(k--){
      int v;
      scanf("%d", &v);
      info[u].add_edge( v - 1, 1);
    }
  }
  bfs(0, N);
  for(int i = 0 ; i < N ; i++ ){
    printf("%d %d\n", i + 1, hoge[i]);
  }
}

C++: #include<stdio.h>
#include<limits.h>
#define MAX 101
#define WHITE 0
#define GRAY 1
#define BLACK 2
#define TRUE 1
#define FALSE 0
/*void DFSVisit(int);
  void DFS(void);*/
void BFS(int);
int deQueue(void);
void enQueue(int);
int isEmpty(void);
int G[MAX][MAX];
int D[MAX];
int F[MAX];
int color[MAX];
int Q[MAX];
int n;
int time;
int head = 0, tail = 0;
main(){
  int i, j, m, k, value, start = 1;
  scanf("%d",&n);

  for(i = 1; i <= n; i++){
    for(j = 1; j <= n; j++){

      G[i][j] = 0;

    }
  }

  for(i = 1; i <= n; i++){

    scanf("%d %d", &k, &m);

    for(j = 1; j <= m; j++){

      scanf("%d",&value);

      G[i][value] = 1;
    }
  }
 
  BFS(start);

  for(i = 1; i <= n; i++)
    {
      if(D[i]==INT_MAX)D[i] = -1;
      printf("%d %d\n", i, D[i]);
    }

 return 0;

}




/*void DFS(void){
  int u;

  for( u = 1; u <= n; u++ ){

    color[u] = WHITE;

  }

  time = 0;

 for( u = 1; u <= n; u++ ){
   if( color[u] == WHITE )
     DFSVisit(u);

  }

}

void DFSVisit(int u){
  int v;

  color[u] = GRAY;

  time++;
 
  D[u] = time;

  for(v = 1; v <= n ; v++){

    if(G[u][v] == 1 && color[v] == WHITE)
      DFSVisit(v);
  }
  color[u] = BLACK;

  F[u] = ++time;
  }*/

void BFS(int start){
  int u, v;

  for(u = 2; u <= n; u++ ){

    color[u] =  WHITE;

    D[u] = INT_MAX;

  }

  color[start] = GRAY;

  D[start] = 0;

  enQueue(start);
  while(isEmpty() != FALSE){

    u = deQueue();

    for( v = 1; v <= n; v++ ){
      if(color[v] == WHITE && G[u][v] == 1){

	color[v] = GRAY;

	D[v] = D[u] + 1;

	enQueue(v);
      }
    }
  }
}

void enQueue(int x){

  Q[tail] = x;

    if(tail == 100)tail = 0;
    
    else tail ++; 

}

int deQueue(){

  int x;

  x = Q[head];

  if(head == 100)head = 0;

  else head++;

  return x;
}


int isEmpty(){
  if(tail == head)return FALSE;

  else return TRUE;
}