#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void Read(T &x) {
  int f = 1;
  char t = getchar();
  while (t < '0' || t > '9') {
    if (t == '-') f = -1;
    t = getchar();
  }
  x = 0;
  while (t >= '0' && t <= '9') {
    x = x * 10 + t - '0';
    t = getchar();
  }
  x *= f;
}
template <class T>
inline void chkmin(T &x, T y) {
  if (x > y) x = y;
}
template <class T>
inline void chkmax(T &x, T y) {
  if (x < y) x = y;
}
const int maxn = 100005;
struct Instate {
  int n, k, X, Y;
  int val[maxn];
};
Instate in;
int fst[maxn], v[maxn << 1], nxt[maxn << 1], e_cn;
long long f[maxn], inv[maxn];
long long fpm(long long x, long long k) {
  int re = 1;
  while (k > 0) {
    if (k & 1) re = 1ll * re * x % in.Y;
    x = 1ll * x * x % in.Y;
    k >>= 1;
  }
  return re;
}
void addedge(int a, int b) {
  e_cn++, v[e_cn] = b;
  nxt[e_cn] = fst[a], fst[a] = e_cn;
}
void input() {
  int a, b;
  Read(in.n), Read(in.Y), Read(in.k), Read(in.X);
  for (register int i = 1; i <= in.n; i++) Read(in.val[i]);
  for (register int i = 1; i < in.n; i++) {
    Read(a), Read(b);
    addedge(a, b);
    addedge(b, a);
  }
}
void prepare() {
  f[0] = 1;
  for (register int i = 1; i <= in.n; i++) f[i] = 1ll * f[i - 1] * in.k % in.Y;
  for (register int i = 0; i <= in.n; i++) inv[i] = fpm(f[i], in.Y - 2);
}
bool used[maxn];
int dfn[maxn], now;
int sz[maxn], son[maxn];
int indeg[maxn], oudeg[maxn];
long long downval[maxn], upval[maxn];
long long s_up[maxn], s_down[maxn];
pair<long long, int> up_pool[maxn], down_pool[maxn];
int len1, len2;
void dfs(int cn, int pr) {
  dfn[++now] = cn;
  sz[cn] = 1, son[cn] = 0;
  for (register int i = fst[cn]; i; i = nxt[i]) {
    if (!used[v[i]] && v[i] != pr) {
      dfs(v[i], cn);
      sz[cn] += sz[v[i]];
      chkmax(son[cn], sz[v[i]]);
    }
  }
}
int getcentroid(int cn) {
  int re = -1;
  now = 0, dfs(cn, cn);
  for (register int i = 1; i <= now; i++) {
    chkmax(son[dfn[i]], sz[cn] - sz[dfn[i]]);
    if (re == -1 || son[dfn[i]] < son[re]) re = dfn[i];
  }
  return re;
}
void go(int cn, int pr, int dep, long long n1, long long n2) {
  n1 = (n1 + 1ll * in.val[cn] * f[dep] % in.Y) % in.Y;
  n2 = (n2 + 1ll * in.val[cn] * inv[dep] % in.Y) % in.Y;
  downval[cn] = n1;
  upval[cn] = 1ll * n2 * f[dep] % in.Y;
  s_up[++len1] = ((in.X - upval[cn]) % in.Y + in.Y) % in.Y * inv[dep] % in.Y;
  s_down[++len2] = downval[cn];
  for (register int i = fst[cn]; i; i = nxt[i]) {
    if (!used[v[i]] && v[i] != pr) {
      go(v[i], cn, dep + 1, n1, n2);
    }
  }
}
int find(pair<long long, int> arr[maxn], int len, long long val) {
  int l = 1, r = len, mid;
  while (r >= l) {
    mid = (l + r) >> 1;
    if (arr[mid].first == val) {
      return arr[mid].second;
    }
    if (val < arr[mid].first)
      r = mid - 1;
    else
      l = mid + 1;
  }
  return 0;
}
void pre_sort() {
  int n1 = 0, n2 = 0;
  sort(s_up + 1, s_up + len1 + 1);
  sort(s_down + 1, s_down + len2 + 1);
  s_up[len1 + 1] = s_down[len2 + 1] = -1;
  for (register int i = 1, j = 1; i <= len1 + 1; i++) {
    if (i != 1 && s_up[i] != s_up[i - 1]) {
      up_pool[++n1] = make_pair(s_up[i - 1], i - j);
      j = i;
    }
  }
  for (register int i = 1, j = 1; i <= len2 + 1; i++) {
    if (i != 1 && s_down[i] != s_down[i - 1]) {
      down_pool[++n2] = make_pair(s_down[i - 1], i - j);
      j = i;
    }
  }
  len1 = n1, len2 = n2;
}
void calc(int cn, int pr, int dep, int flag, long long sub) {
  indeg[cn] +=
      flag * find(up_pool, len1, ((downval[cn] - sub) % in.Y + in.Y) % in.Y);
  oudeg[cn] +=
      flag *
      find(down_pool, len2,
           ((in.X - (upval[cn] - 1ll * sub * f[dep] % in.Y)) % in.Y + in.Y) %
               in.Y * inv[dep] % in.Y);
  for (register int i = fst[cn]; i; i = nxt[i]) {
    if (v[i] != pr && !used[v[i]]) {
      calc(v[i], cn, dep + 1, flag, sub);
    }
  }
}
void exec(int cn) {
  int g, en1, en2;
  used[g = getcentroid(cn)] = true;
  len1 = len2 = 0;
  go(g, g, 0, 0, 0), pre_sort();
  calc(g, g, 0, 1, in.val[g]);
  for (register int i = fst[g]; i; i = nxt[i]) {
    if (!used[v[i]]) {
      en1 = 1ll * in.val[g] * f[0] % in.Y;
      en2 = 1ll * in.val[g] * inv[0] % in.Y;
      len1 = len2 = 0;
      go(v[i], g, 1, en1, en2), pre_sort();
      calc(v[i], g, 1, -1, in.val[g]);
      exec(v[i]);
    }
  }
}
void solve() {
  long long ans = 1ll * in.n * in.n * in.n, d = 0;
  exec(1);
  for (register int i = 1; i <= in.n; i++) {
    d += 2ll * indeg[i] * (in.n - indeg[i]) +
         2ll * oudeg[i] * (in.n - oudeg[i]) +
         1ll * indeg[i] * (in.n - oudeg[i]) +
         1ll * oudeg[i] * (in.n - indeg[i]);
  }
  cout << ans - d / 2 << endl;
}
int main() {
  input();
  prepare();
  solve();
  return 0;
}
