#include <bits/stdc++.h>
using namespace std;
int read() {
  int ret = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f *= -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    ret = ret * 10 + c - '0';
    c = getchar();
  }
  return f * ret;
}
int power(int first, int k, int Mod) {
  int ret = 1;
  while (k) {
    if (k & 1) ret = 1LL * ret * first % Mod;
    first = 1LL * first * first % Mod;
    k >>= 1;
  }
  return ret;
}
const int MAXN = 100000;
int n, Y, X, k, m;
pair<int, int> front[(MAXN << 1) + 10];
int orderx[(MAXN << 1) + 10], stdx[MAXN + 10];
void sortx() {
  static int num[MAXN + 10];
  memset(num, 0, sizeof(num));
  for (int i = 1; i <= m; i++) num[front[i].first]++;
  for (int i = 1; i <= n; i++) stdx[i] = num[i] += num[i - 1];
  for (int i = 1; i <= m; i++) orderx[++num[front[i].first - 1]] = i;
  return;
}
bool check[MAXN + 10];
int v[MAXN + 10];
int ki[MAXN + 10], inv[MAXN + 10];
int DFS[MAXN + 10], T;
int sz[MAXN + 10], maxs[MAXN + 10];
void dfs(int pre, int first) {
  DFS[++T] = first;
  sz[first] = 1;
  maxs[first] = 0;
  for (int i = stdx[first - 1] + 1; i <= stdx[first]; i++) {
    int next = front[orderx[i]].second;
    if (next != pre && !check[next]) {
      dfs(first, next);
      sz[first] += sz[next];
      maxs[first] = ((maxs[first]) > (sz[next]) ? (maxs[first]) : (sz[next]));
    }
  }
  return;
}
int center(int first) {
  int ret = first;
  T = 0;
  dfs(-1, first);
  for (int i = 2; i <= T; i++) {
    int s = DFS[i];
    if (((maxs[s]) > (sz[first] - sz[s]) ? (maxs[s]) : (sz[first] - sz[s])) <
        ((maxs[ret]) > (sz[first] - sz[ret]) ? (maxs[ret])
                                             : (sz[first] - sz[ret])))
      ret = s;
  }
  return ret;
}
map<int, int> B, A;
int Ax[MAXN + 10], Bx[MAXN + 10];
int deep[MAXN + 10];
void search(int pre, int first, int sumA, int sumB, int dep) {
  deep[first] = dep;
  DFS[++T] = first;
  Ax[first] = sumA = (1LL * ki[dep] * v[first] + sumA) % Y;
  A[sumA]++;
  Bx[first] = sumB = (1LL * sumB * k + v[first]) % Y;
  B[1LL * (X - sumB + Y) * inv[dep] % Y]++;
  for (int i = stdx[first - 1] + 1; i <= stdx[first]; i++) {
    int next = front[orderx[i]].second;
    if (next != pre && !check[next]) search(first, next, sumA, sumB, dep + 1);
  }
  return;
}
int in[MAXN + 10], out[MAXN + 10];
int DDFS[MAXN + 10], DT;
void solve(int first) {
  first = center(first);
  check[first] = true;
  DT = 0;
  for (int i = stdx[first - 1] + 1; i <= stdx[first]; i++) {
    int next = front[orderx[i]].second;
    if (!check[next]) {
      T = 0;
      A.clear();
      B.clear();
      search(first, next, v[first], 0, 1);
      for (int j = 1; j <= T; j++) {
        DDFS[++DT] = DFS[j];
        in[DFS[j]] -= B[Ax[DFS[j]]];
        out[DFS[j]] -= A[1LL * (X - Bx[DFS[j]] + Y) * inv[deep[DFS[j]]] % Y];
      }
    }
  }
  A.clear();
  B.clear();
  if (v[first] == X) {
    in[first]++;
    out[first]++;
  }
  for (int i = 1; i <= DT; i++) {
    A[Ax[DDFS[i]]]++;
    B[1LL * (X - Bx[DDFS[i]] + Y) * inv[deep[DDFS[i]]] % Y]++;
  }
  for (int i = 1; i <= DT; i++) {
    in[DDFS[i]] += B[Ax[DDFS[i]]];
    out[DDFS[i]] += A[1LL * (X - Bx[DDFS[i]] + Y) * inv[deep[DDFS[i]]] % Y];
    if (Ax[DDFS[i]] == X) {
      in[DDFS[i]]++;
      out[first]++;
    }
    if ((1LL * v[first] * ki[deep[DDFS[i]]] + Bx[DDFS[i]]) % Y == X) {
      in[first]++;
      out[DDFS[i]]++;
    }
  }
  for (int i = stdx[first - 1] + 1; i <= stdx[first]; i++) {
    int next = front[orderx[i]].second;
    if (!check[next]) solve(next);
  }
  return;
}
void init() {
  n = read();
  Y = read();
  k = read();
  X = read();
  ki[0] = 1;
  inv[0] = 1;
  for (int i = 1; i <= n; i++) {
    ki[i] = 1LL * ki[i - 1] * k % Y;
    inv[i] = power(ki[i], Y - 2, Y);
  }
  for (int i = 1; i <= n; i++) v[i] = read();
  for (int i = 1; i < n; i++) {
    int first = read(), second = read();
    front[++m] = make_pair(first, second);
    front[++m] = make_pair(second, first);
  }
  sortx();
  solve(1);
  long long ans = 0;
  for (int i = 1; i <= n; i++)
    ans += 2LL * in[i] * (n - in[i]) + 1LL * in[i] * (n - out[i]) +
           1LL * out[i] * (n - in[i]) + 2LL * out[i] * (n - out[i]);
  ans = 1LL * n * n * n - (ans >> 1);
  cout << ans << endl;
  return;
}
int main() {
  init();
  return 0;
}
