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()
}
}
}