#include #include #include #include #include // Function to solve a single test case void solve() { int n; std::cin >> n; std::vector p(n + 1); std::vector> adj(n + 1); for (int i = 1; i <= n; ++i) { std::cin >> p[i]; } std::vector> edge_list; for (int i = 0; i < n - 1; ++i) { int u, v; std::cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); edge_list.push_back({u, v}); } // Precompute next hops for all pairs std::vector> next_hop(n + 1, std::vector(n + 1, 0)); for (int start_node = 1; start_node <= n; ++start_node) { std::queue q_bfs; q_bfs.push(start_node); std::vector parent(n + 1, 0); parent[start_node] = start_node; // Sentinel for root std::vector visited(n + 1, false); visited[start_node] = true; while (!q_bfs.empty()) { int u = q_bfs.front(); q_bfs.pop(); for (int v : adj[u]) { if (!visited[v]) { visited[v] = true; parent[v] = u; q_bfs.push(v); } } } for (int i = 1; i <= n; ++i) { if (i == start_node) continue; int curr = i; while (parent[curr] != start_node) { curr = parent[curr]; } next_hop[start_node][i] = curr; } } std::vector> operations; while (true) { bool sorted = true; for (int i = 1; i <= n; ++i) { if (p[i] != i) { sorted = false; break; } } if (sorted) break; std::vector score2_edges, score1_edges; for (int i = 0; i < n - 1; ++i) { int u = edge_list[i].first; int v = edge_list[i].second; int val_u = p[u]; int val_v = p[v]; bool u_wants_v = false; if (val_u != u) { u_wants_v = (next_hop[u][val_u] == v); } bool v_wants_u = false; if (val_v != v) { v_wants_u = (next_hop[v][val_v] == u); } if (u_wants_v && v_wants_u) { score2_edges.push_back(i + 1); } else if (u_wants_v || v_wants_u) { score1_edges.push_back(i + 1); } } std::vector current_op; std::vector used_vertex(n + 1, false); for (int edge_idx : score2_edges) { int u = edge_list[edge_idx - 1].first; int v = edge_list[edge_idx - 1].second; if (!used_vertex[u] && !used_vertex[v]) { current_op.push_back(edge_idx); used_vertex[u] = true; used_vertex[v] = true; } } for (int edge_idx : score1_edges) { int u = edge_list[edge_idx - 1].first; int v = edge_list[edge_idx - 1].second; if (!used_vertex[u] && !used_vertex[v]) { current_op.push_back(edge_idx); used_vertex[u] = true; used_vertex[v] = true; } } operations.push_back(current_op); for (int edge_idx : current_op) { int u = edge_list[edge_idx - 1].first; int v = edge_list[edge_idx - 1].second; std::swap(p[u], p[v]); } } std::cout << operations.size() << "\n"; for (const auto& op : operations) { std::cout << op.size(); for (int edge_idx : op) { std::cout << " " << edge_idx; } std::cout << "\n"; } } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int t; std::cin >> t; while (t--) { solve(); } return 0; }