#include <bits/stdc++.h>
using namespace std;
const long long MOD = 998244353;
// Fast modular exponentiation (and inverse by Fermat’s little theorem)
long long modExp(long long base, long long exp) {
long long res = 1;
while(exp > 0) {
if(exp & 1) res = (res * base) % MOD;
base = (base * base) % MOD;
exp >>= 1;
}
return res;
}
long long modInv(long long x) {
return modExp(x, MOD - 2);
}
// In our forest of probabilities, each vertex i has
// F[i] = p[i]/q[i] (fall probability) and R[i] = 1 - F[i] (remain probability).
// A vertex becomes a leaf if it remains and exactly one neighbor remains.
// We then correct for dependencies when two vertices are “close.”
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t--){
int n;
cin >> n;
vector<long long> p(n), q(n), F(n), R(n), L(n, 0);
vector<vector<int>> graph(n);
for (int i = 0; i < n; i++){
cin >> p[i] >> q[i];
long long invq = modInv(q[i]);
F[i] = (p[i] % MOD * invq) % MOD; // falling probability
R[i] = (1 - F[i] + MOD) % MOD; // remaining probability
}
for (int i = 0; i < n - 1; i++){
int u, v;
cin >> u >> v;
u--; v--;
graph[u].push_back(v);
graph[v].push_back(u);
}
// Precompute for each vertex the product over its neighbors of F[neighbor]
vector<long long> prod(n, 1);
for (int i = 0; i < n; i++){
for (int nb : graph[i]){
prod[i] = (prod[i] * F[nb]) % MOD;
}
}
// Compute L[i]: probability vertex i becomes a leaf.
// If i has no neighbors, it can never be a leaf (by the problem’s definition).
for (int i = 0; i < n; i++){
if(graph[i].empty()){
L[i] = 0;
} else {
long long sumNeighbor = 0;
// For each neighbor j, the chance that j is the unique surviving neighbor:
// Multiply by R[j] and “cancel” F[j] from the full product over neighbors.
for (int nb : graph[i]){
long long term = (R[nb] * prod[i]) % MOD;
term = (term * modInv(F[nb])) % MOD;
sumNeighbor = (sumNeighbor + term) % MOD;
}
L[i] = (R[i] * sumNeighbor) % MOD;
}
}
// S0 is the "naively independent" contribution:
// S0 = 1/2 * [ (sum_i L[i])^2 - sum_i L[i]^2 ]
long long sumL = 0, sumL2 = 0;
for (int i = 0; i < n; i++){
sumL = (sumL + L[i]) % MOD;
sumL2 = (sumL2 + (L[i] * L[i]) % MOD) % MOD;
}
long long inv2 = modInv(2);
long long S0 = (((sumL * sumL) % MOD - sumL2 + MOD) % MOD * inv2) % MOD;
// Correction for adjacent vertices:
// For an edge (u,v), both become leaves only if they “choose each other.”
long long sum_adj = 0;
for (int u = 0; u < n; u++){
for (int v : graph[u]){
if(u < v){
long long term = (R[u] * R[v]) % MOD;
// In vertex u, the unique surviving neighbor must be v:
long long part_u = (prod[u] * modInv(F[v])) % MOD;
// And vice versa for vertex v.
long long part_v = (prod[v] * modInv(F[u])) % MOD;
term = (term * ((part_u * part_v) % MOD)) % MOD;
term = (term - (L[u] * L[v]) % MOD + MOD) % MOD;
sum_adj = (sum_adj + term) % MOD;
}
}
}
// Correction for pairs of vertices at distance 2 (they share a common neighbor u).
// We sum over each vertex u as the common neighbor.
long long sum_dist2 = 0;
for (int u = 0; u < n; u++){
int d = graph[u].size();
if(d < 2) continue;
// We want to compute, over unordered pairs (i, j) among neighbors of u, the sum
// of δ^{(2)}_{ij} defined by:
// δ^{(2)}_{ij} = R[i]*R[j]*( R[u]*(A_i*A_j)
// + ((L[i] - R[i]*R[u]*A_i) * (L[j] - R[j]*R[u]*A_j) * inv(F[u]) ) )
// - L[i]*L[j],
// where A_i = prod[i] * inv(F[u]).
//
// We can sum these pairs in O(d) per u by precomputing sums.
long long invF_u = modInv(F[u]);
long long invF_u2 = (invF_u * invF_u) % MOD;
long long sum_RA = 0, sum_RA2 = 0; // for term1: using X_i = R[i]*prod[i]
long long sum_B = 0, sum_B2 = 0; // for term2: using B[i] = R[i]*(L[i] - R[i]*R[u]*(prod[i]*invF_u))
long long sum_Lu = 0, sum_Lu2 = 0; // for term3: using L[i]
for (int i : graph[u]) {
long long X = (R[i] * prod[i]) % MOD; // note: A_i will be X * invF_u
sum_RA = (sum_RA + X) % MOD;
sum_RA2 = (sum_RA2 + (X * X) % MOD) % MOD;
sum_Lu = (sum_Lu + L[i]) % MOD;
sum_Lu2 = (sum_Lu2 + (L[i] * L[i]) % MOD) % MOD;
long long A = (prod[i] * invF_u) % MOD;
long long diff = (L[i] - (R[i] * R[u]) % MOD * A % MOD + MOD) % MOD;
long long B = (R[i] * diff) % MOD;
sum_B = (sum_B + B) % MOD;
sum_B2 = (sum_B2 + (B * B) % MOD) % MOD;
}
// Term1: contribution from R[u]*A_i*A_j over pairs
long long term1 = (R[u] * invF_u2) % MOD;
term1 = (term1 * (((sum_RA * sum_RA) % MOD - sum_RA2 + MOD) % MOD)) % MOD;
term1 = (term1 * inv2) % MOD;
// Term2: contribution from the difference part, multiplied by inv(F[u])
long long term2 = (invF_u * (((sum_B * sum_B) % MOD - sum_B2 + MOD) % MOD)) % MOD;
term2 = (term2 * inv2) % MOD;
// Term3: subtract the “naive” product over L-values
long long term3 = (((sum_Lu * sum_Lu) % MOD - sum_Lu2 + MOD) % MOD * inv2) % MOD;
long long cur_u = (term1 + term2 - term3 + MOD) % MOD;
sum_dist2 = (sum_dist2 + cur_u) % MOD;
}
// Final answer is S0 plus 1/2 times the sum of adjacent and distance–2 corrections.
long long finalAns = (S0 + inv2 * ((sum_adj + sum_dist2) % MOD)) % MOD;
cout << finalAns % MOD << "\n";
}
return 0;
}