#include <bits/stdc++.h>
template <typename T>
inline T max(T a, T b) {
  return a > b ? a : b;
}
template <typename T>
inline T min(T a, T b) {
  return a < b ? a : b;
}
template <typename T>
inline T abs(T a) {
  return a > 0 ? a : -a;
}
template <typename T>
inline bool repr(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T>
inline bool repl(T &a, T b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T>
inline T gcd(T a, T b) {
  T t;
  if (a < b) {
    while (a) {
      t = a;
      a = b % a;
      b = t;
    }
    return b;
  } else {
    while (b) {
      t = b;
      b = a % b;
      a = t;
    }
    return a;
  }
}
template <typename T>
inline T sqr(T x) {
  return x * x;
}
struct Cg {
  __attribute__((always_inline)) inline char operator()() { return getchar(); }
};
struct Cp {
  __attribute__((always_inline)) inline void operator()(char x) { putchar(x); }
};
__attribute__((always_inline)) inline bool IS(char x) {
  return x == 10 || x == 13 || x == ' ';
}
template <typename T>
struct Fr {
  T P;
  __attribute__((always_inline)) inline Fr &operator,(int &x) {
    x = 0;
    unsigned char t = P();
    while ((t < '0' || t > '9') && t != '-') t = P();
    bool f = 0;
    if (t == '-') t = P(), f = 1;
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    if (f) x = -x;
    return *this;
  }
  __attribute__((always_inline)) inline operator int() {
    int x;
    *this, x;
    return x;
  }
  __attribute__((always_inline)) inline Fr &operator,(long long &x) {
    x = 0;
    unsigned char t = P();
    while ((t < '0' || t > '9') && t != '-') t = P();
    bool f = 0;
    if (t == '-') t = P(), f = 1;
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    if (f) x = -x;
    return *this;
  }
  __attribute__((always_inline)) inline operator long long() {
    long long x;
    *this, x;
    return x;
  }
  __attribute__((always_inline)) inline Fr &operator,(char &x) {
    for (x = P(); IS(x); x = P())
      ;
    return *this;
  }
  __attribute__((always_inline)) inline operator char() {
    char x;
    *this, x;
    return x;
  }
  __attribute__((always_inline)) inline Fr &operator,(char *x) {
    char t = P();
    for (; IS(t); t = P())
      ;
    if (~t) {
      for (; !IS(t) && ~t; t = P()) *x++ = t;
    }
    *x++ = 0;
    return *this;
  }
  __attribute__((always_inline)) inline Fr &operator,(double &x) {
    x = 0;
    unsigned char t = P();
    while ((t < '0' || t > '9') && t != '-') t = P();
    bool f = 0;
    if (t == '-') t = P(), f = 1;
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    if (t == '.') {
      double u = 0.1;
      for (t = P(); t >= '0' && t <= '9'; t = P(), u *= 0.1) x += u * (t - '0');
    }
    if (f) x = -x;
    return *this;
  }
  __attribute__((always_inline)) inline operator double() {
    double x;
    *this, x;
    return x;
  }
  __attribute__((always_inline)) inline Fr &operator,(long double &x) {
    x = 0;
    unsigned char t = P();
    while ((t < '0' || t > '9') && t != '-') t = P();
    bool f = 0;
    if (t == '-') t = P(), f = 1;
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    if (t == '.') {
      double u = 0.1;
      for (t = P(); t >= '0' && t <= '9'; t = P(), u *= 0.1) x += u * (t - '0');
    }
    if (f) x = -x;
    return *this;
  }
  __attribute__((always_inline)) inline operator long double() {
    long double x;
    *this, x;
    return x;
  }
  __attribute__((always_inline)) inline Fr &operator,(unsigned int &x) {
    x = 0;
    unsigned char t = P();
    while (t < '0' || t > '9') t = P();
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    return *this;
  }
  __attribute__((always_inline)) inline operator unsigned int() {
    unsigned int x;
    *this, x;
    return x;
  }
  __attribute__((always_inline)) inline Fr &operator,(unsigned long long &x) {
    x = 0;
    unsigned char t = P();
    while (t < '0' || t > '9') t = P();
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    return *this;
  }
  __attribute__((always_inline)) inline operator unsigned long long() {
    unsigned long long x;
    *this, x;
    return x;
  }
};
Fr<Cg> in;
template <typename T>
struct Fw {
  T P;
  __attribute__((always_inline)) inline Fw &operator,(int x) {
    if (x) {
      if (x < 0) P('-'), x = -x;
      unsigned char s[10], c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator()(int x) {
    if (x) {
      if (x < 0) P('-'), x = -x;
      unsigned char s[10], c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator,(unsigned int x) {
    if (x) {
      unsigned char s[10], c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator()(unsigned int x) {
    if (x) {
      unsigned char s[10], c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator,(long long x) {
    if (x) {
      if (x < 0) P('-'), x = -x;
      unsigned char s[19], c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator()(long long x) {
    if (x) {
      if (x < 0) P('-'), x = -x;
      unsigned char s[19], c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator,(unsigned long long x) {
    if (x) {
      unsigned char s[20], c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator()(unsigned long long x) {
    if (x) {
      unsigned char s[20], c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator,(char x) {
    P(x);
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator()(char x) {
    P(x);
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator,(const char *x) {
    while (*x) P(*x++);
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator()(const char *x) {
    while (*x) P(*x++);
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator()(double x, int y) {
    if (y) {
      double t = 0.5;
      for (int i = y; i--;) t *= 0.1;
      if (x >= 0)
        x += t;
      else
        x -= t, P('-');
      *this, (long long)(abs(x));
      P('.');
      if (x < 0) x = -x;
      while (y--) {
        x *= 10;
        x -= floor(x * 0.1) * 10;
        P(((int)x) % 10 + '0');
      }
    } else if (x >= 0)
      *this, (long long)(x + 0.5);
    else
      *this, (long long)(x - 0.5);
    ;
    return *this;
  }
  __attribute__((always_inline)) inline Fw &operator()(long double x, int y) {
    if (y) {
      double t = 0.5;
      for (int i = y; i--;) t *= 0.1;
      if (x >= 0)
        x += t;
      else
        x -= t, P('-');
      *this, (long long)(abs(x));
      P('.');
      if (x < 0) x = -x;
      while (y--) {
        x *= 10;
        x -= floor(x * 0.1) * 10;
        P(((int)x) % 10 + '0');
      }
    } else if (x >= 0)
      *this, (long long)(x + 0.5);
    else
      *this, (long long)(x - 0.5);
    ;
    return *this;
  }
};
Fw<Cp> out;
const int N = 500007, P = 1000000007;
std::vector<int> p[N];
int n, idm, s[N], fa[N], dep[N], id[N], sz[N], ws[N], top[N], f[N * 2],
    mask[N * 2], fsz[N * 2], fac[N], si[N], so[N];
bool fu[N], fv[N];
inline int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
inline void dfs(int x) {
  sz[x] = 1;
  int y = 0;
  for (__typeof((p[x]).end()) i = (p[x]).begin(); i != (p[x]).end(); ++i)
    if (*i != fa[x]) {
      fa[*i] = x;
      dep[*i] = dep[x] + 1;
      dfs(*i);
      sz[x] += sz[*i];
      if (repr(y, sz[*i])) ws[x] = *i;
    }
}
inline void dfs2(int x, int y) {
  top[x] = y;
  id[x] = ++idm;
  if (ws[x]) dfs2(ws[x], y);
  for (__typeof((p[x]).end()) i = (p[x]).begin(); i != (p[x]).end(); ++i)
    if (*i != fa[x] && *i != ws[x]) dfs2(*i, *i);
}
inline int lca(int a, int b) {
  while (top[a] != top[b]) {
    if (dep[top[a]] > dep[top[b]]) std::swap(a, b);
    b = fa[top[b]];
  }
  return dep[a] < dep[b] ? a : b;
}
inline int getx(int a, int b) {
  while (fa[a] != b) a = fa[a];
  return a;
}
inline bool used(int a, int b) {
  if (fa[a] == b) return fu[a];
  return fv[b];
}
inline void wa() {
  out, 0, '\n';
  exit(0);
}
inline int idd(int x, int y) {
  if (fa[x] == y) return x + n;
  return y;
}
inline void conn(int x, int y, int z) {
  y = find(idd(x, y));
  z = find(idd(x, z));
  if (y == z) wa();
  f[y] = z;
}
int main() {
  fac[0] = 1;
  for (int i = 1, iend = N - 1; i <= iend; i++)
    fac[i] = (long long)fac[i - 1] * i % P;
  in, n;
  for (int i = 1, iend = n - 1; i <= iend; i++) {
    int x, y;
    in, x, y;
    p[x].push_back(y);
    p[y].push_back(x);
  }
  for (int i = 1, iend = n; i <= iend; i++) in, s[i];
  dfs(1);
  dfs2(1, 1);
  for (int i = 1, iend = n * 2; i <= iend; i++) f[i] = i;
  for (int i = 1, iend = n; i <= iend; i++)
    if (s[i]) {
      int x = i, y = s[i], z = lca(x, y);
      if (x == y) wa();
      auto linkup = [&](int a, int b) {
        for (int i = a; i != b; i = fa[i]) {
          if (fu[i]) wa();
          fu[i] = 1;
        }
        for (; fa[a] != b; a = fa[a]) conn(fa[a], a, fa[fa[a]]);
      };
      auto linkdown = [&](int a, int b) {
        for (int i = a; i != b; i = fa[i]) {
          if (fv[i]) wa();
          fv[i] = 1;
        }
        for (; fa[a] != b; a = fa[a]) conn(fa[a], a, fa[fa[a]]);
      };
      if (si[x]) wa();
      if (so[y]) wa();
      if (x == z) {
        linkdown(y, z);
        si[x] = getx(y, z);
        so[y] = fa[y];
      } else if (y == z) {
        linkup(x, z);
        si[x] = fa[x];
        so[y] = getx(x, z);
      } else {
        si[x] = fa[x];
        so[y] = fa[y];
        linkup(x, z);
        linkdown(y, z);
        x = getx(x, z);
        y = getx(y, z);
        conn(z, x, y);
      }
    }
  int ans = 1;
  for (int i = 1, iend = n; i <= iend; i++) {
    for (__typeof((p[i]).end()) j = (p[i]).begin(); j != (p[i]).end(); ++j) {
      mask[find(idd(i, *j))] |= (si[i] == *j) + (so[i] == *j) * 2;
      fsz[find(idd(i, *j))]++;
    }
    std::vector<std::pair<int, int> > t;
    for (__typeof((p[i]).end()) j = (p[i]).begin(); j != (p[i]).end(); ++j)
      if (find(idd(i, *j)) == idd(i, *j)) {
        t.push_back(std::make_pair(fsz[idd(i, *j)], mask[idd(i, *j)]));
      }
    for (__typeof((t).end()) j = (t).begin(); j != (t).end(); ++j) {
      if (j->second == 3) {
        if (j->first != p[i].size()) wa();
        goto ok;
      }
    }
    {
      int ta, uc = 0;
      for (__typeof((t).end()) j = (t).begin(); j != (t).end(); ++j)
        if (j->second) uc++;
      if (!uc) {
        ta = fac[t.size()];
      } else if (uc == 1) {
        ta = fac[t.size() - 1];
      } else {
        ta = fac[t.size() - 2];
      }
      ans = (long long)ans * ta % P;
    }
  ok:;
  }
  out, ans, '\n';
}
