#include<atcoder/modint>#include<bits/stdc++.h>usingnamespacestd;usingnamespaceatcoder;usingmint=modint998244353;classTree{public:intn;vector<vector<int>>adj;vector<vector<mint>>dp;vector<int>a;// dp[i][d] is the count of induced connected subgraph such that the highest
// vertex is node i and it has degree d, and all vertices with degree 1
// except node i has the chosen color.
// All degrees >= 2 are treated as identical.
Tree(intn){this->n=n;adj.resize(n);a.resize(n);dp.resize(n,vector<mint>(3,0));}voiddfs(intsrc,intpar,intcolor){// Start with no children.
dp[src][0]=1;for(autochild:adj[src]){if(child==par){continue;}dfs(child,src,color);vector<mint>ndp(3);for(intd=0;d<3;d++){// Ignore this children.
ndp[d]+=dp[src][d];for(intnow=0;now<3;now++){if(now==0&&a[child]!=color){continue;}intnxt=d+1;if(nxt>1){nxt=2;}// Append this children.
ndp[nxt]+=dp[src][d]*dp[child][now];}}swap(dp[src],ndp);}}voidclear_dp(){for(inti=0;i<n;i++){for(intd=0;d<3;d++){dp[i][d]=0;}}}};voidsolve(){intn;cin>>n;Treet(n);auto&a=t.a;for(inti=0;i<n;i++){cin>>a[i];a[i]--;}intm=n-1;for(inti=0;i<m;i++){intx,y;cin>>x>>y;x--;y--;t.adj[x].push_back(y);t.adj[y].push_back(x);}mintans=0;auto&dp=t.dp;for(intcolor=0;color<n;color++){// Remember to clear DP before running DFS for new color.
t.clear_dp();t.dfs(0,-1,color);mintcur=0;for(inti=0;i<n;i++){if(a[i]==color){cur+=dp[i][0];cur+=dp[i][1];}cur+=dp[i][2];}ans+=cur;cout<<cur.val()<<" ";}cout<<endl;cout<<ans.val()<<endl;}intmain(){intt;cin>>t;for(inti=0;i<t;i++){solve();}return0;}