import sys from collections import deque # 最小染色数量,为红线(两个标记点有相连)的数量 # 方案数量,是与红线有相连的未染色边的数量,并除以模MOD # 由于染色方案数量可能很大,请输出对10^9+7取模后的结果 MOD = 10 ** 9 + 7 def main(): input_l = sys.stdin.read().split() # 输入列表,存的数字字符 ["1","2"] ptr = 0 # 坐标指针 n, k = map(int, input_l[ptr:ptr + 2]) # 总节点数n(编号1~n), 标记的节点数k ptr += 2 # 坐标指针后移2 marked = list(map(int, input_l[ptr:ptr + k])) # 读第二行输入的k个标记点的编号 [8,2,4,7,9,6] ptr += k # 坐标指针后移k marked_set = set(marked) # 生成集合,自动去重并按照默认升序排序{2, 4, 6, 7, 8, 9} # 构建邻接表,第n个表表示节点编号n的相邻点[[],[3,8,11],[],[1]] adj = [[] for _ in range(n + 1)] # 构建邻接对所有边[(u0,v0),(u1,v1)] edges = [] for _ in range(n - 1): # 读入节点连接情况 u, v = map(int, input_l[ptr:ptr + 2]) ptr += 2 # 邻接表adj第u位[]里加入节点v adj[u].append(v) # 邻接表adj第v位[]里加入节点u adj[v].append(u) # 邻接对edges加入 edges.append((u, v)) # 使用自环边找到标记节点的连通分量 parent = [0] * (n + 1) # [0,0,0] # 访问标志表 visited = [False] * (n + 1) # [False,False,False] # 大组件列表存所有红线小列表[[8,9][2,4][7,6]] components = [] # 遍历所有已经标记的k个点的编号 for node in marked: # 如果没访问过 if not visited[node]: queue = deque() # 定义双端列表queue # 将当前循环的已标记节点编号,从最右端加入双端列表 queue.append(node) # 将编号对应的内容置位,不会再重复访问 visited[node] = True # 小组件列表,存每个红线[8,9] component = [] # 双端列表非空时(有当前循环节点或其相邻节的1至多个点) while queue: # 最左的点取出给u u = queue.popleft() # 将u写入当前已标记节点的小组件列表 component.append(u) # 遍历第adj列表的第u个列表,v为u所有相邻的节点编号 for v in adj[u]: # 如果该节点未被访问过,且v也是是被标记的节点,则两点连线为红线 # 访问并把父列表的v编号位置写为u if not visited[v] and v in marked_set: # 检查边缘是否自动变红(两者都标记) # 访问并把标志列表置位 visited[v] = True # 将父列表的第v位写入编号u parent[v] = u # 将该节点v加入双端列表最右侧,等待出栈 queue.append(v) # 将小组件加入大组件列表 components.append(component) # 组件编号表为[-1,-1,-1],节点存红边在components列表里的索引[-1,...,0,0,...](边8~9) component_id = [-1] * (n + 1) # 遍历大组件表,同时取组件列表的编号idx和值小列表comp for idx, comp in enumerate(components): # 遍历当前小组件列表 for node in comp: # 将组件编号表的该节点对应的位置的改成小组件列表在大组件列表里的编号 component_id[node] = idx # 边界计数列表[2,0,0]编号第i的红线有n条相邻的黑边 boundary_counts = [0] * len(components) # 取出初始化的所有边的节点对 for u, v in edges: # 若u和v中有1个未标记的节点 if (u in marked_set) != (v in marked_set): # 边界边缘 # 如果u已经标记 if u in marked_set: # 已标记点遍历写入u marked_node = u # unmarked_node = v # 如果v已经标记 else: # # 已标记点遍历写入v marked_node = v # unmarked_node = u # 取组件编号表里,该已标记节点位位对应的值 cid = component_id[marked_node] # 作为边界计数表的索引,并让对应值自增1 boundary_counts[cid] += 1 # 最小染色代价为红边数 min_cost = len(components) # 染色方案数初始化为1 num_ways = 1 # 遍历边界计数列表,染色方案数依次乘以每红边对应的黑边数边,并对10^9+7取模 for cnt in boundary_counts: num_ways = num_ways * cnt % MOD print(min_cost, num_ways) if __name__ == '__main__': main()