Go: package main

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

const (
	N     = 100
	INFTY = 1 << 21
)

type Graph struct {
	M [N][N]int
	d [N]int
}

func (g *Graph) bfs(s, n int) string {
	var q []int
	q = append(q, s) // push

	for i := 0; i < n; i++ {
		g.d[i] = INFTY
	}
	g.d[s] = 0

	for len(q) != 0 {
		u := q[0]
		q = q[1:] // pop
		for v := 0; v < n; v++ {
			if g.M[u][v] == 0 || g.d[v] != INFTY {
				continue
			}
			g.d[v] = g.d[u] + 1
			q = append(q, v) // push
		}
	}

	var out bytes.Buffer
	for i := 0; i < n; i++ {
		if g.d[i] == INFTY {
			out.WriteString(fmt.Sprintf("%d -1\n", i+1))
			continue
		}
		out.WriteString(fmt.Sprintf("%d %d\n", i+1, g.d[i]))
	}

	return strings.TrimRight(out.String(), "\n")
}

func answer(reader io.Reader) string {
	sc := bufio.NewScanner(reader)
	sc.Split(bufio.ScanWords)

	sc.Scan()
	n, _ := strconv.Atoi(sc.Text())

	var g Graph
	for i := 0; i < n; i++ {
		sc.Scan()
		u, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		k, _ := strconv.Atoi(sc.Text())
		u--
		for j := 0; j < k; j++ {
			sc.Scan()
			v, _ := strconv.Atoi(sc.Text())
			v--
			g.M[u][v] = 1
		}
	}

	return g.bfs(0, n)
}

func main() {
	fmt.Println(answer(os.Stdin))
}

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