// RMQ
#include<vector>
#include<climits>
#include<cassert>
const int INF = INT_MAX;
class RangeMinimumQuery {
public:
  explicit RangeMinimumQuery(int s);
  void update(int i, int v);
  int index(int left, int right) const;
  int value(int left, int right) const;
private:
  int parent(int node) const;
  int left_child(int node) const;
  int right_child(int node) const;
  int power_of_two(int n) const;
  int query(int left, int right, int node, int node_left, int node_right) const;
  int size_, nil_, inf_;
  std::vector<int> index_, value_;
};
RangeMinimumQuery::RangeMinimumQuery(int s) : size_(power_of_two(s)), nil_(size_), inf_(INF), index_(2 * size_ - 1, nil_), value_(size_ + 1, inf_) {}
void RangeMinimumQuery::update(int i, int v) {
  int node = i + size_ - 1;
  index_.at(node) = i;
  value_.at(i) = v;
  while((node = parent(node)) != nil_) {
    int l = value_.at(index_.at(left_child(node)));
    int r = value_.at(index_.at(right_child(node)));
    index_.at(node) = index_.at(l <= r ? left_child(node) : right_child(node));
  }
}
int RangeMinimumQuery::index(int left, int right) const {
  return query(left, right, 0, 0, size_ - 1);
}
int RangeMinimumQuery::value(int left, int right) const {
  return value_.at(query(left, right, 0, 0, size_ - 1));
}
int RangeMinimumQuery::parent(int node) const {return node ? (node - 1) / 2 : nil_;}
int RangeMinimumQuery::left_child(int node) const {return 2 * node + 1;}
int RangeMinimumQuery::right_child(int node) const {return 2 * node + 2;}
int RangeMinimumQuery::power_of_two(int n) const {
  while(n & (n - 1)) n += n & -n;
  return n;
}
int RangeMinimumQuery::query(int left, int right, int node, int node_left, int node_right) const {
  assert(left <= right);
  assert(0 <= left);
  assert(right < size_);
  if(node_right < left || right < node_left) return nil_;
  if(left <= node_left && node_right <= right) return index_.at(node);
  int middle = (node_left + node_right) / 2;
  int l = query(left, right, left_child(node), node_left, middle);
  int r = query(left, right, right_child(node), middle + 1, node_right);
  return value_.at(l) <= value_.at(r) ? l : r;
}

// Graph: Adjacency list
#include<vector>
typedef std::vector<std::vector<int>> Graph;

// LCA
#include<vector>
#include<utility>
#include<memory>
class LowestCommonAncestor {
public:
  explicit LowestCommonAncestor(const Graph& g) : id_(g.size()) {
    dfs(g, 0, 0);
    RMQ_ = std::unique_ptr<RangeMinimumQuery>(new RangeMinimumQuery(depth_.size()));
    for(int i = 0; i < depth_.size(); ++i) RMQ_->update(i, depth_.at(i));
  }
  int find(int u, int v) const {
    if(id_.at(u) > id_.at(v)) std::swap(u, v);
    return vs_.at(RMQ_->index(id_.at(u), id_.at(v)));
  }
private:
  void dfs(const Graph& g, int current, int depth) {
    id_.at(current) = vs_.size();
    vs_.push_back(current);
    depth_.push_back(depth);
    for(const auto& next: g.at(current)) {
      dfs(g, next, depth + 1);
      vs_.push_back(current);
      depth_.push_back(depth);
    }
  }
  std::vector<int> id_, vs_, depth_;
  std::unique_ptr<RangeMinimumQuery> RMQ_;
};

#include<bits/stdc++.h>
using namespace std;
int main() {
  int n;
  cin >> n;

  Graph g(n);
  for(auto& list: g) {
    int k;
    cin >> k;
    list.resize(k);
    for(auto& c: list) cin >> c;
  }

  LowestCommonAncestor lca(g);
  int q;
  cin >> q;
  for(int i = 0; i < q; ++i) {
    int u, v;
    cin >> u >> v;
    cout << lca.find(u, v) << endl;
  }
}

Measured memory_bytes: 15512