#include #include #include using i64 = long long; constexpr int MOD = 998244353; template struct ReRooting { using Graph = std::vector>; using MergeFunc = std::function; using AddNodeFunc = std::function; Graph G; Monoid IDE; MergeFunc MERGE; AddNodeFunc ADDNODE; std::vector> dp; ReRooting() {} ReRooting(const Graph &g, const Monoid &ide, \ const MergeFunc &merge, const AddNodeFunc &addnode) { G = g; IDE = ide; MERGE = merge; ADDNODE = addnode; build(); } Monoid rec(int v, int p) { Monoid res = IDE; dp[v].assign(G[v].size(), IDE); for(int i=0;i left(G[v].size() + 1, IDE); std::vector right(G[v].size() + 1, IDE); for(int i=0;i()); int root = 0, nullparent = -1; rec(root, nullparent); rerec(root, nullparent, IDE); } Monoid get(int v) { Monoid res = IDE; for(int i=0;i>1); if(k&1) return (((half * half) % MOD) * n) % MOD; return (half * half) % MOD; } int main() { int N; std::cin >> N; std::vector A(N); for(int i=0;i> A[i]; std::vector> G(N, std::vector()); for(int i=0;i> u >> v; u--;v--; G[u].push_back(v); G[v].push_back(u); } auto merge = [&](i64 a, i64 b) { return (a + b) % MOD; }; auto add = [&](int v, i64 a) { return ((a + 1) * A[v]) % MOD; }; i64 identity = 0; ReRooting rr(G, identity, merge, add); i64 ans = 0; for(int v=0;v