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 <iostream>
#include <queue>
using namespace std;

int a[100][100];
int n;
int D[100];
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) {
			if (a[cur][dst] == 1 && D[dst] == -1) {
				D[dst] = D[cur]+1;
				Q.push(dst);
			}
		}
	}
}

int main() {
	cin >> n;
	int p,q,r;
	for (int i=0; i<n; ++i) {
		cin >> p >> q;
		D[i] = -1;
		for (int i=0; i<q; ++i) {
			cin >> r;
			a[p-1][r-1] = 1;
		}
	}
	bfs(0);
	for (int i=0; i<n; ++i) {
		cout << i+1 << " " << D[i] << endl;
	}
}

C++: #include <stdio.h>
#include <iostream>
using namespace std;

class Adjl{
private:
	int u;
	int k;
	Adjl **next;
	int check_id;
public:
	Adjl(int u);
	~Adjl(){ if (next != NULL) delete[] next; }
	void setV(int k, Adjl *vk);
	int breadthFirstSearch(int id);
	void print(int id);
};

Adjl::Adjl(int u)
{
	this->u = u;
	k = 0;
	next = NULL;
	check_id = 0;
}

void Adjl::setV(int k, Adjl *vk)
{
	if (this->k == 0) next = new Adjl*[k];
	next[this->k] = vk;
	(this->k)++;
}

int Adjl::breadthFirstSearch(int id)
{
	if (id == check_id) return -1;
	else check_id = id;

	if (id == this->u) return 0;

	int d_min = -1;
	for (int i = 0; i < k; i++) {
		int d = next[i]->breadthFirstSearch(id);
		if (d == -1) continue;
		if (d_min == -1) d_min = d + 1;
		else d_min = min(d + 1, d_min);
	}
	return d_min;
}

void Adjl::print(int id)
{
	cout << id << " " << breadthFirstSearch(id) << endl;
}

int main(void)
{
	int n;
	cin >> n;
	
	Adjl **adjl = new Adjl*[n];
	int check[100] = {0};

	for (int i = 0; i < n; i++) {
		int u, k;
		cin >> u >> k;
		if (check[i] == 0) {
			adjl[i] = new Adjl(u);
			check[i] = 1;
		}
		check[i] = 1;
		for (int j = 0; j < k; j++) {
			int vk;
			cin >> vk;
			if (check[vk - 1] == 0) {
				adjl[vk - 1] = new Adjl(vk);
				check[vk - 1] = 1;
			}
			adjl[i]->setV(k, adjl[vk - 1]);
		}
	}

	for (int i = 1; i <= n; i++) {
		adjl[0]->print(i);
	}

	delete[] adjl;
	return 0;
}

C++: #include <iostream>
#include <stdio.h>


int map_max;
int map[110][110];
int rows;
int cols[110];
int howfar[100];
int far;
int visited[100];

void get_map();
void print_map();
int search(int node, int far);
void print_result();
void check_result();

int main()
{

  get_map();
  //print_map();
  search(1, 0);
  check_result();
  print_result();
  return 0;
}

void check_result()
{
  for(int i=1;i<map_max;i++)
    {
      if(howfar[i]==0)
	{
	  howfar[i]=-1;
	}
    }
}

void print_result()
{
  for(int i=0;i<map_max;i++)
    {
      std::cout << i+1 << " " << howfar[i] << std::endl;
    }
}

void get_map()
{

  int k;
  scanf("%d", &map_max);//<100

  for(int i=0;i<map_max;i++)
    {
      scanf("%d", &k);
      scanf("%d", &cols[i]);
      for(int j=0;j<cols[i];j++)
	{
	  map[i][j]=0;
	  scanf("%d", &map[i][j]);
	}
    }

  
  return ;
}

void print_map()
{
  for(int i=0;i<map_max;i++)
    {
      for(int j=0;j<cols[i];j++)
	{
	  printf("%d", map[i][j]);
	}
      puts("");
    }
return ;
}
int search(int node, int far)
{
  if(visited[node-1] == 1)
    {
      if(howfar[node-1]>far)
	{
	  howfar[node-1]=far;
	}
      return -1;
    }
  else
    {
      howfar[node-1]=far;
      visited[node-1]=1;
    }

  for(int i=0;i<cols[node-1];i++)
    {
      //if(map[node-1][i]!=0)
	{
	  search(map[node-1][i], far+1);
	}
    }
  return -1;
}

C++: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<climits>
#include<iostream>
#include<sstream>
#include<utility>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#include<set>
#include<stack>

using namespace std;

const int MAX_N = 101;
const int DUMMY = 10000;

int N, u, k, v = 0;

vector<int>V [MAX_N];
int d [MAX_N];
bool visited [MAX_N];

bool bfs(int u, int depth)
{
    for (int i = 0; i < V[u].size(); ++i) {
        if(V[u][i] == 1) continue;
        bfs(V[u][i] - 1, depth + 1);
    }
        
    
    d[u] = min(d[u], depth);
    
    if (V[u].size() == 0 || u == 0)
        return true;
}

int main()
{
    //initialize
    for (int i = 0; i < MAX_N; ++i) {
        d[i]   = DUMMY;
        visited[i] = false;
    }
    
    //input
    scanf("%d", &N);
    for (int i = 0; i < N; ++i) {
      scanf("%d %d", &u, &k);
      for (int j = 0; j < k; ++j) {
          scanf("%d", &v);
          V[i].push_back(v);
      }
      sort(V[i].begin(), V[i].end());
    }

    //serach
    bfs(1-1, 0);
    
    //output
    for (int i = 0; i < N; ++i) {
      if(d[i] == DUMMY) cout << i+1 << ' ' << -1 << endl;
      else cout << i+1 << ' ' << d[i] << endl;
    }

    return 0;
}