#include <bits/stdc++.h>
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
using namespace ::std;
const int maxn = 1e5 + 500;
const int inf = 1e9 + 400;
long long y, k, x;
int val[maxn];
vector<int> ger[maxn];
int inp[maxn];
int out[maxn];
bool vis[maxn];
int sz[maxn];
long long tav[maxn];
long long rtav[maxn];
void set_sz(int a, int p = -1) {
  sz[a] = 1;
  for (auto v : ger[a]) {
    if (v != p && !vis[v]) {
      set_sz(v, a);
      sz[a] += sz[v];
    }
  }
}
int find_cent(int a, int x, int p = -1) {
  for (auto v : ger[a]) {
    if (v != p && !vis[v] && sz[v] > x) {
      return find_cent(v, x, a);
    }
  }
  return a;
}
map<int, int> ma, mb;
int L[maxn];
int second[maxn];
int T[maxn];
void add_vertex(int a, int c) {
  ma[((x - second[a] + y) * rtav[L[a]]) % y] += c;
  mb[T[a]] += c;
}
void calcol_vertex(int a) {
  inp[a] += ma[T[a]];
  int res = ((x - second[a] + y) * rtav[L[a]]) % y;
  out[a] += mb[res];
}
void dfs_hesab(int a, long long s, long long t, int l, int p) {
  second[a] = s;
  T[a] = t;
  L[a] = l;
  for (auto v : ger[a]) {
    if (!vis[v] && v != p) {
      dfs_hesab(v, (s * k + val[v]) % y, (t + tav[l + 1] * val[v]) % y, l + 1,
                a);
    }
  }
}
void dfs_add(int a, int c, int p = -1) {
  add_vertex(a, c);
  for (auto v : ger[a]) {
    if (!vis[v] && v != p) {
      dfs_add(v, c, a);
    }
  }
}
void dfs_cal(int a, int p) {
  calcol_vertex(a);
  for (auto v : ger[a]) {
    if (!vis[v] && v != p) {
      dfs_cal(v, a);
    }
  }
}
void dfs(int a) {
  set_sz(a);
  int cn = find_cent(a, sz[a] / 2);
  vis[cn] = 1;
  dfs_hesab(cn, 0, val[cn], 0, -1);
  dfs_add(cn, 1);
  calcol_vertex(cn);
  for (auto v : ger[cn]) {
    if (!vis[v]) {
      dfs_add(v, -1, cn);
      dfs_cal(v, cn);
      dfs_add(v, +1, cn);
    }
  }
  ma.clear();
  mb.clear();
  for (auto v : ger[cn]) {
    if (!vis[v]) {
      dfs(v);
    }
  }
}
int poww(int a, int b) {
  long long ans = 1;
  while (b) {
    if (b & 1) {
      ans = (ans * a) % y;
    }
    a = ((long long)a * (long long)a) % y;
    b >>= 1;
  }
  return ans;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n >> y >> k >> x;
  tav[0] = 1;
  rtav[0] = 1;
  for (int i = 1; i < maxn; i++) {
    tav[i] = (tav[i - 1] * k) % y;
    rtav[i] = poww(tav[i], y - 2);
  }
  for (int i = 0; i < n; i++) {
    cin >> val[i];
    val[i] %= y;
  }
  for (int i = 1; i < n; i++) {
    int v, u;
    cin >> v >> u;
    v--;
    u--;
    ger[v].push_back(u);
    ger[u].push_back(v);
  }
  dfs(0);
  long long ans = 1LL * n * n * n;
  long long resX = 0;
  for (int i = 0; i < n; i++) {
    long long OUTX = out[i];
    long long INX = inp[i];
    resX += 2 * OUTX * (n - OUTX);
    resX += INX * (n - OUTX);
    resX += OUTX * (n - INX);
    resX += 2 * INX * (n - INX);
  }
  cout << ans - resX / 2;
}
