#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3fll;
const int maxn = 1e5 + 5;
long long mod, K, X;
int z[maxn];
vector<int> V[maxn];
long long Pow[maxn], Powinv[maxn];
long long qpow(long long base, long long num) {
  long long ret = 1;
  while (num) {
    if (num & 1) ret = ret * base % mod;
    base = base * base % mod;
    num >>= 1;
  }
  return ret;
}
bool ban[maxn];
vector<pair<pair<int, int>, pair<long long, long long> > > nodeV;
map<long long, long long> val2rootcalcM, val4rootM;
long long in0[maxn], out0[maxn];
int Sz[maxn];
void clear() {
  val2rootcalcM.clear();
  val4rootM.clear();
}
void calc(int x, int fa, long long val2root, long long val4root, int dep,
          int flag) {
  val2root = (val2root * K + z[x]) % mod;
  val4root = (val4root + z[x] * Pow[dep]) % mod;
  val4rootM[val4root] += flag;
  val2rootcalcM[((X - val2root) * Powinv[dep] % mod + mod) % mod] += flag;
  nodeV.push_back(make_pair(make_pair(x, dep), make_pair(val2root, val4root)));
  int sz = V[x].size();
  for (int i = 0; i < sz; i++)
    if (V[x][i] != fa && !ban[V[x][i]])
      calc(V[x][i], x, val2root, val4root, dep + 1, flag);
}
int dfs_size(int x, int fa) {
  Sz[x] = 1;
  int sz = V[x].size();
  for (int i = 0; i < sz; i++)
    if (V[x][i] != fa && !ban[V[x][i]]) Sz[x] += dfs_size(V[x][i], x);
  return Sz[x];
}
int zx;
void dfs_ans(int x, int fa, int all) {
  int flag = true;
  if ((all - Sz[x]) * 2 > all) flag = false;
  int sz = V[x].size();
  for (int i = 0; i < sz; i++)
    if (V[x][i] != fa && !ban[V[x][i]]) {
      if (Sz[V[x][i]] * 2 > all) flag = false;
    }
  if (flag) zx = x;
  for (int i = 0; i < sz; i++)
    if (V[x][i] != fa && !ban[V[x][i]]) {
      dfs_ans(V[x][i], x, all);
    }
}
int find(int x) {
  dfs_size(x, x);
  zx = 0;
  dfs_ans(x, x, Sz[x]);
  return zx;
}
void solve(int x) {
  clear();
  int root = find(x);
  nodeV.clear();
  ban[root] = 1;
  int sz = V[root].size();
  for (int i = 0; i < sz; i++)
    if (!ban[V[root][i]]) {
      nodeV.clear();
      calc(V[root][i], root, z[root], 0, 1, 1);
    }
  if (z[root] % mod == X) in0[root]++, out0[root]++;
  out0[root] += val4rootM[(X - z[root] + mod) % mod];
  in0[root] += val2rootcalcM[0];
  val4rootM[0]++;
  val2rootcalcM[(X - z[root] + mod) % mod]++;
  for (int i = 0; i < sz; i++)
    if (!ban[V[root][i]]) {
      nodeV.clear();
      calc(V[root][i], root, z[root], 0, 1, -1);
      int szz = nodeV.size();
      for (int j = 0; j < szz; j++) {
        int no = nodeV[j].first.first, dep = nodeV[j].first.second;
        long long val2root = nodeV[j].second.first,
                  val4root = nodeV[j].second.second;
        long long tmp = (X - val2root) * Powinv[dep] % mod;
        tmp = (tmp + mod) % mod;
        out0[no] += val4rootM[tmp];
        in0[no] += val2rootcalcM[val4root];
      }
      nodeV.clear();
      calc(V[root][i], root, z[root], 0, 1, 1);
    }
  for (int i = 0; i < sz; i++)
    if (!ban[V[root][i]]) {
      solve(V[root][i]);
    }
}
long long in1[maxn], out1[maxn];
int main() {
  int n;
  scanf("%d%I64d%I64d%I64d", &n, &mod, &K, &X);
  for (int i = 1; i <= n; i++) scanf("%d", z + i);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    V[u].push_back(v);
    V[v].push_back(u);
  }
  Pow[0] = Powinv[0] = 1;
  long long tmp = qpow(K, mod - 2);
  for (int i = 1; i <= n; i++) {
    Pow[i] = Pow[i - 1] * K % mod;
    Powinv[i] = Powinv[i - 1] * tmp % mod;
  }
  solve(1);
  for (int i = 1; i <= n; i++) in1[i] = n - in0[i], out1[i] = n - out0[i];
  long long p = 0;
  for (int i = 1; i <= n; i++) {
    p += 2 * out0[i] * out1[i] + 2 * in0[i] * in1[i] + in0[i] * out1[i] +
         in1[i] * out0[i];
  }
  printf("%I64d\n", 1ll * n * n * n - p / 2);
  return 0;
}
