#include using namespace std; #define rep(i, l, n) for(int i = int(l); i < int(n); i++) #define ll long long #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() template bool chmin(T &a, T b) {if(a > b) {a = b; return true;} return false;} template bool chmax(T &a, T b) {if(a < b) {a = b; return true;} return false;} template using spq = priority_queue, greater>; // bool -> Yes/No string answer(bool b) {return b ? "Yes" : "No";} void fix(int k) {cout << fixed << setprecision(k);} const int inf = 2e9; const long long INF = 2e18; const long double eps = 1e-12; const long double pi = acos(-1); int dx[] = {0, -1, 0, 1, -1, -1, 1, 1}, dy[] = {1, 0, -1, 0, 1, -1, -1, 1}; // verify : https://atcoder.jp/contests/abc428/submissions/70542879 // 全方位木dp template struct Rerooting { int n; S unit; std::vector> dp; std::vector ans; std::vector> g; Rerooting(int N) : n(N) { unit = id(); dp.resize(N); ans.assign(N, unit); g.resize(N); } void add_edge(int a, int b) { assert(0 <= a && a < n); assert(0 <= b && b < n); g[a].emplace_back(b); g[b].emplace_back(a); } std::vector build() { dfs(0); bfs(0, unit); return ans; } S dfs(int v, int par = -1) { S x = unit; int m = g[v].size(); dp[v].assign(m, unit); for(int i = 0; i < m; i++) { int u = g[v][i]; if(u == par) continue; dp[v][i] = dfs(u, v); x = merge(x, dp[v][i]); } return add_root(x, v); } void bfs(int v, const S &p_val, int par = -1) { int m = g[v].size(); for(int i = 0; i < m; i++) { if(g[v][i] == par) dp[v][i] = p_val; } std::vector right_values(m + 1, unit); for(int i = m - 1; i >= 0; i--) { right_values[i] = merge(right_values[i + 1], dp[v][i]); } ans[v] = add_root(right_values[0], v); S last = unit, cur = unit; for(int i = 0; i < m; i++) { last = cur; cur = merge(last, dp[v][i]); int u = g[v][i]; if(u == par) continue; bfs(u, add_root(merge(last, right_values[i + 1]), v), v); } } }; struct S { array cnt; S() {rep(i, 0, 4) cnt[i] = 0;} }; S merge(S a, S b) { S ret; rep(i, 0, 4) ret.cnt[i] = a.cnt[i] + b.cnt[i]; return ret; } S add_root(S x, int v) { x.cnt[3] = x.cnt[2]; x.cnt[2] = x.cnt[1]; x.cnt[1] = x.cnt[0]; x.cnt[0] = 1; return x; } S id() {return S();} int n; void main_program() { cin >> n; Rerooting tree_dp(n); rep(i, 1, n) { int u, v; cin >> u >> v; tree_dp.add_edge(--u, --v); } long ans = 0; for(S res : tree_dp.build()) { ans += res.cnt[3]; //cout << res.cnt[0] << " " << res.cnt[1] << " " << res.cnt[2] << " " << res.cnt[3] << "\n"; } cout << (ans >> 1) % 998244353 << "\n"; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T = 1; cin >> T; while(T--) { main_program(); } }