#include using namespace std; vector> create_map(int N, int M, vector A, vector B) { // Build adjacency list vector> g(N + 1); vector> adj(N + 1, vector(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; } // Handle N=1 separately if (N == 1) { // Any K >=1, choose K=1 return vector>(1, vector(1, 1)); } // Build a spanning tree using DFS vector> treeAdj(N + 1); vector vis(N + 1, 0); vector> treeEdges; function 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); } } }; // Assume graph is connected as per problem guarantee dfs_build(1); // Mark tree edges vector> isTree(N + 1, vector(N + 1, false)); for (auto &e : treeEdges) { int u = e.first, v = e.second; isTree[u][v] = isTree[v][u] = true; } // Generate Euler tour-like sequence on the tree: seq length = 2N - 1 vector seq; function 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(); // First occurrence index for each vertex in seq vector firstOcc(N + 1, -1); for (int i = 0; i < L; ++i) { int u = seq[i]; if (firstOcc[u] == -1) firstOcc[u] = i; } // Assign non-tree edges to one endpoint (the one with earlier first occurrence) vector> islands(N + 1); for (int i = 0; i < M; ++i) { int u = A[i], v = B[i]; if (isTree[u][v]) continue; // tree edge will be realized by band boundaries int assign = (firstOcc[u] <= firstOcc[v]) ? u : v; int other = (assign == u ? v : u); islands[assign].push_back(other); } // Compute required width per vertex band auto bandWidth = [&](int u)->int{ // Only place islands on the first occurrence band // Each island uses pattern: ... u v u ... so width = 1 + 2 * (#islands[u]) 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); // Safety, though our construction ensures K <= 237. vector> C(K, vector(K, 1)); // Build the grid for (int r = 0; r < K; ++r) { int bandIdx, kind; int u; if (r < H) { bandIdx = r / 3; kind = r % 3; // 0: top u, 1: middle (with islands), 2: bottom u u = seq[bandIdx]; } else { // Fill remaining rows with last band's bottom row to avoid new adjacencies bandIdx = L - 1; kind = 2; u = seq[bandIdx]; } if (kind != 1) { // Uniform row of color u for (int c = 0; c < K; ++c) C[r][c] = u; } else { // Middle row: only place islands if this is the first occurrence band for u 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; } // Fill the rest with u for (; pos < K; ++pos) C[r][pos] = u; } else { // Not first occurrence band: keep uniform u 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 A(M), B(M); for (int i = 0; i < M; ++i) cin >> A[i] >> B[i]; vector> 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; }