import std; void main () { int N = readln.chomp.to!int; auto A = readln.split.to!(int[]); const long MOD = 998244353; auto graph = new int[][](N, 0); foreach (i; 0..N - 1) { int U, V; readln.read(U, V); U--, V--; graph[U] ~= V; graph[V] ~= U; } long ans = 0; auto dp = new long[](N); // dp[i] := iを根とする部分木に属するすべての頂点jに対して、f(i, j)の総和 void dfs (int pos, int par) { long s = 0; foreach (to; graph[pos]) { if (to == par) continue; dfs(to, pos); ans += s * A[pos] % MOD * dp[to] % MOD; s += dp[to]; if (MOD <= s) s -= MOD; } dp[pos] = (s + 1) * A[pos] % MOD; ans += dp[pos] - A[pos]; if (MOD <= ans) ans -= MOD; } dfs(0, -1); writeln(ans); } void read (T...) (string S, ref T args) { import std.conv : to; import std.array : split; auto buf = S.split; foreach (i, ref arg; args) { arg = buf[i].to!(typeof(arg)); } }