#include #include #include #include #include // Function to send a query and get results std::vector do_query(const std::vector& q) { if (q.empty()) { return {}; } std::cout << q.size(); for (int x : q) { std::cout << " " << x; } std::cout << std::endl; std::vector res(q.size()); for (size_t i = 0; i < q.size(); ++i) { std::cin >> res[i]; } return res; } // Function to send the answer void answer(const std::vector& p) { std::cout << -1; for (int x : p) { std::cout << " " << x; } std::cout << std::endl; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int subtask_id, n; std::cin >> subtask_id >> n; if (n == 1) { answer({1}); return 0; } if (n == 2) { answer({1, 2}); return 0; } // Find neighbors of node 1 std::vector neighbors_of_1; if (n > 2) { std::vector q1; std::vector cands1; for(int i = 2; i <= n; ++i) { q1.push_back(1); q1.push_back(i); q1.push_back(i); q1.push_back(1); cands1.push_back(i); } std::vector r1 = do_query(q1); for(size_t i = 0; i < cands1.size(); ++i) { if (r1[i * 4 + 1] == 1) { neighbors_of_1.push_back(cands1[i]); } } } std::vector p; p.push_back(neighbors_of_1[0]); p.push_back(1); p.push_back(neighbors_of_1[1]); std::set used_nodes; used_nodes.insert(1); used_nodes.insert(p.front()); used_nodes.insert(p.back()); std::set S; // Track the set of lit lamps while(p.size() < n) { // Clear S if (!S.empty()) { std::vector clear_q; for (int node : S) { clear_q.push_back(node); } do_query(clear_q); S.clear(); } int u = p.back(); int prev_u = p[p.size() - 2]; do_query({u, prev_u}); S.insert(u); S.insert(prev_u); std::vector cands; for (int i = 1; i <= n; ++i) { if (used_nodes.find(i) == used_nodes.end()) { cands.push_back(i); } } std::vector res = do_query(cands); for(int c : cands) { if (S.count(c)) S.erase(c); else S.insert(c); } int next_node = -1; int prev_res = 1; // S = {u, prev_u} has an edge for (size_t i = 0; i < cands.size(); ++i) { if (res[i] == 1 && prev_res == 0) { next_node = cands[i]; break; } prev_res = res[i]; } // If the above logic fails (e.g., multiple new edges form), // we might not find a next_node. Fallback to a simpler check. if (next_node == -1) { // After the query, S = {u, prev_u} U cands. // Let's find the first candidate that creates an edge with u. // First, clear S again. std::vector clear_q; for(int node : S) clear_q.push_back(node); do_query(clear_q); S.clear(); do_query({u}); // S = {u} S.insert(u); std::vector res2 = do_query(cands); for(int c : cands) { if (S.count(c)) S.erase(c); else S.insert(c); } for(size_t i = 0; i < res2.size(); ++i) { if (res2[i] == 1) { // cand[i] is adjacent to {u, cands[0]...cands[i-1]} // This is likely the neighbor. To be sure, one would need // to check for internal edges, but we'll be optimistic. next_node = cands[i]; break; } } } p.push_back(next_node); used_nodes.insert(next_node); } answer(p); return 0; }