#include <bits/stdc++.h>   using namespace std;   const int N = 210000;   vector<int> p[N];   bool vis[N], inq[N];   int fa[N], froot[N], troot[N], size[N], q[N], powk[N], val[N], in0[N], out0[N],       in1[N], out1[N], n, jsb, goal, k, dep[N], inv[N];   inline int Pow(int a, int b) {     int c = 1;     for (; b; b >>= 1, a = a * 1ll * a % jsb)       if (b & 1) c = c * 1ll * a % jsb;     return c;   }   const int mo = 100007;   struct state {     int head[N], np[N], p[N], cnt[N];     int tot;     inline void clear() {       for (int i = (1); i <= (int)tot; i++) {         int x = p[i];         np[i] = cnt[i] = p[i] = 0;         x %= mo;         head[x] = 0;       }       tot = 0;     }     inline void add(int x) {       int pos = x % mo;       for (int u = head[pos]; u; u = np[u])         if (p[u] == x) {           cnt[u]++;           return;         }       tot++;       p[tot] = x;       cnt[tot] = 1;       np[tot] = head[pos];       head[pos] = tot;     }     inline int ask(int x) {       int pos = x % mo;       for (int u = head[pos]; u; u = np[u])         if (p[u] == x) {           return cnt[u];         }       return 0;     }   } cnt;   inline int getroot(int y) {     q[q[0] = 1] = y;     inq[y] = 1;     fa[y] = 0;     for (int i = (1); i <= (int)q[0]; i++) {       int x = q[i];       for (int j = (0); j <= (int)p[x].size() - 1; j++)         if (!inq[p[x][j]] && !vis[p[x][j]]) {           q[++q[0]] = p[x][j];           inq[p[x][j]] = 1;           fa[p[x][j]] = x;         }     }     int a, b;     b = 210000;     a = 0;     for (int i = (q[0]); i >= (int)1; i--) {       int x = q[i];       size[x] = 1;       int MA = -1;       for (int j = (0); j <= (int)p[x].size() - 1; j++)         if (inq[p[x][j]] && fa[x] != p[x][j] && !vis[p[x][j]]) {           size[x] += size[p[x][j]];           if (size[p[x][j]] > MA) MA = size[p[x][j]];         }       if (q[0] - size[x] > MA) MA = q[0] - size[x];       if (MA < b) {         b = MA;         a = x;       }     }     for (int i = (1); i <= (int)q[0]; i++) {       int x = q[i];       inq[x] = 0;     }     return a;   }   inline void Bfs1(int y) {     q[q[0] = 1] = y;     inq[y] = 1;     froot[y] = val[y];     troot[y] = val[y];     dep[y] = 0;     for (int i = (1); i <= (int)q[0]; i++) {       int x = q[i];       for (int j = (0); j <= (int)p[x].size() - 1; j++)         if (!inq[p[x][j]] && !vis[p[x][j]]) {           int d = p[x][j];           troot[d] = (troot[x] * 1ll * k + val[d]) % jsb;           dep[d] = dep[x] + 1;           froot[d] = (froot[x] + 1ll * powk[dep[d]] * val[d]) % jsb;           q[++q[0]] = d;           inq[d] = 1;         }     }     for (int i = (1); i <= (int)q[0]; i++) inq[q[i]] = 0;   }   inline void work(int rt, int y, int v) {     q[q[0] = 1] = y;     inq[y] = 1;     for (int i = (1); i <= (int)q[0]; i++) {       int x = q[i];       for (int j = (0); j <= (int)p[x].size() - 1; j++)         if (!inq[p[x][j]] && !vis[p[x][j]]) {           inq[p[x][j]] = 1;           q[++q[0]] = p[x][j];         }     }     for (int i = (1); i <= (int)q[0]; i++) cnt.add((froot[q[i]] + jsb) % jsb);     for (int i = (1); i <= (int)q[0]; i++) {       int x = q[i];       int key = powk[dep[x]] * 1ll * val[rt] % jsb;       key = (key + goal) % jsb;       key = (key - troot[x]) % jsb;       key = key * 1ll * inv[dep[x]] % jsb;       if (key < 0) key += jsb;       out1[x] += cnt.ask(key) * v;     }     cnt.clear();     for (int i = (1); i <= (int)q[0]; i++) {       int x = q[i];       int key = (goal - troot[x]) % jsb;       key = key * 1ll * inv[dep[x]] % jsb;       if (key < 0) key += jsb;       cnt.add(key);     }     for (int i = (1); i <= (int)q[0]; i++) {       int x = q[i];       int key = froot[x];       key = (key - val[rt]) % jsb;       if (key < 0) key += jsb;       in1[x] += cnt.ask(key) * v;     }     cnt.clear();     for (int i = (1); i <= (int)q[0]; i++) inq[q[i]] = 0;   }   void fenzhi(int y, int depp) {     int x = getroot(y);     Bfs1(x);     vis[x] = 1;     work(x, x, 1);     for (int i = (0); i <= (int)p[x].size() - 1; i++)       if (!vis[p[x][i]]) work(x, p[x][i], -1);     for (int i = (0); i <= (int)p[x].size() - 1; i++)       if (!vis[p[x][i]]) fenzhi(p[x][i], depp + 1);   }   int main() {     scanf( %d%d%d%d , &n, &jsb, &k, &goal);     powk[0] = 1;     for (int i = (1); i <= (int)n; i++) powk[i] = powk[i - 1] * 1ll * k % jsb;     for (int i = (0); i <= (int)n; i++) inv[i] = Pow(powk[i], jsb - 2);     for (int i = (1); i <= (int)n; i++) scanf( %d , &val[i]);     for (int i = (1); i <= (int)n - 1; i++) {       int u, v;       scanf( %d%d , &u, &v);       p[u].push_back(v);       p[v].push_back(u);     }     fenzhi(1, 0);     long long ans = 0;     for (int i = (1); i <= (int)n; i++) {       in0[i] = n - in1[i];       out0[i] = n - out1[i];       ans = (ans + 2ll * out1[i] * out0[i]);       ans = (ans + 2ll * in1[i] * in0[i]);       ans = (ans + 1ll * in1[i] * out0[i]);       ans = (ans + 1ll * in0[i] * out1[i]);     }     long long pa = n * 1ll * n;     pa = pa * 1ll * n;     ans /= 2;     printf( %I64d n , pa - ans);     return 0;   }