#include <bits/stdc++.h>
using namespace std;
char gc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
int getnum() {
  int x = 0, f = 1;
  char ch = gc();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = gc();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = gc();
  }
  return x * f;
}
const int N = 500010, mo = 1e9 + 7;
int n;
int cnt;
int par[N];
int depth[N];
int a[N];
int A[N];
int B[N];
int st[N];
int jc[N];
vector<int> G[N];
struct tnode {
  int u, v;
};
vector<tnode> F[N];
int OUT[N];
int IN[N];
int TO[N];
int vis[N];
void output() {
  printf("0");
  exit(0);
}
void addedge(int u, int v) { G[u].push_back(v); }
void get_read() {
  n = getnum();
  for (int i = 1; i <= n - 1; ++i) {
    int u = getnum(), v = getnum();
    addedge(u, v);
    addedge(v, u);
  }
  for (int i = 1; i <= n; ++i) a[i] = getnum();
}
void dfs(int u, int fa) {
  par[u] = fa;
  depth[u] = depth[fa] + 1;
  for (int i = 0, L = G[u].size(); i < L; ++i) {
    int v = G[u][i];
    if (v == fa) continue;
    dfs(v, u);
  }
}
int calc(int u, int v) {
  int LA = 0, LB = 0;
  while (depth[u] > depth[v]) A[++LA] = u, u = par[u];
  while (depth[v] > depth[u]) B[++LB] = v, v = par[v];
  while (u != v) {
    A[++LA] = u;
    u = par[u];
    B[++LB] = v;
    v = par[v];
  }
  int top = 0;
  for (int i = 1; i <= LA; ++i) st[++top] = A[i];
  st[++top] = u;
  for (int i = LB; i >= 1; --i) st[++top] = B[i];
  F[st[1]].push_back((tnode){0, st[2]});
  for (int i = 2; i <= top - 1; ++i)
    F[st[i]].push_back((tnode){st[i - 1], st[i + 1]});
  F[st[top]].push_back((tnode){st[top - 1], n + 1});
  return top - 1;
}
int solve(int u) {
  G[u].push_back(0);
  G[u].push_back(n + 1);
  for (int i = 0, L = F[u].size(); i < L; ++i) {
    tnode X = F[u][i];
    ++OUT[X.u];
    ++IN[X.v];
    TO[X.u] = X.v;
  }
  for (int i = 0, L = G[u].size(); i < L; ++i) {
    int x = G[u][i];
    if (vis[x]) continue;
    vis[x] = 1;
    while (TO[x] != -1 && !vis[TO[x]]) x = TO[x], vis[x] = 1;
    if (TO[x] == G[u][i]) output();
  }
  int cur = 0;
  while (TO[cur] != -1) cur = TO[cur];
  if (cur == n + 1 && G[u].size() - F[u].size() > 1) output();
  for (int i = 0, L = G[u].size(); i < L; ++i) {
    int x = G[u][i];
    OUT[x] = IN[x] = vis[x] = 0;
    TO[x] = -1;
  }
  return max((int)G[u].size() - (int)F[u].size() - 2, 0);
}
void get_work() {
  dfs(1, 0);
  int ret = 0;
  for (int i = 1; i <= n; ++i) {
    if (a[i]) {
      if (a[i] == i) output();
      ret += calc(a[i], i);
      if (ret > 2 * n - 2) output();
    }
  }
  jc[0] = 1;
  for (int i = 1; i <= n; ++i) jc[i] = 1LL * jc[i - 1] * i % mo;
  int sum = 1;
  memset(TO, -1, sizeof(TO));
  for (int i = 1; i <= n; ++i) {
    sum = 1LL * sum * jc[solve(i)] % mo;
  }
  printf("%d", sum);
}
int main() {
  get_read();
  get_work();
  return 0;
}
