#include <bits/stdc++.h>
using namespace std;
const long long int md = 1e9 + 7;
const int MAXN = 5e5 + 10, lg = 19;
int n, av, h[MAXN], par[lg][MAXN], parid[MAXN], cmp[MAXN], in[MAXN], out[MAXN],
    fr[MAXN], ls[MAXN], mark[MAXN];
long long int fac[MAXN], ans = 1ll, cnt;
vector<pair<int, int>> a1[MAXN];
vector<int> nd, path, adj[2][MAXN];
bool can = true, visit[MAXN];
void dfs(int v, int parv) {
  for (auto i : a1[v]) {
    int u = i.first, ind = i.second;
    if (u == parv) continue;
    h[u] = h[v] + 1;
    par[0][u] = v;
    parid[u] = ind;
    dfs(u, v);
  }
  return;
}
int findpar(int x, int v) {
  for (int i = 0; i < lg; i++)
    if ((x >> i) & 1) v = par[i][v];
  return v;
}
inline int findlca(int u, int v) {
  if (h[u] < h[v]) swap(u, v);
  u = findpar(h[u] - h[v], u);
  if (u == v) return v;
  for (int i = lg - 1; i >= 0; i--)
    if (par[i][u] != par[i][v]) u = par[i][u], v = par[i][v];
  return par[0][u];
}
void dfs2(int v, int parv) {
  visit[v] = true;
  cmp[v] = cnt;
  for (int u : adj[0][v]) {
    if (mark[u] != mark[v]) continue;
    if (visit[u] && u != parv) can = false;
    if (!visit[u]) dfs2(u, v);
  }
  for (int u : adj[1][v]) {
    if (mark[u] != mark[v]) continue;
    if (visit[u] && u != parv) can = false;
    if (!visit[u]) dfs2(u, v);
  }
  return;
}
inline int ee(int u, int v) { return ((v == par[0][u]) ? parid[u] : parid[v]); }
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    fr[i] = -1;
    ls[i] = -1;
    scanf("%d%d", &u, &v);
    u--;
    v--;
    a1[v].push_back({u, i});
    a1[u].push_back({v, i});
  }
  fac[0] = 1ll;
  fr[n - 1] = -1;
  ls[n - 1] = -1;
  for (long long int i = 1ll; i < MAXN; i++) fac[i] = (fac[i - 1] * i) % md;
  dfs(0, -1);
  for (int k = 1; k < lg; k++)
    for (int i = 0; i < n; i++) par[k][i] = par[k - 1][par[k - 1][i]];
  for (int v = 0; v < n; v++) {
    scanf("%d", &av);
    av--;
    if (av == -1) continue;
    if (av == v) {
      printf("%d", 0);
      return 0;
    }
    int lca = findlca(v, av);
    path.clear();
    if (lca == v) {
      int u = av;
      path.push_back(av);
      while (u != v) {
        u = par[0][u];
        path.push_back(u);
      }
      reverse(path.begin(), path.end());
    } else if (lca == av) {
      int v2 = v;
      path.push_back(v);
      while (v2 != av) {
        v2 = par[0][v2];
        path.push_back(v2);
      }
    } else {
      nd.clear();
      int v2 = v, u = av;
      while (v2 != lca) {
        path.push_back(v2);
        v2 = par[0][v2];
      }
      nd.push_back(u);
      while (u != lca) {
        u = par[0][u];
        nd.push_back(u);
      }
      while (!nd.empty()) {
        path.push_back(nd.back());
        nd.pop_back();
      }
    }
    int sz = (int)path.size();
    fr[path[0]] = ee(path[0], path[1]);
    ls[path[sz - 1]] = ee(path[sz - 1], path[sz - 2]);
    for (int i = 1; i < sz - 1; i++) {
      int e1 = ee(path[i - 1], path[i]), e2 = ee(path[i], path[i + 1]);
      adj[1][e1].push_back(e2);
      adj[0][e2].push_back(e1);
      if ((int)adj[1][e1].size() > 2 || (int)adj[0][e2].size() > 2) {
        printf("%d", 0);
        return 0;
      }
    }
  }
  for (int r = 0; r < n; r++) {
    if (!can) break;
    nd.clear();
    cnt = 0;
    for (auto i : a1[r]) {
      nd.push_back(i.second);
      in[i.second] = out[i.second] = 0;
      visit[i.second] = false;
      mark[i.second] = r + 1;
    }
    if (fr[r] != -1) in[fr[r]]++;
    if (ls[r] != -1) out[ls[r]]++;
    for (int i : nd) {
      for (auto u : adj[0][i])
        if (mark[u] == r + 1) in[i]++;
      for (auto u : adj[1][i])
        if (mark[u] == r + 1) out[i]++;
      if (in[i] > 1 || out[i] > 1) {
        printf("%d", 0);
        return 0;
      }
    }
    for (int i : nd) {
      if (!visit[i]) {
        dfs2(i, -1);
        cnt++;
      }
    }
    if (ls[r] != -1 && fr[r] != -1 && cmp[ls[r]] == cmp[fr[r]] && cnt > 1) {
      printf("%d", 0);
      return 0;
    }
    cnt -= (fr[r] != -1) + (ls[r] != -1);
    ans *= fac[max(0ll, cnt)];
    ans %= md;
  }
  if (!can) ans = 0;
  printf("%lld", ans);
  return 0;
}
