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
*/
// BufferedInputStream in = new BufferedInputStream(new FileInputStream(
// "C:\\CodeChef\\smundhra\\src\\lifeUniverseAndEverything\\Input"));
// System.setIn(in);
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;
Node mostPopfriend;
double minDist
= Double.
MAX_VALUE; List<Node> nodeList = new ArrayList<Node>();
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));
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;
}
}