#include <bits/stdc++.h>
using namespace std;
const int RLEN = 1 << 20 | 1;
inline char gc() {
  static char ibuf[RLEN], *ib, *ob;
  (ib == ob) && (ob = (ib = ibuf) + fread(ibuf, 1, RLEN, stdin));
  return (ib == ob) ? EOF : *ib++;
}
inline int read() {
  char ch = gc();
  int res = 0;
  bool f = 1;
  while (!isdigit(ch)) f ^= ch == '-', ch = gc();
  while (isdigit(ch)) res = (res + (res << 2) << 1) + (ch ^ 48), ch = gc();
  return f ? res : -res;
}
inline long long readll() {
  char ch = gc();
  long long res = 0;
  bool f = 1;
  while (!isdigit(ch)) f ^= ch == '-', ch = gc();
  while (isdigit(ch)) res = (res + (res << 2) << 1) + (ch ^ 48), ch = gc();
  return f ? res : -res;
}
inline int readstring(char *s) {
  int top = 0;
  char ch = gc();
  while (isspace(ch)) ch = gc();
  while (!isspace(ch) && ch != EOF) s[++top] = ch, ch = gc();
  s[top + 1] = '\0';
  return top;
}
template <typename tp>
inline void chemx(tp &a, tp b) {
  a = max(a, b);
}
template <typename tp>
inline void chemn(tp &a, tp b) {
  a = min(a, b);
}
int mod;
inline int add(int a, int b) {
  return (a + b) >= mod ? (a + b - mod) : (a + b);
}
inline int dec(int a, int b) { return (a < b) ? (a - b + mod) : (a - b); }
inline int mul(int a, int b) {
  static long long r;
  r = (long long)a * b;
  return (r >= mod) ? (r % mod) : r;
}
inline void Add(int &a, int b) { a = (a + b) >= mod ? (a + b - mod) : (a + b); }
inline void Dec(int &a, int b) { a = (a < b) ? (a - b + mod) : (a - b); }
inline void Mul(int &a, int b) {
  static long long r;
  r = (long long)a * b;
  a = (r >= mod) ? (r % mod) : r;
}
inline int ksm(int a, int b, int res = 1) {
  for (; b; b >>= 1, Mul(a, a)) (b & 1) && (Mul(res, a), 1);
  return res;
}
inline int Inv(int x) { return ksm(x, mod - 2); }
inline int fix(long long x) {
  x %= mod;
  return (x < 0) ? x + mod : x;
}
const int N = 100005;
int n, X, K;
int pw[N], ip[N], a[N];
int in[N], out[N];
vector<int> e[N];
inline void init_pw() {
  pw[0] = ip[0] = 1;
  for (int i = 1, iv = Inv(K); i <= n; i++)
    pw[i] = mul(pw[i - 1], K), ip[i] = mul(ip[i - 1], iv);
}
int siz[N], maxn, mxsz, rt;
bool vis[N];
void getrt(int u, int fa) {
  int son = 0;
  siz[u] = 1;
  for (const int &v : e[u])
    if (!vis[v] && v != fa) {
      getrt(v, u);
      siz[u] += siz[v];
      chemx(son, siz[v]);
    }
  chemx(son, maxn - siz[u]);
  if (son < mxsz) mxsz = son, rt = u;
}
pair<int, int> tu[N], td[N];
struct Map {
  static const int mod = 5000007;
  int val[mod];
  long long key[mod];
  int stk[mod], top;
  Map() { memset(key, -1, sizeof(key)); }
  inline void clear() {
    while (top) key[stk[top]] = -1, val[stk[top]] = 0, top--;
  }
  inline void update(long long p, int k) {
    int v = p % mod;
    for (; ~key[v]; v = (v == mod - 1 ? 0 : v + 1))
      if (key[v] == p) {
        val[v] += k;
        return;
      }
    stk[++top] = v, key[v] = p, val[v] = k;
  }
  inline int query(long long p) {
    int v = p % mod;
    for (; ~key[v]; v = (v == mod - 1 ? 0 : v + 1))
      if (key[v] == p) return val[v];
    return 0;
  }
} mp1, mp2;
int tot;
void get_vl(int u, int fa, int dep, int up, int dn) {
  tot++;
  up = add(mul(up, K), a[u]);
  if (dep) dn = add(dn, mul(a[u], pw[dep - 1]));
  int vl = mul(dec(X, up), ip[dep + 1]);
  mp1.update(vl, 1), mp2.update(dn, 1);
  tu[tot] = pair<int, int>(vl, u);
  td[tot] = pair<int, int>(dn, u);
  for (const int &v : e[u])
    if (!vis[v] && v != fa) get_vl(v, u, dep + 1, up, dn);
}
inline void calc(int u, int coef, int dep, int up, int dn = 0) {
  tot = 1;
  mp1.clear(), mp2.clear();
  up = add(mul(up, K), a[u]);
  if (dep) dn = add(dn, mul(a[u], pw[dep - 1]));
  tu[1] = pair<int, int>(mul(dec(X, up), ip[dep + 1]), u);
  td[1] = pair<int, int>(dn, u);
  mp1.update(mul(dec(X, up), ip[dep + 1]), 1);
  mp2.update(dn, 1);
  for (const int &v : e[u])
    if (!vis[v]) get_vl(v, u, dep + 1, up, dn);
  for (int i = 1; i <= tot; i++) {
    in[td[i].second] += coef * mp1.query(td[i].first);
    out[tu[i].second] += coef * mp2.query(tu[i].first);
  }
}
void solve(int u, int ts) {
  vis[u] = 1;
  calc(u, 1, 0, 0);
  for (const int &v : e[u])
    if (!vis[v]) {
      calc(v, -1, 1, a[u]);
    }
  for (const int &v : e[u])
    if (!vis[v]) {
      if (siz[v] > siz[u]) maxn = ts - siz[u];
      mxsz = 1e9;
      getrt(v, rt = 0);
      solve(v, maxn);
    }
}
int main() {
  n = read(), mod = read(), K = read(), X = read();
  init_pw();
  for (int i = 1; i <= n; i++) a[i] = read();
  for (int i = 1; i < n; i++) {
    int u = read(), v = read();
    e[u].push_back(v), e[v].push_back(u);
  }
  maxn = n, mxsz = 1e9;
  getrt(1, 0);
  solve(rt, n);
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    long long in0 = in[i], in1 = n - in0, out0 = out[i], out1 = n - out0;
    ans += in0 * in1 * 2 + out0 * out1 * 2 + in0 * out1 + in1 * out0;
  }
  ans /= 2;
  cout << (long long)n * n * n - ans << '\n';
  return 0;
}
