#include <bits/stdc++.h>
using namespace std;
struct READ {
  int d1, d2, d3;
  READ(int d1 = -1, int d2 = -1, int d3 = -1) : d1(d1), d2(d2), d3(d3) {}
  template <class T>
  operator T() {
    T tmp;
    this->read(tmp);
    return tmp;
  }
  template <class T>
  void read(T &t) {
    cin >> t;
  }
  template <class T>
  void read(vector<T> &cont) {
    assert(d1 != -1);
    cont.resize(d1);
    READ r(d2, d3);
    for (int i = 0; i < d1; ++i) r.read(cont[i]);
  }
  template <class T1, class T2>
  void read(pair<T1, T2> &x) {
    read(x.first);
    read(x.second);
  }
};
struct Node {
  int color = -1;
  int index = -1;
  int depth = -1;
  Node *parent = nullptr;
  vector<Node *> children;
  int64_t fc = 0;
  int64_t fp = 0;
};
vector<Node *> buildTree(vector<int> &colors, vector<pair<int, int>> &edges) {
  vector<Node *> nodes(colors.size());
  for (int i = 0; i < nodes.size(); ++i) {
    nodes[i] = new Node;
    nodes[i]->color = colors[i];
    nodes[i]->index = i;
  }
  nodes[0]->depth = 0;
  vector<vector<int>> edgeByNode(nodes.size());
  for (auto &e : edges) {
    edgeByNode[e.first - 1].push_back(e.second - 1);
    edgeByNode[e.second - 1].push_back(e.first - 1);
  }
  queue<Node *> queue;
  queue.push(nodes[0]);
  while (!queue.empty()) {
    Node *p = queue.front();
    queue.pop();
    for (int child : edgeByNode[p->index]) {
      Node *c = nodes[child];
      if (c == p->parent) continue;
      p->children.push_back(c);
      c->parent = p;
      c->depth = p->depth + 1;
      queue.push(c);
    }
  }
  return nodes;
}
Node *common_parent(Node *a, Node *b) {
  while (a->depth > b->depth) a = a->parent;
  while (b->depth > a->depth) b = b->parent;
  while (a != b) {
    a = a->parent;
    b = b->parent;
  }
  return a;
}
bool prefill(vector<Node *> &nodes) {
  unordered_map<int, vector<Node *>> nodesByColor;
  for (Node *n : nodes) {
    nodesByColor[n->color].push_back(n);
  }
  for (auto &p : nodesByColor) {
    if (p.first == 0 || p.second.size() == 1) continue;
    set<pair<int, Node *>> s;
    for (Node *n : p.second) {
      s.emplace(n->depth, n);
    }
    while (s.size() > 1) {
      Node *n = prev(s.end())->second;
      s.erase(prev(s.end()));
      Node *p = n->parent;
      if (p->color != 0 && p->color != n->color) return false;
      p->color = n->color;
      s.emplace(p->depth, p);
    }
  }
  return true;
}
int64_t mod_rev(int64_t x, int64_t mod) {
  int64_t a = mod, b = 1, c = 0;
  int64_t d = x, e = 0, f = 1;
  while (d != 0) {
    int64_t g = a % d, h = b - a / d * e, i = c - a / d * f;
    a = d, b = e, c = f;
    d = g, e = h, f = i;
  }
  return ((c % mod) + mod) % mod;
}
void dfs(Node *root) {
  if (root->children.empty()) {
    if (root->color) {
      root->fc = 1;
      root->fp = 0;
    } else {
      root->fp = 1;
      root->fc = 0;
    }
    return;
  }
  for (Node *child : root->children) {
    dfs(child);
  }
  if (root->color) {
    int64_t x = 1;
    for (Node *child : root->children) {
      x = x * (child->fc + child->fp) % 998244353;
    }
    root->fc = x;
    root->fp = 0;
  } else {
    int64_t fc = 0, fp = 1;
    for (Node *child : root->children) {
      fp = fp * (child->fc + child->fp) % 998244353;
    }
    for (Node *child : root->children) {
      int64_t x = fp * mod_rev(child->fc + child->fp, 998244353) % 998244353 *
                  child->fc % 998244353;
      fc += x;
    }
    root->fc = fc;
    root->fp = fp;
  }
}
int main(int argc, char *argv[]) {
  int n = READ();
  int k = READ();
  vector<int> colors = READ(n);
  vector<pair<int, int>> edges = READ(n - 1);
  vector<Node *> nodes = buildTree(colors, edges);
  if (!prefill(nodes)) {
    cout << 0 << endl;
    return 0;
  }
  dfs(nodes[0]);
  cout << nodes[0]->fc << endl;
  return 0;
}
