package info.frady.algo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.Vector;
/**
* meng3.wei 2020.04.23
2
10 2
1 2
4 2
9 7
2 7
5 6
6 8
10 6
1 3
3 8
9 3
8 10
10 5
1 3
2 4
3 5
4 6
5 7
6 8
7 9
8 10
10 1
1 2
1 3
1 4
1 5
1 6
*/
public class 两顶点之间的长度 {
public static int T;
public static int N;//顶点个数 20000以下
public static int Q;//咨询的个数 十万以下
public static int[] dep;//存放每个节点到节点1的距离
public static boolean[] visited;//存放是否访问过
public static int[] result;//存放结果
public static int visitedCount;
public static Vector<Integer>[] g;
public static int[] pid;
public static Vector<Integer>[] vect;
public static void main(String[] args) throws Exception{
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
T=Integer.parseInt(reader.readLine());//测试用例的个数
result=new int[T];
for (int d = 0; d < T; d++) {
String[] str=reader.readLine().split(" ");
N=Integer.parseInt(str[0]);
Q=Integer.parseInt(str[1]);
dep=new int[N+1];
pid=new int[N+1];
vect=new Vector[N+1];//邻接表法存储图
visited=new boolean[N+1];
for(int i=0;i<N+1;i++) {
vect[i]=new Vector<Integer>();
}
//N-1条边
for (int i = 1; i < N; i++) {//连接关系接收进来
str=reader.readLine().split(" ");
int start=Integer.parseInt(str[0]);
int end=Integer.parseInt(str[1]);
vect[start].add(end);
vect[end].add(start);
}
BFSNode();//更新层级
/*for (int i = 1; i <= N; i++) {
System.out.printf("节点 %d 的父亲节点是 %d ,深度是 %d \n",i,pid[i],dep[i]);
}*/
for (int i = 0; i <Q ; i++) {
str=reader.readLine().split(" ");
int start=Integer.parseInt(str[0]);
int end=Integer.parseInt(str[1]);
result[d]=result[d]+process(start,end);
}
}
for (int d = 0; d < T; d++) {
System.out.printf("#%d %d\n",(d+1),result[d]);
}
reader.close();
}
public static int process(int start,int end){//计算两个点的距离
if(dep[start]<dep[end]){//start比较深
int tmp=start;
start=end;
end=tmp;
}
int m=findCommonPNode(start,end);//找到共同的父亲节点
if(m==end){//两个节点是父子节点的关系
return dep[start]-dep[end];
}else{
return dep[start]+dep[end]-2*dep[m];// 不是父子节点,距离为 两个节点到公共节点距离的和
}
}
public static int findCommonPNode(int start,int end){//找个两个点的共同父节点,最差的共同节点就是顶级节点
if(dep[start]<dep[end]){//保持start比较深
int tmp=start;
start=end;
end=tmp;
}
int step=dep[start]-dep[end];
for (int i = 0; i < step; i++) {//截止到同一个等级
start=pid[start];
}
if(start==end){//start是end的子节点
return end;
}
step=dep[end];
for (int i = 0; i <step ; i++) {
start=pid[start];
end=pid[end];
if(start==end){
return start;
}
}
return 1;
}
private static void BFSNode(){
Queue<Integer> que=new LinkedList<>();
que.offer(1);//从第一个节点开始遍历
dep[1]=0;
pid[1]=1;
while(!que.isEmpty()) {
int point=que.poll();
if(!visited[point]){
visited[point]=true;//标识已经被访问了
//System.out.printf("节点 %d 被访问了 \n",point);
for (int i:vect[point]) {
if(!visited[i]){
que.offer(i);
if(dep[i]==0){
pid[i]=point;
dep[i]=dep[point]+1;
}
}
}
}
}
}
}