#include <bits/stdc++.h>
using namespace std;
int n, y, k, x;
long long ans;
struct Edge {
  int e, n;
} e[100010 << 1];
int hd[100010], cnt;
void add(int a, int b) {
  e[++cnt].e = b;
  e[cnt].n = hd[a];
  hd[a] = cnt;
}
int siz[100010], mxt[100010], vis[100010];
int sum, rt;
int val[100010], kpow[100010] = {1}, inv[100010] = {1};
void getrt(int p, int f) {
  int i, q;
  siz[p] = 1;
  mxt[p] = 0;
  for (i = hd[p]; i; i = e[i].n) {
    q = e[i].e;
    if (q == f || vis[q]) continue;
    getrt(q, p);
    siz[p] += siz[q];
    mxt[p] = max(mxt[p], siz[q]);
  }
  mxt[p] = max(mxt[p], sum - mxt[p]);
  if (mxt[p] < mxt[rt]) rt = p;
}
int in[2][100010], out[2][100010];
pair<int, int> buc1[100010], buc2[100010];
int tot;
void getv(int p, int f, int dep, int up, int down) {
  int i, q;
  up = ((long long)up * k + val[p]) % y;
  down = (down + (long long)val[p] * kpow[dep]) % y;
  buc1[++tot] =
      make_pair((((long long)x - up + y) * inv[dep] + val[rt]) % y, p);
  buc2[tot] = make_pair(down, p);
  for (i = hd[p]; i; i = e[i].n) {
    q = e[i].e;
    if (q == f || vis[q]) continue;
    getv(q, p, dep + 1, up, down);
  }
}
void calc(int p, int flag, int up, int down) {
  int i, q;
  tot = 0;
  up = ((long long)up * k + val[p]) % y;
  down = ((long long)val[p] * kpow[flag] + down) % y;
  buc1[++tot] =
      make_pair((((long long)x - up + y) * inv[flag] + val[rt]) % y, p);
  buc2[tot] = make_pair(down, p);
  for (i = hd[p]; i; i = e[i].n) {
    q = e[i].e;
    if (!vis[q]) getv(q, p, 1 + flag, up, down);
  }
  sort(buc1 + 1, buc1 + tot + 1);
  sort(buc2 + 1, buc2 + tot + 1);
  buc1[tot + 1] = make_pair(-1, -1);
  buc2[tot + 1] = make_pair(-1, -1);
  int pa = 1, pb = 1, num = 1;
  for (i = 1; i <= tot; i++) {
    while (pb <= tot && buc1[i].first > buc2[pb].first) pb++;
    if (buc1[i].first != buc2[pb].first) continue;
    while (pb < tot && buc2[pb].first == buc2[pb + 1].first) num++, pb++;
    out[1][buc1[i].second] += (flag ? -1 : 1) * num;
    if (i == tot || buc1[i].first != buc1[i + 1].first) num = 1;
  }
  for (i = 1; i <= tot; i++) {
    while (pa <= tot && buc1[pa].first < buc2[i].first) pa++;
    if (buc1[pa].first != buc2[i].first) continue;
    while (pa < tot && buc1[pa].first == buc1[pa + 1].first) num++, pa++;
    in[1][buc2[i].second] += (flag ? -1 : 1) * num;
    if (i == tot || buc2[i].first != buc2[i + 1].first) num = 1;
  }
}
void solve(int p) {
  vis[p] = 1;
  int i, q;
  calc(p, 0, 0, 0);
  for (i = hd[p]; i; i = e[i].n) {
    q = e[i].e;
    if (!vis[q]) calc(q, 1, val[rt], val[rt]);
  }
  for (i = hd[p]; i; i = e[i].n) {
    q = e[i].e;
    if (vis[q]) continue;
    sum = siz[q];
    mxt[rt = 0] = n + 1;
    getrt(q, 0);
    solve(rt);
  }
}
int qp(int a, int b) {
  int ans = 1;
  for (; b; b >>= 1, a = (long long)a * a % y)
    if (b & 1) ans = (long long)ans * a % y;
  return ans;
}
int main() {
  int i, X, Y;
  scanf("%d%d%d%d", &n, &y, &k, &x);
  for (i = 1; i < 100010; i++) kpow[i] = kpow[i - 1] * 1LL * k % y;
  int kinv = qp(k, y - 2);
  for (i = 1; i < 100010; i++) inv[i] = inv[i - 1] * 1LL * kinv % y;
  for (i = 1; i <= n; i++) scanf("%d", &val[i]);
  for (i = 1; i < n; i++) scanf("%d%d", &X, &Y), add(Y, X), add(X, Y);
  sum = n;
  mxt[rt = 0] = n + 1;
  getrt(1, 0);
  solve(rt);
  ans = (long long)n * n * n * 2;
  for (i = 1; i <= n; i++) {
    in[0][i] = n - in[1][i];
    out[0][i] = n - out[1][i];
    ans -= 2LL * in[0][i] * in[1][i] + 2LL * out[0][i] * out[1][i] +
           (long long)in[0][i] * out[1][i] + (long long)in[1][i] * out[0][i];
  }
  printf("%I64d\n", ans / 2);
  return 0;
}
