#include <bits/stdc++.h>
template <typename T>
T gcd(T a, T b) {
  return ((a % b == 0) ? b : gcd(b, a % b));
}
template <typename T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
using LL = long long;
constexpr LL LINF = 334ll << 53;
constexpr int INF = 15 << 26;
constexpr LL MOD = 998244353;
namespace Problem {
using namespace std;
struct Edge {
  int from, to;
  Edge(int from, int to) : from(from), to(to){};
  Edge() { Edge(0, 0); }
};
bool operator<(Edge a, Edge b) { return a.to < b.to; }
bool operator==(Edge a, Edge b) { return a.to == b.to; }
using Graph = vector<vector<Edge>>;
struct HeavyLightDecomposition {
  vector<int> index, htop, hchild, par, dep, idtov, topo, sub, heads;
  Graph T;
  HeavyLightDecomposition(int n)
      : index(n, -1),
        htop(n),
        hchild(n, -1),
        par(n),
        dep(n),
        idtov(n),
        sub(n),
        T(n) {}
  void add_edge(int a, int b) {
    T[a].push_back(Edge(a, b));
    T[b].push_back(Edge(b, a));
  }
  void calc(int root) {
    queue<int> Q({root});
    par[root] = -1;
    while (!Q.empty()) {
      int curr = Q.front();
      Q.pop();
      topo.push_back(curr);
      for (auto &x : T[curr]) {
        if (x.to != par[curr]) {
          par[x.to] = curr;
          Q.push(x.to);
          dep[x.to] = dep[curr] + 1;
        }
      }
    }
    for (int i = par.size() - 1, max_sub = 0; i >= 0; --i) {
      ++sub[topo[i]];
      if (i > 0) sub[par[topo[i]]] += sub[topo[i]];
      if (i > 0 and i < par.size() - 1)
        if (par[topo[i + 1]] != par[topo[i]]) max_sub = 0;
      if (i > 0 and sub[topo[i]] > max_sub) {
        hchild[par[topo[i]]] = topo[i];
        max_sub = sub[topo[i]];
      }
      for (auto &x : T[topo[i]])
        if (x.to != par[topo[i]] and x.to != hchild[topo[i]])
          heads.push_back(x.to);
    }
    heads.push_back(root);
    reverse(heads.begin(), heads.end());
    int id = 0;
    for (int x : heads) {
      for (int i = x; i != -1; i = hchild[i]) {
        index[i] = id++;
        idtov[index[i]] = i;
        htop[i] = x;
      }
    }
  }
  bool same(int a, int b) { return htop[a] == htop[b]; }
  int lca(int a, int b) {
    if (index[a] > index[b]) swap(a, b);
    if (same(a, b)) return a;
    return lca(a, par[htop[b]]);
  }
  int dist(int a, int b) { return dep[a] + dep[b] - 2 * dep[lca(a, b)]; }
  int &operator[](size_t i) { return index[i]; }
  const int &operator[](size_t i) const { return index[i]; }
};
template <long long Mod = MOD>
class Modint {
 public:
  long long v;
  Modint(const Modint &x) { v = x.v; }
  explicit Modint(int x) {
    if (x < 0 or Mod <= x) x %= Mod;
    if (x < 0) x += Mod;
    v = x;
  }
  explicit Modint(long long x) {
    if (x < 0 or Mod <= x) x %= Mod;
    if (x < 0) x += Mod;
    v = x;
  }
  explicit Modint(unsigned x) {
    if (Mod <= x) x %= Mod;
    v = x;
  }
  explicit Modint(unsigned long long x) {
    if (Mod <= x) x %= Mod;
    v = x;
  }
  template <typename T>
  explicit Modint(T x) {
    if (x < 0 or Mod <= x) x %= Mod;
    v = x;
  }
  Modint() : v(0) {}
  long long get() const { return v; }
  Modint mpow(Modint &n) const { return mpow(n.v); }
  Modint mpow(long long n) const {
    long long i = 1, p = v;
    Modint ret(1);
    while (i <= n) {
      if (i & n) ret *= p;
      i = (i << 1);
      p = (p * p) % Mod;
    }
    return ret;
  }
  Modint operator-() const { return (v ? Modint(Mod - v) : Modint(0)); }
  explicit operator int() const { return v; }
  explicit operator long long() const { return v; }
  Modint &operator+=(const Modint &a) {
    v = (v + a.v);
    if (v >= Mod) v -= Mod;
    return *this;
  }
  Modint &operator-=(const Modint &a) {
    v = (v - a.v);
    if (v < 0) v += Mod;
    return *this;
  }
  Modint &operator*=(const Modint &a) {
    v = (v * a.v) % Mod;
    return *this;
  }
  Modint &operator/=(const Modint &a) {
    v = (v * a.mpow(Mod - 2).v) % Mod;
    return *this;
  }
  template <class T>
  Modint &operator+=(const T &a) {
    v = (v + Modint(a).v);
    if (v >= Mod) v -= Mod;
    return *this;
  }
  template <class T>
  Modint &operator-=(const T &a) {
    v = (v - Modint(a).v);
    if (v < 0) v += Mod;
    return *this;
  }
  template <class T>
  Modint &operator*=(const T &a) {
    v = (v * Modint(a).v) % Mod;
    return *this;
  }
  template <class T>
  Modint &operator/=(const T &a) {
    v = (v * Modint(a).mpow(Mod - 2).v) % Mod;
    return *this;
  }
  friend Modint operator+(const Modint &a, const Modint &b) {
    return Modint(a) += b;
  }
  friend Modint operator-(const Modint &a, const Modint &b) {
    return Modint(a) -= b;
  }
  friend Modint operator*(const Modint &a, const Modint &b) {
    return Modint(a) *= b;
  }
  friend Modint operator/(const Modint &a, const Modint &b) {
    return Modint(a) /= b;
  }
  template <class T, class U>
  friend Modint operator+(const T &a, const U &b) {
    return Modint(a) += Modint(b);
  }
  template <class T, class U>
  friend Modint operator-(const T &a, const U &b) {
    return Modint(a) -= Modint(b);
  }
  template <class T, class U>
  friend Modint operator*(const T &a, const U &b) {
    return Modint(a) *= Modint(b);
  }
  template <class T, class U>
  friend Modint operator/(const T &a, const U &b) {
    return Modint(a) /= Modint(b);
  }
};
template <long long M>
ostream &operator<<(ostream &os, const Modint<M> m) {
  return os << m.v;
}
class Solver2 {
 public:
  int n, k;
  HeavyLightDecomposition hld;
  vector<int> color;
  vector<int> lca;
  vector<vector<int>> cid;
  Graph t;
  vector<vector<Modint<>>> dp;
  Solver2(LL n, LL k)
      : n(n),
        k(k),
        hld(n),
        color(n),
        lca(k + 1),
        cid(k + 1),
        dp(n, vector<Modint<>>(2)){};
  void solve() {
    for (int i = 0; i < n; ++i) {
      cin >> color[i];
      cid[color[i]].push_back(i);
    }
    for (int i = 0; i < n - 1; ++i) {
      int a, b;
      cin >> a >> b;
      hld.add_edge(--a, --b);
    }
    hld.calc(0);
    for (int i = 1; i <= k; ++i) {
      lca[i] = cid[i][0];
      for (int j = 1; j < cid[i].size(); ++j) {
        ;
        lca[i] = hld.lca(lca[i], cid[i][j]);
        ;
      }
    };
    t = hld.T;
    if (dfs_paint(0) == -1) {
      cout << 0 << endl;
      return;
    }
    for (int i = 1; i <= k; ++i) {
      cid[i].clear();
    }
    for (int i = 0; i < n; ++i) {
      cid[color[i]].push_back(i);
    };
    vector<int> convert(n);
    for (int i = 0; i < n; ++i) {
      if (color[i] > 0)
        convert[i] = cid[color[i]][0];
      else
        convert[i] = i;
    };
    Graph t2(n);
    for (int i = 0; i < n; ++i) {
      for (auto &&e : t[i]) {
        if (convert[e.from] != convert[e.to]) {
          t2[convert[e.from]].emplace_back(convert[e.from], convert[e.to]);
        }
      }
    }
    swap(t, t2);
    for (int i = 0; i < n; ++i) {
      sort(t[i].begin(), t[i].end());
      t[i].erase(unique(t[i].begin(), t[i].end()), t[i].end());
    }
    dfs_dp(0);
    ;
    cout << dp[0][1] << endl;
  }
  void dfs_dp(int c, int p = -1) {
    ;
    if (color[c] == 0) {
      dp[c][1] = Modint<>(0);
      dp[c][0] = Modint<>(1);
      for (auto e : t[c]) {
        if (e.to != p) {
          dfs_dp(e.to, c);
          dp[c][1] =
              dp[c][1] * (dp[e.to][0] + dp[e.to][1]) + dp[c][0] * dp[e.to][1];
          dp[c][0] *= (dp[e.to][0] + dp[e.to][1]);
        }
      }
    } else {
      dp[c][1] = Modint<>(1);
      for (auto e : t[c]) {
        if (e.to != p) {
          dfs_dp(e.to, c);
          dp[c][1] *= (dp[e.to][0] + dp[e.to][1]);
        }
      }
    }
  }
  int dfs_paint(int c, int p = -1) {
    set<int> tmp;
    if (color[c] > 0) tmp.insert(color[c]);
    for (auto e : t[c]) {
      if (e.to != p) {
        int res = dfs_paint(e.to, c);
        if (res == -1) return -1;
        if (res > 0) tmp.insert(res);
      }
    };
    if (tmp.size() > 1) return -1;
    if (tmp.size() == 1) color[c] = *tmp.begin();
    if (color[c] != 0 && lca[color[c]] != c) {
      return color[c];
    } else {
      return 0;
    }
  }
};
}  // namespace Problem
int main() {
  std::cin.tie(0);
  std::ios_base::sync_with_stdio(false);
  long long n = 0, m;
  std::cin >> n >> m;
  Problem::Solver2 sol(n, m);
  sol.solve();
  return 0;
}
