// clang-format off
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define main signed main()
#define loop(i, a, n) for (int i = (a); i < (n); i++)
#define rep(i, n) loop(i, 0, n)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define prec(n) fixed << setprecision(n)
constexpr int INF = sizeof(int) == sizeof(long long) ? 1000000000000000000LL : 1000000000;
constexpr int MOD = 1000000007;
constexpr double PI = 3.14159265358979;
template<typename A, typename B> bool cmin(A &a, const B &b) { return a > b ? (a = b, true) : false; }
template<typename A, typename B> bool cmax(A &a, const B &b) { return a < b ? (a = b, true) : false; }
bool odd(const int &n) { return n & 1; }
bool even(const int &n) { return ~n & 1; }
template<typename T = int> T in() { T x; cin >> x; return x; }
template<typename T = int> T in(T &&x) { T z(forward<T>(x)); cin >> z; return z; }
template<typename T> istream &operator>>(istream &is, vector<T> &v) { for (T &x : v) is >> x; return is; }
template<typename A, typename B> istream &operator>>(istream &is, pair<A, B> &p) { return is >> p.first >> p.second; }
template<typename T> ostream &operator<<(ostream &os, const vector<vector<T>> &v) { int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? "" : "\n"); return os; }
template<typename T> ostream &operator<<(ostream &os, const vector<T> &v) { int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? "" : " "); return os; }
template<typename A, typename B> ostream &operator<<(ostream &os, const pair<A, B> &p) { return os << p.first << ' ' << p.second; }
template<typename Head, typename Value> auto vectors(const Head &head, const Value &v) { return vector<Value>(head, v); }
template<typename Head, typename... Tail> auto vectors(Head x, Tail... tail) { auto inner = vectors(tail...); return vector<decltype(inner)>(x, inner); }
// clang-format on

// template for Edge

struct Edge {
  int src, dst, id;
  Edge(const int &src, const int &dst, const int &id) : src(src), dst(dst), id(id) {}
  Edge(const int &src, const int &dst) : src(src), dst(dst), id(-1) {}
  Edge() : src(), dst(), id(-1) {}
  friend ostream &operator<<(ostream &os, const Edge &e) {
    return os << e.src << "->" << e.dst << " (id=" << e.id << ')';
    return os;
  }
};

template<typename Weight> struct WeightedEdge : Edge {
  Weight weight;

public:
  WeightedEdge(const int &src, const int &dst, const Weight &weight, const int &id) : Edge(src, dst, id), weight(weight) {}
  WeightedEdge(const int &src, const int &dst, const Weight &weight) : Edge(src, dst), weight(weight) {}
  WeightedEdge() : Edge(), weight() {}
  friend ostream &operator<<(ostream &os, const WeightedEdge<Weight> &e) {
    return os << e.src << "->" << e.dst << " (id=" << e.id << ", weight=" << e.weight << ')';
    return os;
  }
};

template<typename Edge> class Graph {
  int n;
  bool directed;
  vector<Edge> edges;

public:
  Graph(const int &n, const bool &directed = true) : n(n), directed(directed) {}
  template<typename... Args> void addEdge(Args... args) { edges.emplace_back(args..., edges.size()); }
  void addEdge(const Edge &edge) { edges.emplace_back(edge); }
  int sizeV() const { return n; }
  int sizeE() const { return edges.size(); }
  bool isDirected() const { return directed; }
  const Edge &operator[](const int &i) const { return edges[i]; }
  auto begin() { return edges.begin(); }
  auto begin() const { return edges.begin(); }
  auto end() { return edges.end(); }
  auto end() const { return edges.end(); }
  friend ostream &operator<<(ostream &os, const Graph<Edge> &g) {
    os << "V=" << g.sizeV() << ", E=" << g.sizeE() << ", directed=" << (g.isDirected() ? "true" : "false") << endl;
    for (auto &e : g.edges) os << e << endl;
    return os;
  }
};

template<typename Edge> class AdjList {
  bool directed;
  vector<vector<Edge>> al;

public:
  AdjList(const Graph<Edge> &g) : directed(g.isDirected()), al(g.sizeV()) {
    int m = g.sizeE();
    if (directed) {
      rep(i, m) al[g[i].src].emplace_back(g[i]);
    } else {
      rep(i, m) {
        al[g[i].src].emplace_back(g[i]);
        al[g[i].src].back().id = i << 1;
        al[g[i].dst].emplace_back(g[i]);
        swap(al[g[i].dst].back().src, al[g[i].dst].back().dst);
        al[g[i].dst].back().id = i << 1 | 1;
      }
    }
  }

  // AdjList(const DirectedGraph<Edge> &g) : directed(true), al(g.sizeV()) {
  //   int m = g.sizeE();
  //   rep(i, m) al[g[i].src].emplace_back(g[i]);
  // }

  // AdjList(const UndirectedGraph<Edge> &g) : directed(false), al(g.sizeV()) {
  //   int m = g.sizeE();
  //   rep(i, m) {
  //     al[g[i].src].emplace_back(g[i]);
  //     al[g[i].src].back().id = i << 1;
  //     al[g[i].dst].emplace_back(g[i]);
  //     swap(al[g[i].dst].back().src, al[g[i].dst].back().dst);
  //     al[g[i].dst].back().id = i << 1 | 1;
  //   }
  // }

  // int size() const { return al.size(); }
  //   int originalEdge(int e) { return e >> (not directed); }
  const auto &operator[](const int &i) const { return al[i]; }
  auto begin() { return al.begin(); }
  auto begin() const { return al.begin(); }
  auto end() { return al.end(); }
  auto end() const { return al.end(); }
};

template<typename Weight> class Dijkstra {
  int s;
  Graph<WeightedEdge<Weight>> g; // needed?

  AdjList<WeightedEdge<Weight>> al;
  vector<Weight> dist;
  vector<Edge> prev;

public:
  Dijkstra(const Graph<WeightedEdge<Weight>> &g,
           const int &s,
           const Weight &inf = numeric_limits<Weight>::max() / 8) //
      : g(g), al(g), s(s), dist(g.sizeV(), inf), prev(g.sizeV()) {
    using state = pair<Weight, int>;
    priority_queue<state, vector<state>, greater<state>> q;
    dist[s] = 0;
    q.emplace(0, s);
    while (q.size()) {
      Weight d;
      int v;
      tie(d, v) = q.top();
      q.pop();
      if (dist[v] < d) continue;
      for (auto &e : al[v]) {
        if (cmin(dist[e.dst], dist[v] + e.weight)) {
          prev[e.dst] = e;
          q.emplace(dist[e.dst], e.dst);
        }
      }
    }
  }

  Weight shortestDist(const int &v) { return dist[v]; }

  vector<Edge> shortestPathEdges(int v) {
    vector<Edge> p;
    for (; v != s; v = prev[v].src) p.emplace_back(prev[v]);
    reverse(all(p));
    return p;
  }

  vector<int> shortestPathVertices(int v) {
    vector<Edge> es = shortestPathEdges(v);
    vector<int> p;
    for (auto &e : es) p.emplace_back(e.src);
    p.emplace_back(v);
    return p;
  }
};

main {
  while (true) {
    int n = in();
    if (n == 0) break;
    Graph<WeightedEdge<double>> g(n, false);
    vector<double> x(n), y(n);
    rep(i, n) {
      int b, x1, y1;
      cin >> b >> x1 >> y1;
      --b;
      x[b] = x1, y[b] = y1;
    }
    rep(i, n) loop(j, i + 1, n) {
      double d = hypot(x[i] - x[j], y[i] - y[j]);
      if (d <= 50.0) g.addEdge(i, j, d);
    }
    int m;
    cin >> m;
    while (m--) {
      int s, t;
      cin >> s >> t;
      --s, --t;
      Dijkstra<double> dij(g, s, INF);
      if (dij.shortestDist(t) == INF) {
        cout << "NA" << endl;
        continue;
      }
      auto p = dij.shortestPathVertices(t);
      for (auto &v : p) v++;
      cout << p << endl;
    }
  }
}



Measured memory_bytes: 3228