← Home
package main

import (
	"fmt"
	"os"
)

var cache map[int]map[int]int

func ask(u, v int) int {
	if u > v {
		u, v = v, u
	}
	if u == v {
		return -1
	}
	if cache[u] != nil {
		if val, ok := cache[u][v]; ok {
			return val
		}
	} else {
		cache[u] = make(map[int]int)
	}

	fmt.Printf("? %d %d\n", u, v-1)
	var ans int
	fmt.Scan(&ans)
	if ans == -2 {
		os.Exit(0)
	}
	cache[u][v] = ans
	return ans
}

type Node struct {
	isLeaf   bool
	leafID   int
	bit      int
	children [2]*Node
}

func getLeaves(node *Node, out *[]int) {
	if node == nil {
		return
	}
	if node.isLeaf {
		*out = append(*out, node.leafID)
		return
	}
	getLeaves(node.children[0], out)
	getLeaves(node.children[1], out)
}

func getFurthestLeaf(node *Node, y int) int {
	var leaves []int
	getLeaves(node, &leaves)
	maxDist := -1
	bestLeaf := -1
	for _, l := range leaves {
		dist := l - y
		if dist < 0 {
			dist = -dist
		}
		if dist > maxDist {
			maxDist = dist
			bestLeaf = l
		}
	}
	return bestLeaf
}

func main() {
	var t int
	if _, err := fmt.Scan(&t); err != nil {
		return
	}

	for tc := 0; tc < t; tc++ {
		var n int
		fmt.Scan(&n)
		if n == -1 {
			os.Exit(0)
		}

		cache = make(map[int]map[int]int)

		var order []int
		l, r := 1, n+1
		for l <= r {
			order = append(order, l)
			l++
			if l <= r {
				order = append(order, r)
				r--
			}
		}

		root := &Node{isLeaf: true, leafID: order[0]}

		for i := 1; i < len(order); i++ {
			y := order[i]
			curr := root
			var parent *Node
			parentChildIdx := -1

			for {
				u := getFurthestLeaf(curr, y)
				m := ask(y, u)

				pathNode := curr
				pathParent := parent
				pathIdx := parentChildIdx

				for !pathNode.isLeaf && pathNode.bit > m {
					pathParent = pathNode
					var leftLeaves []int
					getLeaves(pathNode.children[0], &leftLeaves)
					found := false
					for _, lf := range leftLeaves {
						if lf == u {
							found = true
							break
						}
					}
					if found {
						pathNode = pathNode.children[0]
						pathIdx = 0
					} else {
						pathNode = pathNode.children[1]
						pathIdx = 1
					}
				}

				if !pathNode.isLeaf && pathNode.bit == m {
					var leftLeaves []int
					getLeaves(pathNode.children[0], &leftLeaves)
					found := false
					for _, lf := range leftLeaves {
						if lf == u {
							found = true
							break
						}
					}
					otherIdx := 1
					if found {
						otherIdx = 1
					} else {
						otherIdx = 0
					}
					curr = pathNode.children[otherIdx]
					parent = pathNode
					parentChildIdx = otherIdx
				} else {
					N := &Node{
						isLeaf:   false,
						bit:      m,
						children: [2]*Node{pathNode, {isLeaf: true, leafID: y}},
					}
					if pathParent != nil {
						pathParent.children[pathIdx] = N
					} else {
						root = N
					}
					break
				}
			}
		}

		ans := make([][]int, n+2)
		for i := range ans {
			ans[i] = make([]int, n+2)
			for j := range ans[i] {
				ans[i][j] = -1
			}
		}

		var dfs func(node *Node) []int
		dfs = func(node *Node) []int {
			if node == nil {
				return nil
			}
			if node.isLeaf {
				return []int{node.leafID}
			}
			left := dfs(node.children[0])
			right := dfs(node.children[1])
			for _, u := range left {
				for _, v := range right {
					ans[u][v] = node.bit
					ans[v][u] = node.bit
				}
			}
			res := make([]int, 0, len(left)+len(right))
			res = append(res, left...)
			res = append(res, right...)
			return res
		}
		dfs(root)

		fmt.Println("!")
		for i := 1; i <= n; i++ {
			for j := i; j <= n; j++ {
				if j > i {
					fmt.Printf(" ")
				}
				fmt.Printf("%d", ans[i][j+1])
			}
			fmt.Println()
		}
	}
}