import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;

class Main {
	
	public static void main (String [] args) throws Exception {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		int testCaseCount=Integer.parseInt(br.readLine());
		for (int testCase=0;testCase<testCaseCount;testCase++) {
			boolean [][] edges=new boolean [26][26];
			String s;
			while ((s=br.readLine()).charAt(0)!='*') {
				edges[s.charAt(1)-'A'][s.charAt(3)-'A']=true;
				edges[s.charAt(3)-'A'][s.charAt(1)-'A']=true;
			}
			
			boolean [] nodeExists=new boolean [26];
			StringTokenizer st=new StringTokenizer(br.readLine(), ",");
			while (st.hasMoreTokens()) nodeExists[st.nextToken().charAt(0)-'A']=true;
			
			int acronsCount=0, treeCount=0;
			boolean [] visited=new boolean[26];
			for (int i=0;i<26;i++) if (nodeExists[i] && !visited[i]) {
				int edgesCount=0;
				for (int e=0;e<26;e++) if (edges[i][e]) edgesCount++;
				if (edgesCount==0) {
					visited[i]=true;
					acronsCount++;
				} else {
					boolean tree=true;
					LinkedList<Integer> queue=new LinkedList<>();
					queue.add(i);
					
					boolean [][] edgeVisited=new boolean[26][26];
					while (queue.size()>0) {
						int currI=queue.removeFirst();
						if (visited[currI]) {
							tree=false;
							break;
						} else {
							visited[currI]=true;
							for (int e=0;e<26;e++) if (edges[currI][e] && !edgeVisited[currI][e] && !edgeVisited[e][currI]) {
								queue.add(e);
								edgeVisited[currI][e]=true;
								edgeVisited[e][currI]=true;
							}
						}
					}
					if (tree) treeCount++;
				}
			}
			
			StringBuilder sb=new StringBuilder();
			sb.append("There are ");
			sb.append(treeCount);
			sb.append(" tree(s) and ");
			sb.append(acronsCount);
			sb.append(" acorn(s).");
			System.out.println(sb.toString());
		}
		
	}

}