#include <bits/stdc++.h>
using namespace std;
const long long N = (long long)2e5 + 5;
long long sz[N], bfen[N], ipw[N], mark[N], rfen[N], n, mod, k, q, val[N],
    kpw[N], rin[N], rout[N], bin[N], bout[N];
long long pw(long long a, long long b) {
  return b != 0 ? pw(1ll * a * a % mod, b >> 1) * 1ll * (b & 1 ? a : 1) % mod
                : 1;
}
vector<long long> adj[N];
void fen_update(long long m, long long x, long long *fen) {
  m++;
  while (m > 0) fen[m] += x, m -= m & -m;
}
long long query(long long m, long long *fen, long long res = 0) {
  m++;
  while (m < N) res += fen[m], m += m & -m;
  return res;
}
long long dfs_sz(long long v, long long p = -1) {
  if (mark[v]) {
    return 0;
  }
  sz[v] = 1;
  for (long long u : adj[v])
    if (u != p) sz[v] += dfs_sz(u, v);
  return sz[v];
}
long long m;
pair<long long, long long> upath[N], dpath[N];
long long dpval[N], upval[N], h[N], rcnt[N], bcnt[N];
vector<long long> child[N];
void get_val(long long v, long long p, long long g, long long root,
             long long dw = 0, long long up = 0) {
  if (mark[v]) {
    return;
  }
  h[v] = (p == -1 ? 0 : h[p] + 1);
  if (g != -1) child[g].push_back(v);
  child[root].push_back(v);
  dpval[v] = dw;
  upval[v] = up;
  for (long long u : adj[v])
    if (u != p) {
      get_val(u, v, g != -1 ? g : u, root,
              (dw + kpw[h[v] + 1] * 1ll * val[u]) % mod,
              (up * 1ll * k + val[u]) % mod);
    }
}
void seg_update(long long l, long long r, long long *fen) {
  fen_update(r - 1, 1, fen);
  fen_update(l - 1, -1, fen);
}
pair<long long, long long> path[N];
void get_count(long long root) {
  sort(dpath, dpath + m);
  for (long long i = 0; i < m; ++i) {
    long long v = upath[i].second, x = upath[i].first;
    x = x * 1ll * ipw[h[v]] % mod;
    x = (x - val[root] + mod) % mod;
    long long reach = q * 1ll * ipw[h[v]] % mod;
    path[i].first = (reach - x + mod) % mod;
    path[i].second = v;
    long long l = lower_bound(dpath, dpath + m,
                              make_pair((reach - x + mod) % mod, -1LL)) -
                  dpath;
    long long r =
        lower_bound(dpath, dpath + m, make_pair((reach - x + mod) % mod, N)) -
        dpath;
    seg_update(l, r, rfen);
  }
  sort(path, path + m);
  for (long long i = 0; i < m; ++i) {
    long long v = dpath[i].second, x = dpath[i].first;
    long long l = lower_bound(path, path + m, make_pair(x, -1LL)) - path;
    long long r = lower_bound(path, path + m, make_pair(x, N)) - path;
    seg_update(l, r, bfen);
  }
  for (long long i = 0; i < m; ++i)
    rcnt[dpath[i].second] = query(i, rfen),
    bcnt[path[i].second] = query(i, bfen);
  for (long long i = 0; i <= m + 2; ++i) rfen[i] = bfen[i] = 0;
}
void solve(long long v) {
  dfs_sz(v);
  long long root = v;
  bool found = 0;
  while (!found) {
    found = 1;
    for (long long u : adj[v])
      if (!mark[u] && sz[u] < sz[v] && sz[u] > sz[root] / 2) {
        found = 0;
        v = u;
        break;
      }
  }
  get_val(v, -1, -1, v, val[v], val[v]);
  m = 0;
  for (long long ch : child[v])
    upath[m] = make_pair(upval[ch], ch), dpath[m] = make_pair(dpval[ch], ch),
    m++;
  get_count(v);
  for (long long ch : child[v]) rin[ch] += rcnt[ch], rout[ch] += bcnt[ch];
  for (long long u : adj[v])
    if (!mark[u]) {
      m = 0;
      for (long long ch : child[u])
        upath[m] = make_pair(upval[ch], ch),
        dpath[m] = make_pair(dpval[ch], ch), m++;
      get_count(v);
      for (long long ch : child[u]) rin[ch] -= rcnt[ch], rout[ch] -= bcnt[ch];
    }
  mark[v] = 1;
  for (long long u : adj[v])
    if (!mark[u]) {
      child[u].clear();
      solve(u);
    }
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> mod >> k >> q;
  for (long long v = 0, _n = (long long)(n); v < _n; ++v)
    cin >> val[v], val[v] %= mod;
  kpw[0] = ipw[0] = 1;
  for (long long i = 1; i < N; ++i)
    kpw[i] = kpw[i - 1] * 1ll * k % mod, ipw[i] = pw(kpw[i], mod - 2);
  for (long long e = 0, _n = (long long)(n - 1); e < _n; ++e) {
    long long u, v;
    cin >> u >> v;
    --u, --v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  solve(0);
  long long res = 0;
  for (long long v = 0; v < n; ++v) bin[v] = n - rin[v], bout[v] = n - rout[v];
  for (long long v = 0; v < n; ++v)
    res += rin[v] * 1ll * bin[v] * 2 + rout[v] * 1ll * bout[v] * 2 +
           rin[v] * bout[v] + rout[v] * bin[v];
  cout << n * 1ll * n * n - res / 2 << endl;
}
