#include <bits/stdc++.h>
using namespace std;
vector<pair<int, int> > G[100010];
long long qp(long long a, long long p, long long m) {
  long long ans = 1;
  for (; p; p >>= 1, a = a * a % m)
    if (p & 1) ans = ans * a % m;
  return ans;
}
long long x, mod, k;
long long pw[100010], ipw[100010];
long long v[100010];
void add(int a, int b, int l) {
  G[a].push_back(make_pair(b, l));
  G[b].push_back(make_pair(a, l));
}
int in1[100010], out1[100010];
int deg[100010];
int n, rt, sum;
int siz[100010], mxt[100010], vis[100010];
void getrt(int p, int f) {
  siz[p] = 1;
  mxt[p] = 0;
  for (auto pr : G[p]) {
    int q = pr.first;
    if (vis[q] || q == f) continue;
    getrt(q, p);
    siz[p] += siz[q];
    mxt[p] = max(mxt[p], siz[q]);
  }
  mxt[p] = max(mxt[p], sum - siz[p]);
  if (mxt[p] < mxt[rt]) rt = p;
}
vector<pair<long long, int> > uv, dv;
void getG(int p, int f, int dep, long long up, long long down) {
  up = (up * k + v[p]) % mod;
  down = (down + v[p] * pw[dep]) % mod;
  uv.push_back(make_pair(((x - up + mod) * ipw[dep] % mod + v[rt]) % mod, p));
  dv.push_back(make_pair(down, p));
  for (auto pr : G[p]) {
    int q = pr.first;
    int l = pr.second;
    if (vis[q] || f == q) continue;
    getG(q, p, dep + 1, up, down);
  }
}
void calc(int p, int flag, int dep, long long up, long long down) {
  uv.clear();
  dv.clear();
  up = (up * k + v[p]) % mod;
  down = (down + v[p] * pw[dep]) % mod;
  uv.push_back(make_pair(((x - up + mod) * ipw[dep] % mod + v[rt]) % mod, p));
  dv.push_back(make_pair(down, p));
  for (auto pr : G[p]) {
    int q = pr.first;
    if (vis[q]) continue;
    getG(q, p, dep + 1, up, down);
  }
  sort(uv.begin(), uv.end());
  sort(dv.begin(), dv.end());
  int uvsize = uv.size(), dvsize = dv.size();
  int i, pu = 0, pd = 0, num = 0;
  for (i = 0; i < uvsize; i++) {
    while (pd < dvsize && dv[pd].first < uv[i].first) pd++;
    while (pd < dvsize && dv[pd].first == uv[i].first) pd++, num++;
    out1[uv[i].second] += flag * num;
    while (i + 1 < uvsize && uv[i].first == uv[i + 1].first)
      out1[uv[++i].second] += flag * num;
    num = 0;
  }
  for (i = 0; i < dvsize; i++) {
    while (pu < uvsize && uv[pu].first < dv[i].first) pu++;
    while (pu < uvsize && uv[pu].first == dv[i].first) pu++, num++;
    in1[dv[i].second] += flag * num;
    while (i + 1 < dvsize && dv[i].first == dv[i + 1].first)
      in1[dv[++i].second] += flag * num;
    num = 0;
  }
}
void sol(int p) {
  vis[p] = 1;
  calc(p, 1, 0, 0, 0);
  for (auto pr : G[p]) {
    int q = pr.first;
    if (vis[q]) continue;
    calc(q, -1, 1, v[p], v[p]);
  }
  for (auto pr : G[p]) {
    int q = pr.first;
    if (vis[q]) continue;
    mxt[0] = n;
    rt = 0;
    sum = siz[q];
    getrt(q, 0);
    sol(rt);
  }
}
int main() {
  scanf("%d%d%d%d", &n, &mod, &k, &x);
  pw[0] = ipw[0] = 1;
  long long invk = qp(k, mod - 2, mod);
  for (int i = 1; i < 100010; i++)
    pw[i] = pw[i - 1] * k % mod, ipw[i] = ipw[i - 1] * invk % mod;
  for (int i = 1; i <= n; i++) scanf("%lld", &v[i]);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    add(u, v, 1);
  }
  rt = 0;
  sum = mxt[0] = n;
  getrt(1, 0);
  sol(rt);
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    long long i0, i1, o0, o1;
    i1 = in1[i];
    i0 = n - i1;
    o1 = out1[i];
    o0 = n - o1;
    ans += 2 * i0 * i1 + 2 * o0 * o1 + o0 * i1 + o1 * i0;
  }
  printf("%lld", (long long)n * n * n - ans / 2);
  return 0;
}
