#include <bits/stdc++.h>
using namespace std;
struct edge {
  int next, node;
} e[100000 << 1 | 1];
int head[100000 + 1], tot = 0;
inline void addedge(int a, int b) {
  e[++tot].next = head[a];
  head[a] = tot, e[tot].node = b;
}
int n, mod, k, X, w[100000 + 1], size[100000 + 1], ms[100000 + 1],
    q[100000 + 1], cnt, kpow[100000 + 1], kinv[100000 + 1];
bool v[100000 + 1];
inline int pw(int a, int b) {
  int r = 1;
  while (b > 0) {
    if (b & 1) r = (long long)r * a % mod;
    a = (long long)a * a % mod;
    b >>= 1;
  }
  return r;
}
void getSize(int x, int f) {
  size[x] = 1, ms[x] = 0, q[++cnt] = x;
  for (int i = head[x]; i; i = e[i].next) {
    int node = e[i].node;
    if (v[node] || node == f) continue;
    getSize(node, x);
    size[x] += size[node];
    ms[x] = max(ms[x], size[node]);
  }
}
int center(int x) {
  cnt = 0, getSize(x, 0);
  int val = INT_MAX, p = -1;
  for (int i = 1; i <= cnt; ++i) {
    int s = max(size[x] - size[q[i]], ms[q[i]]);
    if (s < val) val = s, p = q[i];
  }
  return p;
}
int dep[100000 + 1], dt[100000 + 1], df[100000 + 1], in[100000 + 1],
    out[100000 + 1], target[100000 + 1];
void getDist(int x, int f) {
  for (int i = head[x]; i; i = e[i].next) {
    int node = e[i].node;
    if (v[node] || node == f) continue;
    dep[node] = dep[x] + 1;
    dt[node] = (dt[x] + (long long)w[node] * kpow[dep[node]]) % mod;
    df[node] = ((long long)df[x] * k + w[node]) % mod;
    getDist(node, x);
  }
}
vector<int> child[100000 + 1];
void color(int x, int f, int c) {
  child[c].push_back(x);
  for (int i = head[x]; i; i = e[i].next) {
    int node = e[i].node;
    if (v[node] || node == f) continue;
    color(node, x, c);
  }
}
map<int, int> from, to;
map<int, int>::iterator it;
void add(map<int, int> &h, int k, int x) {
  it = h.find(k);
  if (it == h.end())
    h[k] = x;
  else
    it->second += x;
}
int find(map<int, int> &h, int k) {
  it = h.find(k);
  if (it == h.end()) return 0;
  return it->second;
}
void solve() {
  from.clear(), to.clear();
  for (int i = 1; i <= cnt; ++i) {
    int node = q[i];
    for (int j = 0; j < child[node].size(); ++j) {
      int p = child[node][j];
      add(to, dt[p], 1);
    }
  }
  for (int i = 1; i <= cnt; ++i) {
    int node = q[i];
    for (int j = 0; j < child[node].size(); ++j) {
      int p = child[node][j];
      add(to, dt[p], -1);
    }
    for (int j = 0; j < child[node].size(); ++j) {
      int p = child[node][j];
      out[p] += find(to, target[p]);
      in[p] += find(from, dt[p]);
    }
    for (int j = 0; j < child[node].size(); ++j) {
      int p = child[node][j];
      add(from, target[p], 1);
    }
  }
}
void divide(int x) {
  x = center(x);
  v[x] = true;
  dt[x] = df[x] = w[x], dep[x] = 0;
  getDist(x, 0);
  for (int i = 1; i <= cnt; ++i)
    if (q[i] == x) {
      if (dt[q[i]] == X) ++out[x], ++in[x];
    } else {
      if (dt[q[i]] == X) ++out[x], ++in[q[i]];
      if (df[q[i]] == X) ++in[x], ++out[q[i]];
    }
  cnt = 0;
  for (int i = head[x]; i; i = e[i].next) {
    int node = e[i].node;
    if (v[node]) continue;
    child[node].clear(), q[++cnt] = node;
    color(node, 0, node);
    for (int j = 0; j < child[node].size(); ++j) {
      int p = child[node][j];
      target[p] = ((long long)(X - df[p] + mod) * kinv[dep[p]] + w[x]) % mod;
    }
  }
  solve();
  reverse(q + 1, q + cnt + 1);
  solve();
  for (int i = head[x]; i; i = e[i].next) {
    int node = e[i].node;
    if (v[node]) continue;
    divide(node);
  }
}
int main(int argc, char *argv[]) {
  ios ::sync_with_stdio(false);
  cin >> n >> mod >> k >> X;
  for (int i = 1; i <= n; ++i) cin >> w[i];
  for (int i = 1; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    addedge(x, y), addedge(y, x);
  }
  kpow[0] = 1;
  for (int i = 1; i <= n; ++i) {
    kpow[i] = (long long)kpow[i - 1] * k % mod;
    kinv[i] = pw(kpow[i], mod - 2);
  }
  divide(1);
  long long ans = 0LL;
  for (int i = 1; i <= n; ++i) {
    ans += (long long)in[i] * (n - in[i]) * 2LL;
    ans += (long long)out[i] * (n - out[i]) * 2LL;
    ans += (long long)in[i] * (n - out[i]) + (long long)(n - in[i]) * out[i];
  }
  ans = (long long)n * n * n - ans / 2LL;
  cout << ans << endl;
  fclose(stdin);
  fclose(stdout);
  return 0;
}
