import sys
# 定义模数和数组大小
mod = int(1e4 + 7) # 模数,用于取余运算
N = 200010 # 节点数量的最大值
M = N * 2 # 边的数量的最大值(无向图每条边存两次)
# 图的邻接表表示
h = [-1] * N # h[a] 存储节点a的第一条边的索引
e = [0] * M # e[idx] 存储边的终点节点
ne = [0] * M # ne[idx] 存储下一条边的索引
idx = 0 # 当前边的索引
# 节点权重和结果变量
w = [0] * N # w[i] 存储节点i的权重
ans_max = 0 # 存储最大乘积结果
ans_sum = 0 # 存储乘积和的结果
f = [0] * N # f[u] 存储以u为根的子树中节点的最大权重
g = [0] * N # g[u] 存储以u为根的子树中节点权重的和
# 添加边到邻接表
def add(a, b):
global idx
e[idx] = b # 记录边的终点
ne[idx] = h[a] # 将新边插入到链表头部
h[a] = idx # 更新头指针
idx += 1
# 深度优先搜索
def dfs(u, fa):
global ans_max, ans_sum
sum = 0 # 当前子树中已处理子节点的权重和
maxv = 0 # 当前子树中已处理子节点的最大权重
# 遍历u的所有邻接节点
i = h[u]
while i != -1:
j = e[i] # 邻接节点j
if j != fa: # 避免回溯到父节点
dfs(j, u) # 递归处理子节点
# 更新最大乘积结果
ans_max = max(ans_max, w[u] * f[j]) # u的权重与子树j中最大权重的乘积
ans_max = max(ans_max, maxv * w[j]) # 已处理子节点最大权重与当前子节点权重的乘积
maxv = max(maxv, w[j]) # 更新已处理子节点的最大权重
# 更新乘积和结果
ans_sum = (ans_sum + w[u] * g[j]) % mod # u的权重与子树j权重和的乘积
ans_sum = (ans_sum + sum * w[j]) % mod # 已处理子节点权重和与当前子节点权重的乘积
sum = (sum + w[j]) % mod # 更新已处理子节点的权重和
# 更新f和g数组
f[u] = max(f[u], w[j]) # 更新子树u中的最大权重
g[u] = (g[u] + w[j]) % mod # 更新子树u中的权重和
i = ne[i] # 处理下一条边
# 主程序
n = int(input()) # 读取节点数量
# 读取并构建树结构
for i in range(n - 1):
a, b = map(int, input().split())
add(a, b) # 添加无向边
add(b, a)
# 读取节点权重(注意w[0]未使用,节点编号从1开始)
w = [0] + list(map(int, input().split())
# 从根节点1开始DFS遍历
dfs(1, -1)
# 输出结果(ans_sum需要乘以2,因为每对节点被计算了两次)
print(ans_max, ans_sum * 2 % mod)