structEdge { int to, next; } e[maxn * 2]; int c1, head[maxn], du[maxn]; inlinevoidadd_edge(int u, int v){ e[c1].to = v; e[c1].next = head[u]; head[u] = c1++; }
vector<int> E[maxn]; boolcheck(vector<int> &a){ // 事实证明 vector 跑的最快 for (auto u : a) for (auto v : a) { if (u == v) break; if (!binary_search(E[u].begin(), E[u].end(), v)) return0; } return1; }
int vis[maxn]; voidinit(){ memset(head, -1, sizeof head); for (int i = 1; i <= n; ++i) head[i] = -1, E[i].clear(), du[i] = vis[i] = 0; c1 = 0; }
voidwork(){ cin >> n >> m >> k; init(); for (int i = 1; i <= m; ++i) { int x, y; cin >> x >> y; add_edge(x, y); add_edge(y, x); ++du[x]; ++du[y]; E[x].pb(y); E[y].pb(x); } queue<int> Q; for (int i = 1; i <= n; ++i) sort(E[i].begin(), E[i].end()); for (int i = 1; i <= n; ++i) if (du[i] < k) Q.push(i); while (!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = 1; if (du[u] == k - 1 && 1ll * k * (k - 1) / 2 <= m) { vector<int> clique = { u }; for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (vis[v]) continue; clique.pb(v); } if (check(clique)) { cout << 2 << "\n"; for (auto u : clique) cout << u << " "; cout << "\n"; return ; } } for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (--du[v] == k - 1) Q.push(v); } } int s = 0; for (int i = 1; i <= n; ++i) s += du[i] >= k; if (s) { cout << 1 << " " << s << endl; for (int i = 1; i <= n; ++i) if (du[i] >= k) cout << i << " "; cout << "\n"; return ; } cout << "-1\n"; }
intmain(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T; cin >> T; while (T--) work(); return0; }