Problem:
パケット転送

インターネットでは、データはパケットに分割され、パケットごとにルータと呼ばれる中継機器を介して宛先に転送されます。各ルータはパケットに記載された宛先から次に転送すべきルータを判断します。さらに、無限にルータ間を転送され続けることを防ぐため、パケットには TTL（Time To Live） という値が付加されています。ルータは受け取ったパケットの TTL を 1 減算し、その結果が 0 ならそのパケットを破棄し、それ以外なら次のルータに転送します。

そこで、ネットワークの設計を手助けするプログラムを作ることになりました。ネットワークの接続情報と送信パケットの情報を入力として、各パケットが宛先ルータに到着するまでに経由するルータの数のうち最小の値を表示するプログラムを作成してください。

ネットワークは図のように複数のルータとそれらを結ぶケーブルで構成されています。ただし、各接続（ケーブル）は単方向であることに注意してください。各ルータが直接つながっているルータの番号の配列がネットワークの接続の情報として与えられます。ルータの数を n とすれば、各ルータは 1 から n までの整数で識別されます。送信元から宛先ルータまでの経路が複数ある場合は、経由するルータの数が少ない方の値を出力してください。また、パケットが宛先に到達しない場合は NA と出力してください。

例えば、以下の図のようなネットワークで、送信元ルータが 6、宛先ルータが 5 の場合を考えます。最短経路は 6→1→5 であり経由するルータは 3 個です。この場合、TTL はルータ 6、1 でそれぞれ減算されるので、送信時の TTL が 3 以上であればパケットは到達できます。宛先ルータでは TTL を減算する必要はありません。また、送信元と宛先が同じルータになるようなパケットは無いものとします。

Input

入力は以下の形式で与えられます。

n
r1 k1 t11 t12 ... t1k1
r2 k2 t21 t22 ... t2k2
:
rn kn tn1 tn2 ... tnkn
p
s1 d1 v1
s2 d2 v2
:
sp dp vp

1 行目にルータの総数 n（n ≤ 100）、続く n 行に i 番目のルータの接続情報が与えられます。接続情報として、i 番目のルータの番号 ri、i 番目のルータと直接接続しているルータの個数 ki、i 番目のルータから送信できるルータの番号 ti1, ti2, ... tikiが与えられます。

続く行にパケットの個数 p（p ≤ 1000）、続く p 行に i 番目のパケットの情報が与えられます。パケットの情報として、 送信元ルータの番号 si, 宛先ルータの番号 di, TTL の値 vi (0 ≤ vi ≤ 10000) が与えられます。

Output

各パケットごとに、経由するルータの個数または NA を１行に出力してください。

Sample Input

7
1 4 2 5 4 3
2 1 5
3 1 6
4 1 7
5 2 7 6
6 1 1
7 0
6
1 2 2
1 5 3
1 2 1
5 1 3
6 3 3
1 7 4

Output for the Sample Input

2
2
NA
3
3
3

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _0144
{
    public class Program

    {
        public static void Main(string[] args)
        {
            Graph gh = new Graph();
            int n = RInt();
            for (int i = 0 ; i < n ; i++)
            {
                int[] items = RIntAr();
                gh.SetGraph(items[0], items.Skip(2).ToArray());
            }

            int p = RInt();
            for (int i = 0 ; i < p ; i++)
            {
                int[] sdv = RIntAr();
                int distance = gh.GetDistance(sdv[0], sdv[1]);
                Console.WriteLine((distance < sdv[2] && distance != -1) ? (distance + 1).ToString() : "NA");
            }
        }

        static string RSt() { return Console.ReadLine(); }
        static int RInt() { return int.Parse(Console.ReadLine().Trim()); }
        static long RLong() { return long.Parse(Console.ReadLine().Trim()); }
        static double RDouble() { return double.Parse(Console.ReadLine()); }
        static string[] RStAr(char sep = ' ') { return Console.ReadLine().Trim().Split(sep); }
        static int[] RIntAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Trim().Split(sep), e => int.Parse(e)); }
        static long[] RLongAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Trim().Split(sep), e => long.Parse(e)); }
        static double[] RDoubleAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Trim().Split(sep), e => double.Parse(e)); }
        static string WAr<T>(IEnumerable<T> array, string sep = " ") { return string.Join(sep, array.Select(x => x.ToString()).ToArray()); }
    }

}

public class Graph
{
    public class Node
    {
        public List<KeyValuePair<int, int>> Vertex { get; internal set; }
        public bool IsVisited { get; internal set; }
        public int Depth { get; internal set; }

        public Node(List<int> v)
        {
            Vertex = v.Select(x => new KeyValuePair<int, int>(x, -1)).ToList();
            Depth = -1;
        }
    }

    public Dictionary<int, Node> Adj { get; set; }
    public int Count { get { return Adj.Count; } }

    public Graph()
    {
        Adj = new Dictionary<int, Node>();
    }

    /// <summary>
    /// 指定した頂点をセットする
    /// </summary>
    /// <param name="index">頂点u</param>
    /// <param name="item">頂点uに接続する頂点</param>
    public void SetGraph(int index, int[] item)
    {
        if (item == null)
        {
            Adj.Add(index, new Node(new List<int>()));
        }
        else
        {
            Adj.Add(index, new Node(item.ToList()));
        }
    }

    /// <summary>
    /// 訪問済フラグをクリアする
    /// </summary>
    private void InitVisitFlag()
    {
        foreach (KeyValuePair<int, Node> item in Adj) item.Value.IsVisited = false;
    }

    /// <summary>
    /// 頂点間の最小頂点数を返す
    /// </summary>
    /// <param name="start">始点</param>
    /// <param name="end">終点</param>
    /// <returns>
    /// 始点と終点の距離
    /// 始点と終点が連結されていない場合は-1を返す
    /// </returns>
    public int GetDistance(int start, int end)
    {
        InitVisitFlag();
        Queue<Node> que = new Queue<Node>();

        Adj[start].IsVisited = true;
        Adj[start].Depth = 0;

        if (start == end) return Adj[start].Depth;
        que.Enqueue(Adj[start]);

        while (que.Count() != 0)
        {
            Node node = que.Dequeue();
            foreach (KeyValuePair<int, int> vertex in node.Vertex)
            {
                if (!Adj[vertex.Key].IsVisited)
                {
                    Adj[vertex.Key].IsVisited = true;
                    Adj[vertex.Key].Depth = node.Depth + 1;

                    if (vertex.Key == end) return Adj[vertex.Key].Depth;
                    que.Enqueue(Adj[vertex.Key]);
                }
            }
        }
        return -1;
    }
}