#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 1e5 + 10;
unordered_map<long long, long long> w[MAXN];
unordered_map<long long, long long> f[MAXN];
vector<long long> vertex[MAXN];
long long a[MAXN];
long long b[MAXN];
long long c[MAXN];
long long kpw[MAXN];
long long rkpw[MAXN];
long long check[MAXN];
long long subtree[MAXN];
bool centroid_check[MAXN];
long long n, Mod, k, x, t = 1;
long long pw(long long x, long long n) {
  if (n == 0) {
    return 1;
  }
  long long z = pw(x, n / 2);
  z *= z;
  z %= Mod;
  if (n & 1) {
    z *= x;
    z %= Mod;
  }
  return z;
}
void set_dfs(long long v, long long id1, long long id2, long long x1,
             long long x2, long long h) {
  check[v] = t;
  h++;
  x1 *= k;
  x1 %= Mod;
  x1 += a[v];
  x1 %= Mod;
  long long z1 = x - x1 + Mod;
  z1 %= Mod;
  z1 *= rkpw[h];
  z1 %= Mod;
  w[id1][z1]++;
  w[id2][z1]++;
  x2 += kpw[h - 1] * a[v];
  x2 %= Mod;
  f[id1][x2]++;
  f[id2][x2]++;
  for (long long i = 0; i < vertex[v].size(); i++) {
    if (!centroid_check[vertex[v][i]] && check[vertex[v][i]] != t) {
      set_dfs(vertex[v][i], id1, (id2 == n + 1 ? vertex[v][i] : id2), x1, x2,
              h);
    }
  }
}
void add_dfs(long long v, long long id1, long long id2, long long x1,
             long long x2, long long h) {
  check[v] = t;
  h++;
  x1 *= k;
  x1 %= Mod;
  x1 += a[v];
  x1 %= Mod;
  long long z1 = x - x1 + Mod;
  z1 %= Mod;
  z1 *= rkpw[h];
  z1 %= Mod;
  b[v] += f[id1][z1] - f[id2][z1];
  x2 += kpw[h - 1] * a[v];
  x2 %= Mod;
  c[v] += w[id1][x2] - w[id2][x2];
  for (long long i = 0; i < vertex[v].size(); i++) {
    if (!centroid_check[vertex[v][i]] && check[vertex[v][i]] != t) {
      add_dfs(vertex[v][i], id1, id2, x1, x2, h);
    }
  }
}
void solve(long long v) {
  for (long long i = 0; i < vertex[v].size(); i++) {
    if (!centroid_check[vertex[v][i]]) {
      w[vertex[v][i]].clear();
      f[vertex[v][i]].clear();
    }
  }
  t++;
  w[v].clear();
  f[v].clear();
  set_dfs(v, v, n + 1, 0, 0, 0);
  b[v] += f[v][x];
  c[v] += w[v][0];
  for (long long i = 0; i < vertex[v].size(); i++) {
    if (!centroid_check[vertex[v][i]]) {
      t++;
      add_dfs(vertex[v][i], v, vertex[v][i], 0, 0, 0);
    }
  }
}
void set_subtree(long long v) {
  check[v] = t;
  subtree[v] = 1;
  for (long long i = 0; i < vertex[v].size(); i++) {
    if (!centroid_check[vertex[v][i]] && check[vertex[v][i]] != t) {
      set_subtree(vertex[v][i]);
      subtree[v] += subtree[vertex[v][i]];
    }
  }
}
long long get_centroid(long long v, long long root) {
  check[v] = t;
  for (long long i = 0; i < vertex[v].size(); i++) {
    if (!centroid_check[vertex[v][i]] && check[vertex[v][i]] != t &&
        2 * subtree[vertex[v][i]] > subtree[root]) {
      return get_centroid(vertex[v][i], root);
    }
  }
  return v;
}
void centroid_dfs(long long v) {
  centroid_check[v] = true;
  solve(v);
  for (long long i = 0; i < vertex[v].size(); i++) {
    if (!centroid_check[vertex[v][i]]) {
      t++;
      set_subtree(vertex[v][i]);
      t++;
      centroid_dfs(get_centroid(vertex[v][i], vertex[v][i]));
    }
  }
}
int main() {
  ios_base ::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> Mod >> k >> x;
  for (long long i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (long long i = 0; i < (n - 1); i++) {
    long long v, u;
    cin >> v >> u;
    vertex[v].push_back(u);
    vertex[u].push_back(v);
  }
  kpw[0] = 1;
  rkpw[0] = 1;
  for (long long i = 1; i < MAXN; i++) {
    kpw[i] = kpw[i - 1] * k;
    kpw[i] %= Mod;
    rkpw[i] = pw(kpw[i], Mod - 2);
  }
  centroid_dfs(1);
  long long res = 2 * n * n * n;
  for (long long i = 1; i <= n; i++) {
    res -= b[i] * (n - c[i]);
    res -= 2 * b[i] * (n - b[i]);
    res -= 2 * c[i] * (n - c[i]);
    res -= c[i] * (n - b[i]);
  }
  cout << res / 2;
}
