| #include <bits/stdc++.h> |
| using namespace std; |
|
|
| vector<vector<int>> create_map(int N, int M, vector<int> A, vector<int> B) { |
| |
| vector<vector<int>> g(N + 1); |
| vector<vector<bool>> adj(N + 1, vector<bool>(N + 1, false)); |
| for (int i = 0; i < M; ++i) { |
| int u = A[i], v = B[i]; |
| g[u].push_back(v); |
| g[v].push_back(u); |
| adj[u][v] = adj[v][u] = true; |
| } |
| |
| if (N == 1) { |
| |
| return vector<vector<int>>(1, vector<int>(1, 1)); |
| } |
| |
| vector<vector<int>> treeAdj(N + 1); |
| vector<int> vis(N + 1, 0); |
| vector<pair<int,int>> treeEdges; |
| function<void(int)> dfs_build = [&](int u){ |
| vis[u] = 1; |
| for (int v : g[u]) { |
| if (!vis[v]) { |
| treeAdj[u].push_back(v); |
| treeAdj[v].push_back(u); |
| treeEdges.emplace_back(u, v); |
| dfs_build(v); |
| } |
| } |
| }; |
| |
| dfs_build(1); |
|
|
| |
| vector<vector<bool>> isTree(N + 1, vector<bool>(N + 1, false)); |
| for (auto &e : treeEdges) { |
| int u = e.first, v = e.second; |
| isTree[u][v] = isTree[v][u] = true; |
| } |
|
|
| |
| vector<int> seq; |
| function<void(int,int)> euler = [&](int u, int p){ |
| seq.push_back(u); |
| for (int v : treeAdj[u]) { |
| if (v == p) continue; |
| euler(v, u); |
| seq.push_back(u); |
| } |
| }; |
| euler(1, 0); |
|
|
| int L = (int)seq.size(); |
|
|
| |
| vector<int> firstOcc(N + 1, -1); |
| for (int i = 0; i < L; ++i) { |
| int u = seq[i]; |
| if (firstOcc[u] == -1) firstOcc[u] = i; |
| } |
|
|
| |
| vector<vector<int>> islands(N + 1); |
| for (int i = 0; i < M; ++i) { |
| int u = A[i], v = B[i]; |
| if (isTree[u][v]) continue; |
| int assign = (firstOcc[u] <= firstOcc[v]) ? u : v; |
| int other = (assign == u ? v : u); |
| islands[assign].push_back(other); |
| } |
|
|
| |
| auto bandWidth = [&](int u)->int{ |
| |
| |
| return 1 + 2 * (int)islands[u].size(); |
| }; |
|
|
| int W_base = 1; |
| for (int u = 1; u <= N; ++u) { |
| W_base = max(W_base, bandWidth(u)); |
| } |
|
|
| int H = 3 * L; |
| int K = max(H, W_base); |
| if (K < 1) K = 1; |
| K = min(K, 240); |
|
|
| vector<vector<int>> C(K, vector<int>(K, 1)); |
|
|
| |
| for (int r = 0; r < K; ++r) { |
| int bandIdx, kind; |
| int u; |
| if (r < H) { |
| bandIdx = r / 3; |
| kind = r % 3; |
| u = seq[bandIdx]; |
| } else { |
| |
| bandIdx = L - 1; |
| kind = 2; |
| u = seq[bandIdx]; |
| } |
|
|
| if (kind != 1) { |
| |
| for (int c = 0; c < K; ++c) C[r][c] = u; |
| } else { |
| |
| if (bandIdx == firstOcc[u]) { |
| int pos = 0; |
| if (pos < K) C[r][pos++] = u; |
| for (int v : islands[u]) { |
| if (pos < K) C[r][pos++] = v; |
| if (pos < K) C[r][pos++] = u; |
| } |
| |
| for (; pos < K; ++pos) C[r][pos] = u; |
| } else { |
| |
| for (int c = 0; c < K; ++c) C[r][c] = u; |
| } |
| } |
| } |
|
|
| return C; |
| } |
|
|
| int main() { |
| ios::sync_with_stdio(false); |
| cin.tie(nullptr); |
| int T; |
| if (!(cin >> T)) return 0; |
| while (T--) { |
| int N, M; |
| cin >> N >> M; |
| vector<int> A(M), B(M); |
| for (int i = 0; i < M; ++i) cin >> A[i] >> B[i]; |
| vector<vector<int>> C = create_map(N, M, A, B); |
| int P = (int)C.size(); |
| cout << P << "\n"; |
| for (int i = 0; i < P; ++i) { |
| cout << (int)C[i].size() << (i + 1 == P ? '\n' : ' '); |
| } |
| cout << "\n"; |
| for (int i = 0; i < P; ++i) { |
| for (int j = 0; j < (int)C[i].size(); ++j) { |
| cout << C[i][j] << (j + 1 == (int)C[i].size() ? '\n' : ' '); |
| } |
| } |
| cout.flush(); |
| } |
| return 0; |
| } |