#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void umax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline void umin(T &a, T b) {
  if (a > b) a = b;
}
template <class T>
inline T abs(T a) {
  return a > 0 ? a : -a;
}
template <class T>
inline T gcd(T a, T b) {
  return __gcd(a, b);
}
template <class T>
inline T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
const int inf = 1e9 + 143;
const long long longinf = 1e18 + 143;
inline int read() {
  int x;
  scanf(" %d", &x);
  return x;
}
const int N = 101001;
int mod;
inline int add(int x, int y) { return (x + y >= mod) ? x + y - mod : x + y; }
inline int mul(int x, int y) { return (long long)x * y % mod; }
inline int modpow(int x, int n) {
  int res = 1;
  while (n > 0) {
    if (n & 1) res = mul(res, x);
    x = mul(x, x);
    n >>= 1;
  }
  return res;
}
int power[N], inv_power[N];
int n, k, x;
int a[N];
vector<int> g[N];
int in[N], out[N];
bool used[N];
int sz[N];
void dfs(int u, int p) {
  sz[u] = 1;
  for (__typeof((g[u]).begin()) it = (g[u]).begin(); it != (g[u]).end(); it++) {
    int v = *it;
    if (v != p && !used[v]) {
      dfs(v, u);
      sz[u] += sz[v];
    }
  }
}
int best(int u, int p, int all) {
  for (__typeof((g[u]).begin()) it = (g[u]).begin(); it != (g[u]).end(); it++) {
    int v = *it;
    if (v != p && !used[v] && sz[v] * 2 > all) return best(v, u, all);
  }
  return u;
}
int d[N];
int in_val[N], out_val[N];
vector<int> nodes;
void go(int u, int p, int x, int rx) {
  nodes.push_back(u);
  d[u] = d[p] + 1;
  x = add(x, mul(power[d[u] - 1], a[u]));
  rx = add(mul(rx, k), a[u]);
  in_val[u] = x;
  out_val[u] = rx;
  for (__typeof((g[u]).begin()) it = (g[u]).begin(); it != (g[u]).end(); it++) {
    int v = *it;
    if (v != p && !used[v]) {
      go(v, u, x, rx);
    }
  }
}
map<int, int> cnt_in, cnt_weirdout;
void calc(int j) {
  in[j] += cnt_weirdout[in_val[j]];
  int need = mul(add(x, mod - out_val[j]), inv_power[d[j]]);
  out[j] += cnt_in[need];
}
void addto(int j, int u) {
  int in = add(mul(in_val[j], k), a[u]);
  int out = add(out_val[j], mul(a[u], power[d[j]]));
  cnt_in[in]++;
  int weird = mul(add(x, mod - out), inv_power[d[j] + 1]);
  cnt_weirdout[weird]++;
}
void solve(int u) {
  dfs(u, 0);
  u = best(u, 0, sz[u]);
  cnt_in.clear();
  cnt_weirdout.clear();
  cnt_in[a[u]]++;
  cnt_weirdout[mul(add(x, mod - a[u]), inv_power[1])]++;
  for (int i = 0; i < g[u].size(); i++) {
    int v = g[u][i];
    if (used[v]) continue;
    d[u] = 0;
    nodes.clear();
    go(v, u, 0, 0);
    for (__typeof((nodes).begin()) it = (nodes).begin(); it != (nodes).end();
         it++)
      calc(*it);
    for (__typeof((nodes).begin()) it = (nodes).begin(); it != (nodes).end();
         it++) {
      addto(*it, u);
      int j = *it;
      0;
    }
  }
  cnt_in.clear();
  cnt_weirdout.clear();
  for (int i = (int)g[u].size() - 1; i >= 0; i--) {
    int v = g[u][i];
    if (used[v]) continue;
    d[u] = 0;
    nodes.clear();
    go(v, u, 0, 0);
    for (__typeof((nodes).begin()) it = (nodes).begin(); it != (nodes).end();
         it++)
      calc(*it);
    for (__typeof((nodes).begin()) it = (nodes).begin(); it != (nodes).end();
         it++) {
      int j = *it;
      addto(j, u);
      int in = add(mul(in_val[j], k), a[u]);
      int out = add(out_val[j], mul(a[u], power[d[j]]));
      0;
      if (in == x) ::out[u]++;
      if (out == x) ::in[u]++;
    }
  }
  used[u] = 1;
  for (__typeof((g[u]).begin()) it = (g[u]).begin(); it != (g[u]).end(); it++) {
    int v = *it;
    if (!used[v]) solve(v);
  }
}
int main() {
  n = read();
  mod = read();
  k = read();
  x = read();
  power[0] = 1;
  for (int i = 1; i < N; i++) power[i] = mul(power[i - 1], k);
  inv_power[0] = 1;
  inv_power[1] = modpow(k, mod - 2);
  for (int i = 2; i < N; i++)
    inv_power[i] = mul(inv_power[i - 1], inv_power[1]);
  for (int i = 1; i <= n; i++) a[i] = read();
  for (int i = 1; i < n; i++) {
    int u = read(), v = read();
    g[u].push_back(v);
    g[v].push_back(u);
  }
  solve(1);
  for (int i = 1; i <= n; i++)
    if (x == a[i]) {
      in[i]++;
      out[i]++;
    }
  long long res = 0ll;
  for (int i = 1; i <= n; i++) {
    long long in0 = in[i], out0 = out[i];
    long long in1 = n - in0, out1 = n - out0;
    0;
    0;
    res += in0 * out1 + in1 * out0 + 2 * in0 * in1 + 2 * out0 * out1;
  }
  res = (long long)n * n * n - res / 2ll;
  cout << res << endl;
  return 0;
}
