import sys
from collections import deque

# 由于染色方案数量可能很大,请输出对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, 标记的节点数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}

    # 构建邻接表[[],[1],[],[3]]
    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位[]里加入节点u
        adj[u].append(v)
        # 邻接表adj第v位[]里加入节点v
        adj[v].append(u)
        # 邻接对edges加入
        edges.append((u, v))

    # 使用自环边找到标记节点的连通分量

    parent = [0] * (n + 1)  # [0,0,0]
    visited = [False] * (n + 1)  # [False,False,False]
    # 大组件列表
    components = []

    # 遍历所有已经标记的k个点的编号
    for node in marked:
        # 如果没访问过
        if not visited[node]:
            # 定义双端列表queue
            queue = deque()
            # 将当前循环的节点编号,从最右端加入双端列表
            queue.append(node)
            # 将编号对应的内容置位
            visited[node] = True
            # 小组件列表
            component = []
            # 双端列表非空时
            while queue:
                # 最左的点的编号取出给u
                u = queue.popleft()
                # 将u加入小组件列表
                component.append(u)
                # 遍历第adj列表的第u个列表,v为列表里的节点编号
                for v in adj[u]:
                    # 如果该节点未被访问过,且v是被标记的节点
                    if not visited[v] and v in marked_set:
                        # 检查边缘是否自动变红(两者都标记)
                        # 访问并把标志列表置位
                        visited[v] = True
                        # 将父列表的第v位写入编号u
                        parent[v] = u
                        # 将该节点加入双端列表最右侧,等待出栈
                        queue.append(v)
            # 将小组件加入大组件列表
            components.append(component)

    # 对于每个组件,找到边界边缘(标记为u的,未标记为v的)
    # 组件边界表
    # component_boundary = [0] * len(components)

    # 遍历所有的边缘,找到边界边缘。
    # 计算将组件中标记的节点与未标记的节点连接起来的数量
    # 将每个标记节点分配给其组件索引

    # 组件编号表为[-1,-1,-1]
    component_id = [-1] * (n + 1)
    # 遍历大组件表,同时取组件列表的编号idx和值小列表comp
    for idx, comp in enumerate(components):
        # 遍历当前小组件列表
        for node in comp:
            # 将组件编号表的该节点对应的位置的改成小组件列表在大组件列表里的编号
            component_id[node] = idx

    # 边界计数列表[0,0,0]
    boundary_counts = [0] * len(components)
    # 取出初始化的边界值对
    for u, v in edges:
        # 若u和v其中有未标记的节点
        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()