← Home
```go
package main

import (
	"container/heap"
	"fmt"
)

type Query struct {
	u, v int
}

var parent []int
var diff []map[int]bool

func find(i int) int {
	if parent[i] == i {
		return i
	}
	parent[i] = find(parent[i])
	return parent[i]
}

func merge(u, v int) {
	ru := find(u)
	rv := find(v)
	if ru == rv {
		return
	}
	if len(diff[ru]) < len(diff[rv]) {
		ru, rv = rv, ru
	}
	parent[rv] = ru
	for neighbor := range diff[rv] {
		diff[ru][neighbor] = true
		diff[neighbor][ru] = true
		delete(diff[neighbor], rv)
	}
	diff[rv] = nil
}

func deduce(n int) {
	changed := true
	for changed {
		changed = false
		var toMerge [][2]int
		for C := 1; C <= n; C++ {
			if C != find(C) {
				continue
			}
			for D := range diff[C] {
				if C >= D {
					continue
				}
				set1, set2 := diff[C], diff[D]
				if len(set1) > len(set2) {
					set1, set2 = set2, set1
				}
				var same []int
				for A := range set1 {
					if set2[A] {
						same = append(same, A)
					}
				}
				if len(same) > 1 {
					for k := 1; k < len(same); k++ {
						if find(same[0]) != find(same[k]) {
							toMerge = append(toMerge, [2]int{same[0], same[k]})
						}
					}
				}
			}
		}
		for _, pair := range toMerge {
			if find(pair[0]) != find(pair[1]) {
				merge(pair[0], pair[1])
				changed = true
			}
		}
	}
}

type RootItem struct {
	root  int
	count int
}

type RootHeap []*RootItem

func (h RootHeap) Len() int           { return len(h) }
func (h RootHeap) Less(i, j int) bool { return h[i].count > h[j].count }
func (h RootHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *RootHeap) Push(x interface{}) {
	*h = append(*h, x.(*RootItem))
}
func (h *RootHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

func ask(queries []Query) []int {
	if len(queries) == 0 {
		return []int{}
	}
	fmt.Printf("? %d", len(queries))
	for _, q := range queries {
		fmt.Printf(" %d %d", q.u, q.v)
	}
	fmt.Println()

	ans := make([]int, len(queries))
	var s string
	for i := 0; i < len(queries); {
		fmt.Scan(&s)
		for _, ch := range s {
			if ch == '1' || ch == 'S' || ch == 's' || ch == 'Y' || ch == 'y' || ch == 'T' || ch == 't' {
				ans[i] = 1
				i++
			} else if ch == '0' || ch == 'D' || ch == 'd' || ch == 'N' || ch == 'n' || ch == 'F' || ch == 'f' {
				ans[i] = 0
				i++
			}
		}
	}
	return ans
}

func solve(n int) {
	parent = make([]int, n+1)
	for i := 1; i <= n; i++ {
		parent[i] = i
	}
	diff = make([]map[int]bool, n+1)
	for i := 1; i <= n; i++ {
		diff[i] = make(map[int]bool)
	}

	for batch := 0; batch < 7; batch++ {
		available := make(map[int][]int)
		for i := 1; i <= n; i++ {
			r := find(i)
			available[r] = append(available[r], i)
		}

		activeRoots := []int{}
		for r := range available {
			activeRoots = append(activeRoots, r)
		}

		allClique := true
		for i := 0; i < len(activeRoots); i++ {
			for j := i + 1; j < len(activeRoots); j++ {
				if !diff[activeRoots[i]][activeRoots[j]] {
					allClique = false
					break
				}
			}
			if !allClique {
				break
			}
		}
		if allClique {
			break
		}

		h := &RootHeap{}
		heap.Init(h)
		for r, coins := range available {
			heap.Push(h, &RootItem{root: r, count: len(coins)})
		}

		var queries []Query
		for h.Len() > 1 {
			limit := 4
			if h.Len() < 4 {
				limit = h.Len()
			}
			var items []*RootItem
			for i := 0; i < limit; i++ {
				items = append(items, heap.Pop(h).(*RootItem))
			}

			found := false
			for i := 0; i < limit; i++ {
				for j := i + 1; j < limit; j++ {
					r1 := items[i].root
					r2 := items[j].root
					if !diff[r1][r2] {
						c1 := available[r1][0]
						c2 := available[r2][0]
						available[r1] = available[r1][1:]
						available[r2] = available[r2][1:]
						items[i].count--
						items[j].count--
						queries = append(queries, Query{c1, c2})
						found = true
						break
					}
				}
				if found {
					break
				}
			}

			for _, item := range items {
				if item.count > 0 {
					heap.Push(h, item)
				}
			}

			if !found {
				break
			}
		}

		if len(queries) == 0 {
			break
		}

		ans := ask(queries)
		for i, q := range queries {
			if ans[i] == 1 {
				merge(q.u, q.v)
			} else {
				ru := find(q.u)
				rv := find(q.v)
				if ru != rv {
					diff[ru][rv] = true
					diff[rv][ru] = true
				}
			}
		}
		deduce(n)
	}

	piles := make(map[int][]int)
	for i := 1; i <= n; i++ {
		r := find(i)
		piles[r] = append(piles[r], i)
	}

	var pileList [][]int
	for _, p := range piles {
		pileList = append(pileList, p)
	}

	if len(pileList) > 3 {
		for i := 3; i < len(pileList); i++ {
			pileList[2] = append(pileList[2], pileList[i]...)
		}
		pileList = pileList[:3]
	}

	for len(pileList) < 3 {
		pileList = append(pileList, []int{})
	}

	fmt.Println("!")
	for i := 0; i < 3; i++ {
		for j, c := range pileList[i] {
			if j > 0 {
				fmt.Print(" ")
			}
			fmt.Print(c)
		}
		fmt.Println()
	}
}

func main() {
	var T int
	if _, err := fmt.Scan(&T); err != nil {
		return
	}
	for t := 0; t < T; t++ {
		var n int
		fmt.Scan(&n)
		solve(n)
	}
}
```