#include <bits/stdc++.h>
       
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
       
       

struct Edge {
  int from, to;
  Edge(){};
  Edge(int from, int to) : from(from), to(to) {}

  void scanFrom(std::istream& strm, int base = 1) {
    strm >> from >> to;
    if (base == 1) --from, --to;
  }

  Edge reverse() const { return Edge(to, from); }
};

inline std::istream& operator>>(std::istream& strm, Edge& t) {
  t.scanFrom(strm);
  return strm;
}
       
       

template <typename T>
struct WeightedEdge {
  int from, to;
  T _weight;
  WeightedEdge(){};
  WeightedEdge(int from, int to, T weight)
      : from(from), to(to), _weight(weight) {}

  void scanFrom(std::istream& strm, int base = 1) {
    strm >> from >> to >> _weight;
    if (base == 1) --from, --to;
  }

  T weight() const { return _weight; }

  WeightedEdge reverse() const { return WeightedEdge(to, from, _weight); }
};

template <typename T>
inline std::istream& operator>>(std::istream& strm, WeightedEdge<T>& t) {
  t.scanFrom(strm);
  return strm;
}

template <typename Edge>
class Digraph {
  int _E, _V;
  vector<vector<Edge>> _adjacencyList;

 public:
  int E() const { return _E; }

  int V() const { return _V; }
  int size() const { return _V; }

  Digraph() : _V(0), _E(0){};
  Digraph(int V, int E = 0) : _V(V), _E(E) { _adjacencyList.resize(V); }

  void addEdge(const Edge& e) {
    _adjacencyList[e.from].push_back(e);
    ++_E;
  }

  void addUndirectedEdge(const Edge& e) {
    _adjacencyList[e.from].push_back(e);
    _adjacencyList[e.to].push_back(e.reverse());
    ++_E;
  }

  void addNode() {
    ++_V;
    _adjacencyList.push_back(vector<Edge>());
  }

  void scanFrom(std::istream& strm, int base = 1) {
    if (_V == 0) strm >> _V;
    if (_E == 0) strm >> _E;
    _adjacencyList.resize(_V);
    for (int i = 0; i < _E; ++i) {
      Edge e;
      e.scanFrom(cin, base);
      assert(0 <= e.from < _V);
      assert(0 <= e.to < _V);
      addEdge(e);
    }
  }

  vector<Edge> operator[](int u) const { return _adjacencyList[u]; }
  vector<vector<Edge>>& adjacencyList() { return _adjacencyList; }
};

template <typename Edge>
inline std::istream& operator>>(std::istream& strm, Digraph<Edge>& t) {
  t.scanFrom(strm);
  return strm;
}

class BFSShortestPath {
  const int INF = numeric_limits<int>::max();
  vector<int> _distTo;
  vector<int> prev;

 public:
  BFSShortestPath(const Digraph<Edge>& G, int s)
      : _distTo(G.V(), INF), prev(G.V(), -1) {
    queue<int> q;
    q.push(s);
    _distTo[s] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (Edge& e : G[u]) {
        if (_distTo[e.to] != INF) continue;
        _distTo[e.to] = _distTo[u] + 1;
        prev[e.to] = u;
        q.push(e.to);
      }
    }
  }

  int distTo(int u) { return _distTo[u]; }

  bool hasPathTo(int u) { return _distTo[u] != INF; }

  vector<int> pathTo(int u) {
    assert(hasPathTo(u));
    vector<int> path;
    while (u != -1) {
      path.push_back(u);
      u = prev[u];
    }
    return path;
  }
};

int main() {
  int n;
  cin >> n;
  Digraph<Edge> G(n);

  for (int i = 0; i < (int)(n); ++i) {
    int u, k;
    cin >> u >> k;
    --u;
    for (int j = 0; j < (int)(k); ++j) {
      int v;
      cin >> v;
      --v;
      G.addEdge(Edge(u, v));
    }
  }

  BFSShortestPath sp(G, 0);
  for (int i = 0; i < (int)(n); ++i) {
    cout << i + 1 << " " << (sp.hasPathTo(i) ? sp.distTo(i) : -1) << endl;
  }

  return 0;
}



Measured memory_bytes: 3120