#include <bits/stdc++.h>
using namespace std;
const int N = 100100;
int h[N], tot;
int sz[N], mx[N];
int n, sum, x, y;
int vis[N], root;
long long k, rest, mod;
long long val[N], ans;
long long pw[N], ipw[N];
long long in0[N], in1[N], out0[N], out1[N];
struct edge {
  int y, next;
} g[N * 2];
struct node {
  int w;
  long long x;
  node(int _x = 0, long long _w = 0) : x(_x), w(_w) {}
  friend bool operator<(node a, node b) { return a.x < b.x; }
} up[N], dw[N];
int cnt;
long long p(int x) { return x == 0 ? 0 : pw[x - 1]; }
long long power(long long x, int len) {
  long long res = 1;
  for (; len; len >>= 1, x = x * x % mod)
    if (len & 1) res = res * x % mod;
  return res;
}
void adp(int x, int y) {
  g[++tot].y = y;
  g[tot].next = h[x];
  h[x] = tot;
}
void getrt(int x, int fa) {
  sz[x] = 1;
  mx[x] = 0;
  for (int i = h[x]; i; i = g[i].next)
    if (!vis[g[i].y] && g[i].y != fa) {
      getrt(g[i].y, x);
      sz[x] += sz[g[i].y];
      mx[x] = max(mx[x], sz[g[i].y]);
    }
  mx[x] = max(mx[x], sum - sz[x]);
  if (mx[x] < mx[root]) root = x;
}
void dfs(int x, int fa, int dep, long long sup, long long sdw) {
  sup = (sup * k % mod + val[x]) % mod;
  sdw = (sdw + val[x] * p(dep) % mod) % mod;
  up[++cnt] = node((rest - sup + mod) * ipw[dep + 1] % mod, x);
  dw[cnt] = node(sdw, x);
  for (int i = h[x]; i; i = g[i].next)
    if (g[i].y != fa && !vis[g[i].y]) dfs(g[i].y, x, dep + 1, sup, sdw);
}
void calc(int x, int kd, int dep, long long sup, long long sdw) {
  cnt = 0;
  dfs(x, 0, dep, sup, sdw);
  sort(up + 1, up + cnt + 1);
  sort(dw + 1, dw + cnt + 1);
  int i, j, total;
  for (total = 0, i = j = 1; i <= cnt; i++) {
    for (; j <= cnt && dw[j].x <= up[i].x; j++)
      if (j == 1 || dw[j].x != dw[j - 1].x)
        total = 1;
      else
        total++;
    if (j != 1 && dw[j - 1].x == up[i].x) out1[up[i].w] += total * kd;
  }
  for (total = 0, i = j = 1; i <= cnt; i++) {
    for (; j <= cnt && up[j].x <= dw[i].x; j++)
      if (j == 1 || up[j].x != up[j - 1].x)
        total = 1;
      else
        total++;
    if (j != 1 && up[j - 1].x == dw[i].x) in1[dw[i].w] += total * kd;
  }
}
void solve(int x) {
  vis[x] = 1;
  calc(x, 1, 0, 0, 0);
  for (int i = h[x]; i; i = g[i].next)
    if (!vis[g[i].y]) {
      calc(g[i].y, -1, 1, val[x], 0);
      sum = sz[g[i].y];
      root = 0;
      getrt(g[i].y, x);
      solve(root);
    }
}
int main() {
  scanf("%d%I64d%I64d%I64d", &n, &mod, &k, &rest);
  pw[0] = ipw[0] = 1;
  long long ik = power(k, mod - 2);
  for (int i = 1; i <= n; i++) {
    pw[i] = pw[i - 1] * k % mod;
    ipw[i] = ipw[i - 1] * ik % mod;
  }
  for (int i = 1; i <= n; i++) scanf("%I64d", val + i);
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &x, &y);
    adp(x, y);
    adp(y, x);
  }
  sum = mx[0] = n;
  root = 0;
  getrt(1, 0);
  solve(root);
  for (int i = 1; i <= n; i++)
    ans += ((long long)2 * (n - in1[i]) * in1[i] +
            (long long)2 * (n - out1[i]) * out1[i] + (n - in1[i]) * out1[i] +
            (n - out1[i]) * in1[i]);
  printf("%I64d\n", (long long)n * n * n - ans / 2);
}
