#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int s = 0, t = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') t = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
  return s * t;
}
const int N = 1e5 + 5;
long long Ans;
int n, cnt, K, P, RES, All, Minn, root;
int a[N], h[N], size[N], vis[N], sum[N], d[N];
int fac[N], inv[N], F0[N], F1[N], G0[N], G1[N];
int In0[N], Out0[N], In1[N], Out1[N];
vector<int> H[N];
map<int, int> Gmap, Fmap;
struct edge {
  int to, next;
} e[N * 2];
void add(int x, int y) {
  e[++cnt] = (edge){y, h[x]};
  h[x] = cnt;
  e[++cnt] = (edge){x, h[y]};
  h[y] = cnt;
}
int ksm(int x, int k) {
  int res = 1;
  while (k) {
    if (k & 1) res = 1ll * res * x % P;
    x = 1ll * x * x % P, k >>= 1;
  }
  return res;
}
void Mod(int &x) { x = (x % P + P) % P; }
void Find_root(int x, int f) {
  int Maxn = 0;
  size[x] = 1;
  for (int i = h[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (y == f || vis[y]) continue;
    Find_root(y, x);
    size[x] += size[y];
    Maxn = max(Maxn, size[y]);
  }
  Maxn = max(Maxn, All - size[x]);
  if (Maxn < Minn) Minn = Maxn, root = x;
}
void DFS(int x, int f, int from) {
  sum[x] = 1;
  d[x] = d[f] + 1;
  F1[x] = (F1[f] + 1ll * fac[d[x] - 1] * a[x] % P) % P;
  F0[x] = (F1[x] + P - a[root]) % P;
  G1[x] = (1ll * G1[f] * K % P + a[x]) % P;
  G0[x] = (G1[x] + P - 1ll * fac[d[x] - 1] * a[root] % P) % P;
  G0[x] = 1ll * (RES + P - G0[x]) % P * inv[d[x] - 1] % P;
  if (from) {
    H[from].push_back(x);
    Fmap[F0[x]]++;
    Gmap[G0[x]]++;
  }
  for (int i = h[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (y == f || vis[y]) continue;
    if (!from)
      DFS(y, x, y);
    else
      DFS(y, x, from);
    sum[x] += sum[y];
  }
}
void Calc() {
  Gmap.clear(), Fmap.clear();
  DFS(root, 0, 0);
  if (F1[root] == RES) In0[root]++, Out0[root]++;
  for (int i = h[root]; i; i = e[i].next) {
    int from = e[i].to;
    if (vis[from]) continue;
    for (auto x : H[from]) Fmap[F0[x]]--, Gmap[G0[x]]--;
    for (auto x : H[from]) {
      Out0[x] += Fmap[1ll * (RES + P - G1[x]) % P * inv[d[x] - 1] % P];
      In0[x] += Gmap[F1[x]];
      if (G1[x] == RES) Out0[x]++, In0[root]++;
      if (F1[x] == RES) Out0[root]++, In0[x]++;
    }
    for (auto x : H[from]) Fmap[F0[x]]++, Gmap[G0[x]]++;
    H[from].clear();
  }
}
void Solve(int x, int num) {
  All = num, Minn = num;
  Find_root(x, 0);
  Calc();
  vis[root] = 1;
  for (int i = h[root]; i; i = e[i].next) {
    int y = e[i].to;
    if (vis[y]) continue;
    Solve(y, sum[y]);
  }
}
void Init() {
  n = read(), P = read(), K = read(), RES = read();
  for (int i = 1; i <= n; i++) a[i] = read() % P;
  for (int i = 1; i < n; i++) {
    int x = read(), y = read();
    add(x, y);
  }
}
void Prepare() {
  fac[0] = 1;
  for (int i = 1; i <= n; i++) fac[i] = 1ll * fac[i - 1] * K % P;
  inv[0] = 1;
  inv[1] = ksm(K, P - 2);
  for (int i = 2; i <= n; i++) inv[i] = 1ll * inv[i - 1] * inv[1] % P;
}
void Print() {
  for (int i = 1; i <= n; i++) {
    Out1[i] = n - Out0[i];
    In1[i] = n - In0[i];
  }
  for (int i = 1; i <= n; i++) {
    long long tmp = 0;
    tmp += 2ll * Out0[i] * Out1[i];
    tmp += 1ll * Out0[i] * In1[i];
    tmp += 1ll * Out1[i] * In0[i];
    tmp += 2ll * In0[i] * In1[i];
    Ans += tmp;
  }
  printf("%lld", 1ll * n * n * n - Ans / 2);
}
signed main() {
  Init();
  Prepare();
  Solve(1, n);
  Print();
  return 0;
}
