import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * @author smundhra
 * 
 */

/*
 
 */
public class Main {

	/**
	 * @param args
	 * @throws IOException
	 * @throws NumberFormatException
	 */
	public static void main(String[] args) throws NumberFormatException,
			IOException {

		// BufferedInputStream in = new BufferedInputStream(new FileInputStream(
		// "C:\\CodeChef\\smundhra\\src\\lifeUniverseAndEverything\\Input"));
		// System.setIn(in);

		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(new BufferedWriter(
				new OutputStreamWriter(System.out)));

		int t = Integer.parseInt(bf.readLine());
		// long t1 = System.currentTimeMillis();
		while (t > 0) {
			Graph g = new Graph(bf);
			for (Node n : g.hm.keySet())
				g.getAvgDistance(n);
			pw.printf(g.mostPopfriend.getN() + " " + "%f" + "\n", g
					.getMinDist());

			t--;

		}
		pw.flush();
		bf.close();
		// long diff = System.currentTimeMillis() - t1;
		// pw.print(diff);
		pw.close();

	}

}

class Node {

	int n;
	int distance;

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + n;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Node other = (Node) obj;
		if (n != other.n)
			return false;
		return true;
	}

	public int getDistance() {
		return distance;
	}

	public void setDistance(int distance) {
		this.distance = distance;
	}

	public int getN() {
		return n;
	}

	public void setN(int n) {
		this.n = n;
	}

	public Node(int n) {
		this.n = n;
	}

	private boolean isVisited;

	public boolean isVisited() {
		return isVisited;
	}

	public void setVisited(boolean isVisited) {
		this.isVisited = isVisited;
	}

}

class Graph {
	int nodeCount;
	public HashMap<Node, ArrayList<Node>> hm;
	Integer[] s;
	Node mostPopfriend;
	double minDist = Double.MAX_VALUE;
	List<Node> nodeList = new ArrayList<Node>();

	public Graph(BufferedReader bf) throws NumberFormatException, IOException {
		this.nodeCount = Integer.parseInt(bf.readLine());

		hm = new HashMap<Node, ArrayList<Node>>();
		int i;

		for (i = 1; i <= nodeCount; i++) {
			Node node = new Node(i);
			nodeList.add(node);
			hm.put(node, new ArrayList<Node>());
		}
		for (i = 1; i <= nodeCount; i++) {
			String a[] = bf.readLine().split(" ");
			List<Node> l = hm.get(new Node(i));

			for (String s : a) {
				l.add(nodeList.get(Integer.parseInt(s) - 1));
			}
		}
	}

	public void getAvgDistance(Node head) {
		for (Node node : hm.keySet()) {
			node.setVisited(false);
			node.setDistance(0);
		}

		double totalDist = 0D;

		Queue<Node> q = new LinkedList<Node>();
		q.add(head);
		head.setVisited(true);
		while (!q.isEmpty()) {
			Node node = q.poll();

			for (Node n1 : hm.get(node)) {
				if (n1 == null)
					break;
				if (!n1.isVisited()) {
					n1.setDistance(node.getDistance() + 1);
					n1.setVisited(true);
					q.add(n1);
					totalDist += n1.getDistance();
				}
			}
		}
		double avgDistance = totalDist / (double) nodeCount;
		if (avgDistance <= this.minDist) {
			this.minDist = avgDistance;
			this.mostPopfriend = head;
		} else if (avgDistance == this.minDist) {
			if (this.mostPopfriend == null)
				this.mostPopfriend = head;
			if (this.mostPopfriend.getN() > head.getN())
				this.mostPopfriend = head;
		}

	}

	public double getMinDist() {
		return minDist;
	}
}