#include <bits/stdc++.h>
const int maxn = 1e5 + 5;
const int maxm = maxn * 2 + 5;
struct edge {
  int to;
  int next;
} qxx[maxm];
int qxx_cnt, h[maxn];
void add(int x, int y) {
  qxx[++qxx_cnt] = (edge){y, h[x]};
  h[x] = qxx_cnt;
  return;
}
void ad(int x, int y) {
  add(x, y);
  add(y, x);
  return;
}
long long qpow(long long a, int b, int mod) {
  long long ans = 1;
  while (b) {
    if (b & 1) (ans *= a) %= mod;
    (a *= a) %= mod;
    b >>= 1;
  }
  return ans;
}
int tot, root;
bool vis[maxn];
int size[maxn], mx[maxn];
void findr(int x, int f) {
  size[x] = 1;
  mx[x] = 0;
  for (int i = h[x]; i; i = qxx[i].next) {
    int v = qxx[i].to;
    if (vis[v] || v == f) continue;
    findr(v, x);
    size[x] += size[v];
    mx[x] = std::max(mx[x], size[v]);
  }
  mx[x] = std::max(mx[x], tot - size[x]);
  if (mx[x] < mx[root] || !root) root = x;
  return;
}
int n, mod, base, eqm;
int val[maxn];
long long po[maxn], inv[maxn];
long long ing[maxn], inb[maxn], outg[maxn], outb[maxn];
struct point {
  int id;
  long long val;
  friend bool operator<(point now, point oth) { return now.val < oth.val; }
} ls[maxn], rs[maxn];
int scnt;
void ins(int x, int dep, long long lef, long long rig) {
  ls[++scnt] = (point){x, (eqm - lef + mod) * inv[dep + 1] % mod};
  rs[scnt] = (point){x, rig};
  return;
}
void getval(int x, int f, int dep, long long lef, long long rig) {
  lef = (lef * base + val[x]) % mod;
  if (dep) rig = (rig + po[dep - 1] * val[x]) % mod;
  ins(x, dep, lef, rig);
  for (int i = h[x]; i; i = qxx[i].next) {
    int v = qxx[i].to;
    if (vis[v] || v == f) continue;
    getval(v, x, dep + 1, lef, rig);
  }
  return;
}
void move(int coe) {
  int sam = 0;
  int lcn = 1, rcn = 1;
  while (lcn <= scnt) {
    while (rcn <= scnt && rs[rcn].val <= ls[lcn].val) {
      if (rcn == 1 || rs[rcn].val != rs[rcn - 1].val) sam = 0;
      sam++;
      rcn++;
    }
    if (rcn != 1 && rs[rcn - 1].val == ls[lcn].val)
      outg[ls[lcn].id] += sam * coe;
    lcn++;
  }
  lcn = rcn = 1;
  sam = 0;
  while (rcn <= scnt) {
    while (lcn <= scnt && ls[lcn].val <= rs[rcn].val) {
      if (lcn == 1 || ls[lcn].val != ls[lcn - 1].val) sam = 0;
      sam++;
      lcn++;
    }
    if (lcn != 1 && ls[lcn - 1].val == rs[rcn].val)
      ing[rs[rcn].id] += sam * coe;
    rcn++;
  }
  return;
}
void rely(int x, int coe, int dep, long long lef, long long rig) {
  scnt = 0;
  lef = (lef * base + val[x]) % mod;
  if (dep) rig = (rig + po[dep - 1] * val[x]) % mod;
  ins(x, dep, lef, rig);
  for (int i = h[x]; i; i = qxx[i].next) {
    int v = qxx[i].to;
    if (vis[v]) continue;
    getval(v, x, dep + 1, lef, rig);
  }
  std::sort(ls + 1, ls + scnt + 1);
  std::sort(rs + 1, rs + scnt + 1);
  move(coe);
  return;
}
void tian(int x) {
  vis[x] = true;
  rely(x, 1, 0, 0, 0);
  for (int i = h[x]; i; i = qxx[i].next) {
    int v = qxx[i].to;
    if (vis[v]) continue;
    rely(v, -1, 1, val[x], 0);
  }
  for (int i = h[x]; i; i = qxx[i].next) {
    int v = qxx[i].to;
    if (vis[v]) continue;
    tot = size[v];
    root = 0;
    findr(v, 0);
    tian(root);
  }
  return;
}
long long ans;
void init() {
  long long invb = qpow(1ll * base, mod - 2, mod);
  po[0] = 1;
  inv[0] = 1;
  for (int i = 1; i <= maxn - 2; i++) {
    po[i] = 1ll * po[i - 1] * base % mod;
    inv[i] = 1ll * inv[i - 1] * invb % mod;
  }
  return;
}
signed main() {
  scanf("%d%d%d%d", &n, &mod, &base, &eqm);
  for (int i = 1; i <= n; i++) scanf("%d", val + i);
  for (int i = 1; i <= n - 1; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    ad(x, y);
  }
  init();
  findr(1, 0);
  tian(root);
  for (int i = 1; i <= n; i++) {
    inb[i] = n - ing[i];
    outb[i] = n - outg[i];
    ans += ing[i] * inb[i] * 2 + outg[i] * outb[i] * 2 + ing[i] * outb[i] +
           inb[i] * outg[i];
  }
  printf("%lld", 1ll * n * n * n - ans / 2);
  return 0;
}
