from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans
'''
class SMT:
    def __init__(self,arr):
        self.n=len(arr)-1
        self.arr=[0]*(self.n<<2)
        self.lazy=[0]*(self.n<<2)
        def Build(l,r,rt):
            if l==r:
                self.arr[rt]=arr[l]
                return
            m=(l+r)>>1
            Build(l,m,rt<<1)
            Build(m+1,r,rt<<1|1)
            self.pushup(rt)
        Build(1,self.n,1)

    def pushup(self,rt):
        self.arr[rt]=self.arr[rt<<1]+self.arr[rt<<1|1]

    def pushdown(self,rt,ln,rn):#lr,rn表区间数字数
        if self.lazy[rt]:
            self.lazy[rt<<1]+=self.lazy[rt]
            self.lazy[rt<<1|1]=self.lazy[rt]
            self.arr[rt<<1]+=self.lazy[rt]*ln
            self.arr[rt<<1|1]+=self.lazy[rt]*rn
            self.lazy[rt]=0

    def update(self,L,R,c,l=1,r=None,rt=1):#L,R表示操作区间
        if r==None: r=self.n
        if L<=l and r<=R:
            self.arr[rt]+=c*(r-l+1)
            self.lazy[rt]+=c
            return
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        if L<=m: self.update(L,R,c,l,m,rt<<1)
        if R>m: self.update(L,R,c,m+1,r,rt<<1|1)
        self.pushup(rt)

    def query(self,L,R,l=1,r=None,rt=1):
        if r==None: r=self.n
        #print(L,R,l,r,rt)
        if L<=l and R>=r:
            return self.arr[rt]
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        ans=0
        if L<=m: ans+=self.query(L,R,l,m,rt<<1)
        if R>m: ans+=self.query(L,R,m+1,r,rt<<1|1)
        return ans
'''
class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [[ch,len(list(g))] for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

def query(arr):
    print('?',len(arr),*arr)
    sys.stdout.flush()
    x,d=RL()
    if d==-1:
        exit()
    return x,d

t=N()
for i in range(t):
    n=N()
    g=[[] for i in range(n+1)]
    for i in range(n-1):
        u,v=RL()
        g[u].append(v)
        g[v].append(u)
    rt,d=query(list(range(1,n+1)))
    bfs=[[rt]]
    q=deque([rt])
    vis=[0]*(1+n)
    vis[rt]=1
    while q:
        tmp=[]
        for i in range(len(q)):
            u=q.popleft()
            for v in g[u]:
                if not vis[v]:
                    q.append(v)
                    tmp.append(v)
                    vis[v]=1
        if tmp:
            bfs.append(tmp)
    #print(bfs)
    l=(d+1)//2
    r=len(bfs)-1
    #print('l',l,r)
    while l<=r:
        mid=(l+r)//2
        x,nd=query(bfs[mid])
        if nd>d:
            r=mid-1
        else:
            l=mid+1
            a1,d1=x,nd
    #print(l,d1,a1)
    a2,d2=query(bfs[d-d1])
    print('!',a1,a2)
    sys.stdout.flush()
    a=input()
    if a=='Incorrect':
        exit()

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans
'''
class SMT:
    def __init__(self,arr):
        self.n=len(arr)-1
        self.arr=[0]*(self.n<<2)
        self.lazy=[0]*(self.n<<2)
        def Build(l,r,rt):
            if l==r:
                self.arr[rt]=arr[l]
                return
            m=(l+r)>>1
            Build(l,m,rt<<1)
            Build(m+1,r,rt<<1|1)
            self.pushup(rt)
        Build(1,self.n,1)

    def pushup(self,rt):
        self.arr[rt]=self.arr[rt<<1]+self.arr[rt<<1|1]

    def pushdown(self,rt,ln,rn):#lr,rn表区间数字数
        if self.lazy[rt]:
            self.lazy[rt<<1]+=self.lazy[rt]
            self.lazy[rt<<1|1]=self.lazy[rt]
            self.arr[rt<<1]+=self.lazy[rt]*ln
            self.arr[rt<<1|1]+=self.lazy[rt]*rn
            self.lazy[rt]=0

    def update(self,L,R,c,l=1,r=None,rt=1):#L,R表示操作区间
        if r==None: r=self.n
        if L<=l and r<=R:
            self.arr[rt]+=c*(r-l+1)
            self.lazy[rt]+=c
            return
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        if L<=m: self.update(L,R,c,l,m,rt<<1)
        if R>m: self.update(L,R,c,m+1,r,rt<<1|1)
        self.pushup(rt)

    def query(self,L,R,l=1,r=None,rt=1):
        if r==None: r=self.n
        #print(L,R,l,r,rt)
        if L<=l and R>=r:
            return self.arr[rt]
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        ans=0
        if L<=m: ans+=self.query(L,R,l,m,rt<<1)
        if R>m: ans+=self.query(L,R,m+1,r,rt<<1|1)
        return ans
'''
class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [[ch,len(list(g))] for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

def query(arr):
    print('?',len(arr),*arr)
    sys.stdout.flush()
    x,d=RL()
    if d==-1:
        exit()
    return x,d

t=N()
for i in range(t):
    n=N()
    g=[[] for i in range(n+1)]
    for i in range(n-1):
        u,v=RL()
        g[u].append(v)
        g[v].append(u)
    rt,d=query(list(range(1,n+1)))
    bfs=[[rt]]
    q=deque([rt])
    vis=[0]*(1+n)
    vis[rt]=1
    while q:
        tmp=[]
        for i in range(len(q)):
            u=q.popleft()
            for v in g[u]:
                if not vis[v]:
                    q.append(v)
                    tmp.append(v)
                    vis[v]=1
        if tmp:
            bfs.append(tmp)
    #print(bfs)
    l=(d+1)//2
    r=min(d,len(bfs)-1)
    #print('l',l,r)
    while l<=r:
        mid=(l+r)//2
        x,nd=query(bfs[mid])
        if nd>d:
            r=mid-1
        else:
            a1,d1=x,l
            l=mid+1
    #print(l,d1,a1)
    a2,d2=query(bfs[d-d1])
    print('!',a1,a2)
    sys.stdout.flush()
    a=input()
    if a=='Incorrect':
        exit()

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans
'''
class SMT:
    def __init__(self,arr):
        self.n=len(arr)-1
        self.arr=[0]*(self.n<<2)
        self.lazy=[0]*(self.n<<2)
        def Build(l,r,rt):
            if l==r:
                self.arr[rt]=arr[l]
                return
            m=(l+r)>>1
            Build(l,m,rt<<1)
            Build(m+1,r,rt<<1|1)
            self.pushup(rt)
        Build(1,self.n,1)

    def pushup(self,rt):
        self.arr[rt]=self.arr[rt<<1]+self.arr[rt<<1|1]

    def pushdown(self,rt,ln,rn):#lr,rn表区间数字数
        if self.lazy[rt]:
            self.lazy[rt<<1]+=self.lazy[rt]
            self.lazy[rt<<1|1]=self.lazy[rt]
            self.arr[rt<<1]+=self.lazy[rt]*ln
            self.arr[rt<<1|1]+=self.lazy[rt]*rn
            self.lazy[rt]=0

    def update(self,L,R,c,l=1,r=None,rt=1):#L,R表示操作区间
        if r==None: r=self.n
        if L<=l and r<=R:
            self.arr[rt]+=c*(r-l+1)
            self.lazy[rt]+=c
            return
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        if L<=m: self.update(L,R,c,l,m,rt<<1)
        if R>m: self.update(L,R,c,m+1,r,rt<<1|1)
        self.pushup(rt)

    def query(self,L,R,l=1,r=None,rt=1):
        if r==None: r=self.n
        #print(L,R,l,r,rt)
        if L<=l and R>=r:
            return self.arr[rt]
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        ans=0
        if L<=m: ans+=self.query(L,R,l,m,rt<<1)
        if R>m: ans+=self.query(L,R,m+1,r,rt<<1|1)
        return ans
'''
class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [[ch,len(list(g))] for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

def query(arr):
    print('?',len(arr),*arr)
    sys.stdout.flush()
    x,d=RL()
    #if d==-1:
        #exit()
    return x,d

t=N()
for i in range(t):
    n=N()
    g=[[] for i in range(n+1)]
    for i in range(n-1):
        u,v=RL()
        g[u].append(v)
        g[v].append(u)
    rt,d=query(list(range(1,n+1)))
    bfs=[[rt]]
    q=deque([rt])
    vis=[0]*(1+n)
    vis[rt]=1
    par=[0]*(1+n)
    while q:
        tmp=[]
        for i in range(len(q)):
            u=q.popleft()
            for v in g[u]:
                if not vis[v]:
                    par[v]=u
                    q.append(v)
                    tmp.append(v)
                    vis[v]=1
        if tmp:
            bfs.append(tmp)
    #print(bfs)
    l=(d+1)//2
    r=min(d,len(bfs)-1)
    #print('l',l,r)
    while l<=r:
        mid=(l+r)//2
        x,nd=query(bfs[mid])
        if nd>d:
            r=mid-1
        else:
            a1,d1=x,l
            l=mid+1
    if d==d1:
        a2=rt
    else:
        d2=d-d1
        a2=a1
        #while a2 not in bfs[d2]:
            #a2=par[a2]
        while d1>d2:
            d1-=1
            a2=par[a2]
        if a2 not in bfs[d2]:
            print('!',0,0)
            exit()
        bfs[d2].remove(a2)
        a2,d2=query(bfs[d2])
    print('!',a1,a2)
    sys.stdout.flush()
    a=input()
    if a=='Correct':
        continue
    else:
        exit()

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans
'''
class SMT:
    def __init__(self,arr):
        self.n=len(arr)-1
        self.arr=[0]*(self.n<<2)
        self.lazy=[0]*(self.n<<2)
        def Build(l,r,rt):
            if l==r:
                self.arr[rt]=arr[l]
                return
            m=(l+r)>>1
            Build(l,m,rt<<1)
            Build(m+1,r,rt<<1|1)
            self.pushup(rt)
        Build(1,self.n,1)

    def pushup(self,rt):
        self.arr[rt]=self.arr[rt<<1]+self.arr[rt<<1|1]

    def pushdown(self,rt,ln,rn):#lr,rn表区间数字数
        if self.lazy[rt]:
            self.lazy[rt<<1]+=self.lazy[rt]
            self.lazy[rt<<1|1]=self.lazy[rt]
            self.arr[rt<<1]+=self.lazy[rt]*ln
            self.arr[rt<<1|1]+=self.lazy[rt]*rn
            self.lazy[rt]=0

    def update(self,L,R,c,l=1,r=None,rt=1):#L,R表示操作区间
        if r==None: r=self.n
        if L<=l and r<=R:
            self.arr[rt]+=c*(r-l+1)
            self.lazy[rt]+=c
            return
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        if L<=m: self.update(L,R,c,l,m,rt<<1)
        if R>m: self.update(L,R,c,m+1,r,rt<<1|1)
        self.pushup(rt)

    def query(self,L,R,l=1,r=None,rt=1):
        if r==None: r=self.n
        #print(L,R,l,r,rt)
        if L<=l and R>=r:
            return self.arr[rt]
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        ans=0
        if L<=m: ans+=self.query(L,R,l,m,rt<<1)
        if R>m: ans+=self.query(L,R,m+1,r,rt<<1|1)
        return ans
'''
class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [[ch,len(list(g))] for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

def query(arr):
    print('?',len(arr),*arr)
    sys.stdout.flush()
    x,d=RL()
    #if d==-1:
        #exit()
    return x,d

t=N()
for i in range(t):
    n=N()
    g=[[] for i in range(n+1)]
    for i in range(n-1):
        u,v=RL()
        g[u].append(v)
        g[v].append(u)
    rt,d=query(list(range(1,n+1)))
    bfs=[[rt]]
    q=deque([rt])
    vis=[0]*(1+n)
    vis[rt]=1
    par=[0]*(1+n)
    while q:
        tmp=[]
        for i in range(len(q)):
            u=q.popleft()
            for v in g[u]:
                if not vis[v]:
                    par[v]=u
                    q.append(v)
                    tmp.append(v)
                    vis[v]=1
        if tmp:
            bfs.append(tmp)
    #print(bfs)
    l=(d+1)//2
    r=min(d,len(bfs)-1)
    tmp=''
    f=0
    while l<=r:
        mid=(l+r)//2
        x,nd=query(bfs[mid])
        if nd>d:
            r=mid-1
        else:
            a1,d1=x,mid
            l=mid+1
    if d==d1:
        a2=rt
    else:
        d2=d-d1
        a2=a1
        #while a2 not in bfs[d2]:
            #a2=par[a2]
        c=d1-d2
        tmp+=str(d1)
        while c>0:
            c-=1
            a2=par[a2]
        #if a2 not in bfs[d2]:
            #print('!',f,l)
            #exit()
        bfs[d2].remove(a2)
        a2,d2=query(bfs[d2])
    print('!',a1,a2)
    sys.stdout.flush()
    a=input()
    if a=='Correct':
        continue
    else:
        exit()

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans
'''
class SMT:
    def __init__(self,arr):
        self.n=len(arr)-1
        self.arr=[0]*(self.n<<2)
        self.lazy=[0]*(self.n<<2)
        def Build(l,r,rt):
            if l==r:
                self.arr[rt]=arr[l]
                return
            m=(l+r)>>1
            Build(l,m,rt<<1)
            Build(m+1,r,rt<<1|1)
            self.pushup(rt)
        Build(1,self.n,1)

    def pushup(self,rt):
        self.arr[rt]=self.arr[rt<<1]+self.arr[rt<<1|1]

    def pushdown(self,rt,ln,rn):#lr,rn表区间数字数
        if self.lazy[rt]:
            self.lazy[rt<<1]+=self.lazy[rt]
            self.lazy[rt<<1|1]=self.lazy[rt]
            self.arr[rt<<1]+=self.lazy[rt]*ln
            self.arr[rt<<1|1]+=self.lazy[rt]*rn
            self.lazy[rt]=0

    def update(self,L,R,c,l=1,r=None,rt=1):#L,R表示操作区间
        if r==None: r=self.n
        if L<=l and r<=R:
            self.arr[rt]+=c*(r-l+1)
            self.lazy[rt]+=c
            return
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        if L<=m: self.update(L,R,c,l,m,rt<<1)
        if R>m: self.update(L,R,c,m+1,r,rt<<1|1)
        self.pushup(rt)

    def query(self,L,R,l=1,r=None,rt=1):
        if r==None: r=self.n
        #print(L,R,l,r,rt)
        if L<=l and R>=r:
            return self.arr[rt]
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        ans=0
        if L<=m: ans+=self.query(L,R,l,m,rt<<1)
        if R>m: ans+=self.query(L,R,m+1,r,rt<<1|1)
        return ans
'''
class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [[ch,len(list(g))] for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

def query(arr):
    print('?',len(arr),*arr)
    sys.stdout.flush()
    x,d=RL()
    #if d==-1:
        #exit()
    return x,d

t=N()
for i in range(t):
    n=N()
    g=[[] for i in range(n+1)]
    for i in range(n-1):
        u,v=RL()
        g[u].append(v)
        g[v].append(u)
    rt,d=query(list(range(1,n+1)))
    bfs=[[rt]]
    q=deque([rt])
    vis=[0]*(1+n)
    vis[rt]=1
    par=[0]*(1+n)
    while q:
        tmp=[]
        for i in range(len(q)):
            u=q.popleft()
            for v in g[u]:
                if not vis[v]:
                    par[v]=u
                    q.append(v)
                    tmp.append(v)
                    vis[v]=1
        if tmp:
            bfs.append(tmp)
    #print(bfs)
    l=(d+1)//2
    r=min(d,len(bfs)-1)
    #print('l',l,r)
    cnt=0
    f=1
    while l<=r:
        mid=(l+r)//2
        x,nd=query(bfs[mid])
        cnt+=1
        if nd>d:
            r=mid-1
        else:
            a1,d1=x,l
            l=mid+1
        f=0
    if d==d1:
        a2=rt
    else:
        d2=d-d1
        a2=a1
        #while a2 not in bfs[d2]:
            #a2=par[a2]
        c=d1-d2
        while c>0:
            c-=1
            a2=par[a2]
        if a2 not in bfs[d2]:
            print('!',cnt,f)
            exit()
        bfs[d2].remove(a2)
        a2,d2=query(bfs[d2])
    print('!',a1,a2)
    sys.stdout.flush()
    a=input()
    if a=='Correct':
        continue
    else:
        exit()

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans
'''
class SMT:
    def __init__(self,arr):
        self.n=len(arr)-1
        self.arr=[0]*(self.n<<2)
        self.lazy=[0]*(self.n<<2)
        def Build(l,r,rt):
            if l==r:
                self.arr[rt]=arr[l]
                return
            m=(l+r)>>1
            Build(l,m,rt<<1)
            Build(m+1,r,rt<<1|1)
            self.pushup(rt)
        Build(1,self.n,1)

    def pushup(self,rt):
        self.arr[rt]=self.arr[rt<<1]+self.arr[rt<<1|1]

    def pushdown(self,rt,ln,rn):#lr,rn表区间数字数
        if self.lazy[rt]:
            self.lazy[rt<<1]+=self.lazy[rt]
            self.lazy[rt<<1|1]=self.lazy[rt]
            self.arr[rt<<1]+=self.lazy[rt]*ln
            self.arr[rt<<1|1]+=self.lazy[rt]*rn
            self.lazy[rt]=0

    def update(self,L,R,c,l=1,r=None,rt=1):#L,R表示操作区间
        if r==None: r=self.n
        if L<=l and r<=R:
            self.arr[rt]+=c*(r-l+1)
            self.lazy[rt]+=c
            return
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        if L<=m: self.update(L,R,c,l,m,rt<<1)
        if R>m: self.update(L,R,c,m+1,r,rt<<1|1)
        self.pushup(rt)

    def query(self,L,R,l=1,r=None,rt=1):
        if r==None: r=self.n
        #print(L,R,l,r,rt)
        if L<=l and R>=r:
            return self.arr[rt]
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        ans=0
        if L<=m: ans+=self.query(L,R,l,m,rt<<1)
        if R>m: ans+=self.query(L,R,m+1,r,rt<<1|1)
        return ans
'''
class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [[ch,len(list(g))] for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

def query(arr):
    print('?',len(arr),*arr)
    sys.stdout.flush()
    x,d=RL()
    #if d==-1:
        #exit()
    return x,d

t=N()
for i in range(t):
    n=N()
    g=[[] for i in range(n+1)]
    for i in range(n-1):
        u,v=RL()
        g[u].append(v)
        g[v].append(u)
    rt,d=query(list(range(1,n+1)))
    bfs=[[rt]]
    q=deque([rt])
    vis=[0]*(1+n)
    vis[rt]=1
    par=[0]*(1+n)
    while q:
        tmp=[]
        for i in range(len(q)):
            u=q.popleft()
            for v in g[u]:
                if not vis[v]:
                    par[v]=u
                    q.append(v)
                    tmp.append(v)
                    vis[v]=1
        if tmp:
            bfs.append(tmp)
    #print(bfs)
    l=(d+1)//2
    r=min(d,len(bfs)-1)
    while l<=r:
        mid=(l+r)//2
        x,nd=query(bfs[mid])
        if nd>d:
            r=mid-1
        else:
            a1,d1=x,l
            l=mid+1
        #f=0
    if d==d1:
        a2=rt
    else:
        d2=d-d1
        a2=a1
        #while a2 not in bfs[d2]:
            #a2=par[a2]
        c=d1-d2
        while c>0:
            c-=1
            a2=par[a2]
        if a2 not in bfs[d2]:
            print('!',a1,bfs[d2])
            exit()
        bfs[d2].remove(a2)
        a2,d2=query(bfs[d2])
    print('!',a1,a2)
    sys.stdout.flush()
    a=input()
    if a=='Correct':
        continue
    else:
        exit()

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans
'''
class SMT:
    def __init__(self,arr):
        self.n=len(arr)-1
        self.arr=[0]*(self.n<<2)
        self.lazy=[0]*(self.n<<2)
        def Build(l,r,rt):
            if l==r:
                self.arr[rt]=arr[l]
                return
            m=(l+r)>>1
            Build(l,m,rt<<1)
            Build(m+1,r,rt<<1|1)
            self.pushup(rt)
        Build(1,self.n,1)

    def pushup(self,rt):
        self.arr[rt]=self.arr[rt<<1]+self.arr[rt<<1|1]

    def pushdown(self,rt,ln,rn):#lr,rn表区间数字数
        if self.lazy[rt]:
            self.lazy[rt<<1]+=self.lazy[rt]
            self.lazy[rt<<1|1]=self.lazy[rt]
            self.arr[rt<<1]+=self.lazy[rt]*ln
            self.arr[rt<<1|1]+=self.lazy[rt]*rn
            self.lazy[rt]=0

    def update(self,L,R,c,l=1,r=None,rt=1):#L,R表示操作区间
        if r==None: r=self.n
        if L<=l and r<=R:
            self.arr[rt]+=c*(r-l+1)
            self.lazy[rt]+=c
            return
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        if L<=m: self.update(L,R,c,l,m,rt<<1)
        if R>m: self.update(L,R,c,m+1,r,rt<<1|1)
        self.pushup(rt)

    def query(self,L,R,l=1,r=None,rt=1):
        if r==None: r=self.n
        #print(L,R,l,r,rt)
        if L<=l and R>=r:
            return self.arr[rt]
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        ans=0
        if L<=m: ans+=self.query(L,R,l,m,rt<<1)
        if R>m: ans+=self.query(L,R,m+1,r,rt<<1|1)
        return ans
'''
class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [[ch,len(list(g))] for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

def query(arr):
    print('?',len(arr),*arr)
    sys.stdout.flush()
    x,d=RL()
    #if d==-1:
        #exit()
    return x,d

t=N()
for i in range(t):
    n=N()
    g=[[] for i in range(n+1)]
    for i in range(n-1):
        u,v=RL()
        g[u].append(v)
        g[v].append(u)
    rt,d=query(list(range(1,n+1)))
    bfs=[[rt]]
    q=deque([rt])
    vis=[0]*(1+n)
    vis[rt]=1
    par=[0]*(1+n)
    while q:
        tmp=[]
        for i in range(len(q)):
            u=q.popleft()
            for v in g[u]:
                if not vis[v]:
                    par[v]=u
                    q.append(v)
                    tmp.append(v)
                    vis[v]=1
                    if v==32:
                        debug=len(bfs)
        if tmp:
            bfs.append(tmp)
    #print(bfs)
    l=(d+1)//2
    r=min(d,len(bfs)-1)
    while l<=r:
        mid=(l+r)//2
        x,nd=query(bfs[mid])
        if nd>d:
            r=mid-1
        else:
            a1,d1=x,l
            l=mid+1
        #f=0
    if d==d1:
        a2=rt
    else:
        d2=d-d1
        a2=a1
        #while a2 not in bfs[d2]:
            #a2=par[a2]
        c=d1-d2
        while c>0:
            c-=1
            a2=par[a2]
        if a2 not in bfs[d2]:
            tmp=''
            for x in bfs[d2]:
                tmp+=str(x)
                tmp+='000'
            print('!',a1,debug)
            exit()
        bfs[d2].remove(a2)
        a2,d2=query(bfs[d2])
    print('!',a1,a2)
    sys.stdout.flush()
    a=input()
    if a=='Correct':
        continue
    else:
        exit()

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans
'''
class SMT:
    def __init__(self,arr):
        self.n=len(arr)-1
        self.arr=[0]*(self.n<<2)
        self.lazy=[0]*(self.n<<2)
        def Build(l,r,rt):
            if l==r:
                self.arr[rt]=arr[l]
                return
            m=(l+r)>>1
            Build(l,m,rt<<1)
            Build(m+1,r,rt<<1|1)
            self.pushup(rt)
        Build(1,self.n,1)

    def pushup(self,rt):
        self.arr[rt]=self.arr[rt<<1]+self.arr[rt<<1|1]

    def pushdown(self,rt,ln,rn):#lr,rn表区间数字数
        if self.lazy[rt]:
            self.lazy[rt<<1]+=self.lazy[rt]
            self.lazy[rt<<1|1]=self.lazy[rt]
            self.arr[rt<<1]+=self.lazy[rt]*ln
            self.arr[rt<<1|1]+=self.lazy[rt]*rn
            self.lazy[rt]=0

    def update(self,L,R,c,l=1,r=None,rt=1):#L,R表示操作区间
        if r==None: r=self.n
        if L<=l and r<=R:
            self.arr[rt]+=c*(r-l+1)
            self.lazy[rt]+=c
            return
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        if L<=m: self.update(L,R,c,l,m,rt<<1)
        if R>m: self.update(L,R,c,m+1,r,rt<<1|1)
        self.pushup(rt)

    def query(self,L,R,l=1,r=None,rt=1):
        if r==None: r=self.n
        #print(L,R,l,r,rt)
        if L<=l and R>=r:
            return self.arr[rt]
        m=(l+r)>>1
        self.pushdown(rt,m-l+1,r-m)
        ans=0
        if L<=m: ans+=self.query(L,R,l,m,rt<<1)
        if R>m: ans+=self.query(L,R,m+1,r,rt<<1|1)
        return ans
'''
class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [[ch,len(list(g))] for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

def query(arr):
    print('?',len(arr),*arr)
    sys.stdout.flush()
    x,d=RL()
    if d==-1:
        exit()
    return x,d

t=N()
for i in range(t):
    n=N()
    g=[[] for i in range(n+1)]
    for i in range(n-1):
        u,v=RL()
        g[u].append(v)
        g[v].append(u)
    rt,d=query(list(range(1,n+1)))
    bfs=[[rt]]
    q=deque([rt])
    vis=[0]*(1+n)
    vis[rt]=1
    par=[0]*(1+n)
    while q:
        tmp=[]
        for i in range(len(q)):
            u=q.popleft()
            for v in g[u]:
                if not vis[v]:
                    par[v]=u
                    q.append(v)
                    tmp.append(v)
                    vis[v]=1
        if tmp:
            bfs.append(tmp)
    #print(bfs)
    l=(d+1)//2
    r=min(d,len(bfs)-1)
    #print('l',l,r)
    while l<=r:
        mid=(l+r)//2
        x,nd=query(bfs[mid])
        if nd>d:
            r=mid-1
        else:
            a1,d1=x,l
            l=mid+1
    if d==d1:
        a2=rt
    else:
        d2=d-d1
        a2=a1
        while d1>d2:
            d1-=1
            a2=par[a2]
        bfs[d2].remove(a2)
        a2,d2=query(bfs[d2])
    print('!',a1,a2)
    sys.stdout.flush()
    a=input()
    if a=='Incorrect':
        exit()

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''

'''
sys.setrecursionlimit(200000)
import threading
threading.stack_size(10**8)
t=threading.Thread(target=main)
t.start()
t.join()
'''


from sys import exit
from collections import deque
from copy import deepcopy

def readTree(n):
    adj = [set() for _ in range(n)]
    for _ in range(n-1):
        u,v = map(int, input().split())
        adj[u-1].add(v-1)
        adj[v-1].add(u-1)
    return adj

def nodes_at_depth(n, root, adj, d):
    q = deque()
    q.append(root)
    depth = [-1] * n
    depth[root] = 0
    res = []
    parent = [-1] * n
    while q:
        v = q.popleft()
        if depth[v] == d:
            res.append(v)
            continue
        for a in adj[v]:
            if depth[a] == -1:
                parent[a] = v
                depth[a] = depth[v] + 1
                q.append(a)
    return res, parent

def query(vv):
    print('?', len(vv), ' '.join(map(lambda v: str(v+1), vv)), flush=True)
    v, d = map(int, input().split())
    if v == -1:
        exit()
    return v-1, d

def main():
    def solve():

        n = int(input())
        adj = readTree(n)
        v, w = solvebody(adj, n, query)
        print('!', v+1, w+1, flush=True)
        if input() != "Correct":
            exit()

    t = int(input())
    for _ in range(t):
        solve()

def solvebody(adj, n, query):
    # Find a node on the path
    v, d = query(range(n))
    depth = d
    adjm = deepcopy(adj)
    while depth > 1:
        depth = (depth +1) // 2
        vv, parent = nodes_at_depth(n, v, adjm, depth)
        if len(vv) == 1:
            v = vv[0]
            adjm[v].remove(parent[v])
            continue
        x, d1 = query(vv)
        if d1 == d:
            v = x
            adjm[v].remove(parent[v])
    vv, _ = nodes_at_depth(n, v, adjm, 1)
    x, d1 = query(vv)
    if d1 == d:
        v = x
    vv, _ = nodes_at_depth(n, v, adj, d)
    w, _ = query(vv)
    return v, w

if __name__ == "__main__":
    main()


from sys import exit
from collections import deque
from copy import deepcopy

def readTree(n):
    adj = [set() for _ in range(n)]
    for _ in range(n-1):
        u,v = map(int, input().split())
        adj[u-1].add(v-1)
        adj[v-1].add(u-1)
    return adj

def nodes_at_depth(n, root, adj, d):
    q = deque()
    q.append(root)
    depth = [-1] * n
    depth[root] = 0
    res = []
    parent = [-1] * n
    while q:
        v = q.popleft()
        if depth[v] == d:
            res.append(v)
            continue
        for a in adj[v]:
            if depth[a] == -1:
                parent[a] = v
                depth[a] = depth[v] + 1
                q.append(a)
    return res, parent

def query(vv):
    print('?', len(vv), ' '.join(map(lambda v: str(v+1), vv)), flush=True)
    v, d = map(int, input().split())
    if v == -1:
        exit()
    return v-1, d

def main():
    def solve():

        n = int(input())
        adj = readTree(n)
        # Find a node on the path
        v, d = query(range(n))
        depth = d
        adjm = deepcopy(adj)
        while depth > 1:
            depth = depth//2
            vv, parent = nodes_at_depth(n, v, adjm, depth)
            x, d1 = query(vv)
            if d1 == d:
                v = x
                adjm[v].remove(parent[v])
        vv, _ = nodes_at_depth(n, v, adj, d)
        w, _ = query(vv)
        print('!', v+1, w+1, flush=True)
        if input() != "Correct":
            exit()

    t = int(input())
    for _ in range(t):
        solve()

if __name__ == "__main__":
    main()


from sys import exit
from collections import deque
from copy import deepcopy

def readTree(n):
    adj = [set() for _ in range(n)]
    for _ in range(n-1):
        u,v = map(int, input().split())
        adj[u-1].add(v-1)
        adj[v-1].add(u-1)
    return adj

def nodes_at_depth(n, root, adj, d):
    q = deque()
    q.append(root)
    depth = [-1] * n
    depth[root] = 0
    res = []
    parent = [-1] * n
    while q:
        v = q.popleft()
        if depth[v] == d:
            res.append(v)
            continue
        for a in adj[v]:
            if depth[a] == -1:
                parent[a] = v
                depth[a] = depth[v] + 1
                q.append(a)
    return res, parent

def query(vv):
    print('?', len(vv), ' '.join(map(lambda v: str(v+1), vv)), flush=True)
    v, d = map(int, input().split())
    if v == -1:
        exit()
    return v-1, d

def main():
    def solve():

        n = int(input())
        adj = readTree(n)
        v, w = solvebody(adj, n, query)
        print('!', v+1, w+1, flush=True)
        if input() != "Correct":
            exit()

    t = int(input())
    for _ in range(t):
        solve()

def solvebody(adj, n, query):
    # Find a node on the path
    v, d = query(range(n))
    depth = d
    adjm = deepcopy(adj)
    while depth > 1:
        depth = (depth +1) // 2
        vv, parent = nodes_at_depth(n, v, adjm, depth)
        if not vv:
            continue
        x, d1 = query(vv)
        if d1 == d:
            v = x
            adjm[v].remove(parent[v])
    vv, _ = nodes_at_depth(n, v, adjm, 1)
    if vv:
        x, d1 = query(vv)
        if d1 == d:
            v = x
    vv, _ = nodes_at_depth(n, v, adj, d)
    w, _ = query(vv)
    return v, w

if __name__ == "__main__":
    main()


from sys import exit
from collections import deque
from copy import deepcopy

def readTree(n):
    adj = [set() for _ in range(n)]
    for _ in range(n-1):
        u,v = map(int, input().split())
        adj[u-1].add(v-1)
        adj[v-1].add(u-1)
    return adj

def nodes_at_depth(n, root, adj, d):
    q = deque()
    q.append(root)
    depth = [-1] * n
    depth[root] = 0
    res = []
    parent = [-1] * n
    while q:
        v = q.popleft()
        if depth[v] == d:
            res.append(v)
            continue
        for a in adj[v]:
            if depth[a] == -1:
                parent[a] = v
                depth[a] = depth[v] + 1
                q.append(a)
    return res, parent

def query(vv):
    print('?', len(vv), ' '.join(map(lambda v: str(v+1), vv)), flush=True)
    v, d = map(int, input().split())
    if v == -1:
        exit()
    return v-1, d

def main():
    def solve():

        n = int(input())
        adj = readTree(n)
        v, w = solvebody(adj, n, query)
        print('!', v+1, w+1, flush=True)
        if input() != "Correct":
            exit()

    t = int(input())
    for _ in range(t):
        solve()

def solvebody(adj, n, query):
    # Find a node on the path
    v, d = query(range(n))
    depth = d
    adjm = deepcopy(adj)
    while depth > 1:
        depth = (depth +1) // 2
        vv, parent = nodes_at_depth(n, v, adjm, depth)
        if not vv:
            continue
        x, d1 = query(vv)
        if d1 == d:
            v = x
            adjm[v].remove(parent[v])
    vv, _ = nodes_at_depth(n, v, adjm, 1)
    x, d1 = query(vv)
    if d1 == d:
        v = x
    vv, _ = nodes_at_depth(n, v, adj, d)
    w, _ = query(vv)
    return v, w

if __name__ == "__main__":
    main()


from sys import exit
from collections import deque
from copy import deepcopy

def readTree(n):
    adj = [set() for _ in range(n)]
    for _ in range(n-1):
        u,v = map(int, input().split())
        adj[u-1].add(v-1)
        adj[v-1].add(u-1)
    return adj

def nodes_at_depth(n, root, adj, d):
    q = deque()
    q.append(root)
    depth = [-1] * n
    depth[root] = 0
    res = []
    parent = [-1] * n
    while q:
        v = q.popleft()
        if depth[v] == d:
            res.append(v)
            continue
        for a in adj[v]:
            if depth[a] == -1:
                parent[a] = v
                depth[a] = depth[v] + 1
                q.append(a)
    return res, parent

def query(vv):
    print('?', len(vv), ' '.join(map(lambda v: str(v+1), vv)), flush=True)
    v, d = map(int, input().split())
    if v == -1:
        exit()
    return v-1, d

def main():
    def solve():

        n = int(input())
        adj = readTree(n)
        v, w = solvebody(adj, n, query)
        print('!', v+1, w+1, flush=True)
        if input() != "Correct":
            exit()

    t = int(input())
    for _ in range(t):
        solve()

def solvebody(adj, n, query):
    # Find a node on the path
    v, d = query(range(n))
    depth = d
    adjm = deepcopy(adj)
    while depth > 1:
        depth = depth// 2
        vv, parent = nodes_at_depth(n, v, adjm, depth)
        if len(vv) == 1:
            v = vv[0]
            adjm[v].remove(parent[v])
            continue
        x, d1 = query(vv)
        if d1 == d:
            v = x
            adjm[v].remove(parent[v])
    vv, _ = nodes_at_depth(n, v, adjm, 1)
    x, d1 = query(vv)
    if d1 == d:
        v = x
    vv, _ = nodes_at_depth(n, v, adj, d)
    w, _ = query(vv)
    return v, w

if __name__ == "__main__":
    main()


import java.math.BigInteger

fun readInt(): Int {
    return readLine()!!.toInt()
}

fun readLong(): Long {
    return readLine()!!.toLong()
}

fun readBigInt(): BigInteger {
    return readLine()!!.toBigInteger()
}

fun readInts(): List<Int> {
    return readLine()!!.split(" ").map(String::toInt)
}

fun readLongs(): List<Long> {
    return readLine()!!.split(" ").map(String::toLong)
}

fun readBigInts(): List<BigInteger> {
    return readLine()!!.split(" ").map(String::toBigInteger)
}

fun query(nodes: MutableList<Int>): List<Int> {
    println("? ${nodes.size} ${nodes.joinToString(" ")}")
    return readInts()
}

fun output(u: Int, v: Int) {
    println("! $u $v")
    readLine()!!
}

class Solution {
    private var maxDepth = 0
    private val depth = mutableListOf<Int>()
    private val parent = mutableListOf<Int>()
    private val adj = mutableListOf<MutableList<Int>>()

    private fun dfs(u: Int, p: Int) {
        parent[u] = p
        depth[u] = if (p == 0) 0 else depth[p] + 1
        maxDepth = maxDepth.coerceAtLeast(depth[u])
        for (v in adj[u]) {
            if (v != p)
                dfs(v, u)
        }
    }

    fun solve() {
        val n = readInt()
        for (i in 0 until n + 1) {
            adj.add(mutableListOf())
            depth.add(0)
            parent.add(0)
        }
        for (i in 0 until n - 1) {
            val (u, v) = readInts()
            adj[u].add(v)
            adj[v].add(u)
        }
        val (root, minDist) = query((1 until n + 1).toMutableList());
        dfs(root, 0)
        val nodes = Array(maxDepth + 1) { mutableListOf<Int>()}
        for (i in 1 until n + 1)
            nodes[depth[i]].add(i)
        var lo = (minDist + 1) / 2
        var hi = maxDepth
        while (lo <= hi) {
            val mid = (lo + hi) shr 1
            val (_, dist) = query(nodes[mid]);
            if (dist > minDist)
                hi = mid - 1
            else
                lo = mid + 1
        }
        val (u, _) = query(nodes[hi])
        var current = u
        while (current != root) {
            nodes[depth[current]] = nodes[depth[current]].filter { it != current }.toMutableList()
            current = parent[current]
        }
        val (v, _) = query(nodes[minDist - hi])
        output(u, v)
    }
}

fun main() {
    val t = readInt()
    for (i in 0 until t) {
        val solution = Solution()
        solution.solve()
    }
}


import java.math.BigInteger

fun readInt(): Int {
    return readLine()!!.toInt()
}

fun readLong(): Long {
    return readLine()!!.toLong()
}

fun readBigInt(): BigInteger {
    return readLine()!!.toBigInteger()
}

fun readInts(): List<Int> {
    return readLine()!!.split(" ").map(String::toInt)
}

fun readLongs(): List<Long> {
    return readLine()!!.split(" ").map(String::toLong)
}

fun readBigInts(): List<BigInteger> {
    return readLine()!!.split(" ").map(String::toBigInteger)
}

fun query(nodes: MutableList<Int>): List<Int> {
    println("? ${nodes.size} ${nodes.joinToString(" ")}")
    return readInts()
}

fun output(u: Int, v: Int) {
    println("! $u $v")
    readLine()!!
}

class Solution {
    private var maxDepth = 0
    private val depth = mutableListOf<Int>()
    private val adj = mutableListOf<MutableList<Int>>()

    private fun dfs(u: Int, p: Int) {
        depth[u] = if (p == 0) 0 else depth[p] + 1
        maxDepth = maxDepth.coerceAtLeast(depth[u])
        for (v in adj[u]) {
            if (v != p)
                dfs(v, u)
        }
    }

    fun solve() {
        val n = readInt()
        for (i in 0 until n + 1) {
            adj.add(mutableListOf())
            depth.add(0)
        }
        for (i in 0 until n - 1) {
            val (u, v) = readInts()
            adj[u].add(v)
            adj[v].add(u)
        }
        val (root, minDist) = query((1 until n + 1).toMutableList());
        dfs(root, 0)
        val nodes = Array(maxDepth + 1) { mutableListOf<Int>()}
        for (i in 1 until n + 1)
            nodes[depth[i]].add(i)
        var lo = (minDist + 1) / 2
        var hi = maxDepth
        while (lo <= hi) {
            val mid = (lo + hi) shr 1
            val (_, dist) = query(nodes[mid]);
            if (dist > minDist)
                hi = mid - 1
            else
                lo = mid + 1
        }
        val (u, _) = query(nodes[hi]);
        val dv = minDist - hi;
        if (dv == hi)
            nodes[hi] = nodes[hi].filter { it != u }.toMutableList()
        val (v, _) = query(nodes[dv])
        output(u, v)
    }
}

fun main() {
    val t = readInt()
    for (i in 0 until t) {
        val solution = Solution()
        solution.solve()
    }
}


import java.io.*
import java.util.*
import kotlin.math.*
//solves first version of F
fun main(){
	val f = BufferedReader(InputStreamReader(System.`in`))

	for(q in 1..f.readLine().toInt()){
		val n = f.readLine().toInt()

		val adj = Array(n+1){mutableListOf<Int>()}

		for(k in 2..n){
			val (a,b) = f.readLine().split(" ").map{it.toInt()}
			adj[a].add(b)
			adj[b].add(a)
		}

		//get length of path
		val sjq1 = StringJoiner(" ")
		sjq1.add("? $n")
		for(k in 1..n){
			sjq1.add("$k")
		}

		println(sjq1)
		System.out.flush()

		val (xq1,dq1) = f.readLine().split(" ").map{it.toInt()}

		val length = dq1+1

		println("? 1 1") //get depth of peak
		System.out.flush()

		val (xq2,dq2) = f.readLine().split(" ").map{it.toInt()}

		val depthofpeak = dq2-(dq1-1)-1
		//println("$length $depthofpeak")
		val depths = IntArray(n+1)
		val parents = IntArray(n+1)
		val depthset = Array(n){hashSetOf<Int>()}
		depths[1] = 0
		var maxdepth = 0
		fun getdepths(v : Int, p : Int){
			parents[v] = p
			depthset[depths[v]].add(v)
			maxdepth = max(maxdepth,depths[v])

			for(nei in adj[v]){
				if(nei == p) continue
				depths[nei] = depths[v]+1
				getdepths(nei,v)
			}

		}
		getdepths(1,-1)
		//println(depths.joinToString(" "))
		//find deepest node with same d value as dq1
		var l = depthofpeak
		var r = maxdepth
		var ans = -1

		while(l <= r){
			val mid = l + (r-l)/2

			//println("$l $r")
			//query
			val sjq = StringJoiner(" ")
			sjq.add("? ${depthset[mid].size}")
			for(i in depthset[mid]){
				sjq.add("$i")
			}
			println(sjq)
			System.out.flush()
			val (xq,dq) = f.readLine().split(" ").map{it.toInt()}

			if(dq == dq1){
				ans = xq
				l = mid+1
			} else {
				r = mid-1
			}
		}

		//ans is one of the nodes

		val nogo = HashSet<Int>()
		var i = ans
		while(depths[i] != depthofpeak){
			nogo.add(i)
			i = parents[i]
		}
		val pathpeak = i
		val otherdepth = length - (depths[ans] - depthofpeak) + depthofpeak -1

		//println("$pathpeak $otherdepth")

		val finalqset = HashSet<Int>()

		fun finaldfs(v : Int){
			if(depths[v] == otherdepth) finalqset.add(v)

			for(nei in adj[v]){
				if(nei == parents[v] || nogo.contains(nei)) continue
				finaldfs(nei)

			}
		}
		finaldfs(pathpeak)
		val sjfinal = StringJoiner(" ")
		sjfinal.add("? ${finalqset.size}")

		for(k in finalqset){
			sjfinal.add("$k")
		}

		println(sjfinal)
		System.out.flush()

		val (xqfinal,dqfinal) = f.readLine().split(" ").map{it.toInt()}

		println("! $ans $xqfinal")
		System.out.flush()

		val verdict = f.readLine()

	}
}


import java.io.*
import java.util.*
import kotlin.math.*
//solves first version of F
fun main(){
	val f = BufferedReader(InputStreamReader(System.`in`))

	for(q in 1..f.readLine().toInt()){
		val n = f.readLine().toInt()

		val adj = Array(n+1){mutableListOf<Int>()}

		for(k in 2..n){
			val (a,b) = f.readLine().split(" ").map{it.toInt()}
			adj[a].add(b)
			adj[b].add(a)
		}

		//get length of path
		val sjq1 = StringJoiner(" ")
		sjq1.add("? $n")
		for(k in 1..n){
			sjq1.add("$k")
		}

		println(sjq1)
		System.out.flush()

		val (xq1,dq1) = f.readLine().split(" ").map{it.toInt()}

		val length = dq1+1

		println("? 1 1") //get depth of peak
		System.out.flush()

		val (xq2,dq2) = f.readLine().split(" ").map{it.toInt()}

		//val depthofpeak = dq2-(dq1-1)-1
		val depthofpeak = (dq2-dq1)/2
		//println("$length $depthofpeak")
		val depths = IntArray(n+1)
		val parents = IntArray(n+1)
		val depthset = Array(n){hashSetOf<Int>()}
		depths[1] = 0
		var maxdepth = 0
		fun getdepths(v : Int, p : Int){
			parents[v] = p
			depthset[depths[v]].add(v)
			maxdepth = max(maxdepth,depths[v])

			for(nei in adj[v]){
				if(nei == p) continue
				depths[nei] = depths[v]+1
				getdepths(nei,v)
			}

		}
		getdepths(1,-1)
		//println(depths.joinToString(" "))
		//find deepest node with same d value as dq1
		var l = depthofpeak
		var r = maxdepth
		var ans = -1

		while(l <= r){
			val mid = l + (r-l)/2

			//println("$l $r")
			//query
			val sjq = StringJoiner(" ")
			sjq.add("? ${depthset[mid].size}")
			for(i in depthset[mid]){
				sjq.add("$i")
			}
			println(sjq)
			System.out.flush()
			val (xq,dq) = f.readLine().split(" ").map{it.toInt()}

			if(dq == dq1){
				ans = xq
				l = mid+1
			} else {
				r = mid-1
			}
		}

		//ans is one of the nodes

		val nogo = HashSet<Int>()
		var i = ans
		while(depths[i] != depthofpeak){
			nogo.add(i)
			i = parents[i]
		}
		val pathpeak = i
		val otherdepth = length - (depths[ans] - depthofpeak) + depthofpeak -1

		//println("$pathpeak $otherdepth")

		val finalqset = HashSet<Int>()

		fun finaldfs(v : Int){
			if(depths[v] == otherdepth) finalqset.add(v)

			for(nei in adj[v]){
				if(nei == parents[v] || nogo.contains(nei)) continue
				finaldfs(nei)

			}
		}
		finaldfs(pathpeak)
		val sjfinal = StringJoiner(" ")
		sjfinal.add("? ${finalqset.size}")

		for(k in finalqset){
			sjfinal.add("$k")
		}

		println(sjfinal)
		System.out.flush()

		val (xqfinal,dqfinal) = f.readLine().split(" ").map{it.toInt()}

		println("! $ans $xqfinal")
		System.out.flush()

		val verdict = f.readLine()

	}
}


import java.io.*
import java.util.*
import kotlin.math.*
//solves F2, semi-t
fun main(){
	val f = BufferedReader(InputStreamReader(System.`in`))

	for(q in 1..f.readLine().toInt()){
		val n = f.readLine().toInt()

		val adj = Array(n+1){mutableListOf<Int>()}

		for(k in 2..n){
			val (a,b) = f.readLine().split(" ").map{it.toInt()}
			adj[a].add(b)
			adj[b].add(a)
		}

		//get length of path
		val sjq1 = StringJoiner(" ")
		sjq1.add("? $n")
		for(k in 1..n){
			sjq1.add("$k")
		}

		println(sjq1)
		System.out.flush()

		val (peak,dq1) = f.readLine().split(" ").map{it.toInt()}

		val length = dq1+1

		val depths = IntArray(n+1)
		val parents = IntArray(n+1)
		val depthset = Array(n){hashSetOf<Int>()}
		depths[peak] = 0
		var maxdepth = 0
		fun getdepths(v : Int, p : Int){
			parents[v] = p
			depthset[depths[v]].add(v)
			maxdepth = max(maxdepth,depths[v])

			for(nei in adj[v]){
				if(nei == p) continue
				depths[nei] = depths[v]+1
				getdepths(nei,v)
			}

		}
		getdepths(peak,-1)
		//println(depths.joinToString(" "))
		//find deepest node with same d value as dq1
		var l = (length)/2
		var r = min(length,maxdepth)
		var ans = -1

		while(l <= r){
			val mid = l + (r-l)/2

			//println("$l $r")
			//query
			val sjq = StringJoiner(" ")
			sjq.add("? ${depthset[mid].size}")
			for(i in depthset[mid]){
				sjq.add("$i")
			}
			println(sjq)
			System.out.flush()
			val (xq,dq) = f.readLine().split(" ").map{it.toInt()}

			if(dq == dq1){
				ans = xq
				l = mid+1
			} else {
				r = mid-1
			}
		}

		//ans is one of the nodes

		val nogo = HashSet<Int>()
		var i = ans
		while(i != peak){
			nogo.add(i)
			i = parents[i]
		}
		val otherdepth = length - depths[ans] -1

		//println("$pathpeak $otherdepth")

		val finalqset = HashSet<Int>()

		fun finaldfs(v : Int){
			if(depths[v] == otherdepth) finalqset.add(v)

			for(nei in adj[v]){
				if(nei == parents[v] || nogo.contains(nei)) continue
				finaldfs(nei)

			}
		}
		finaldfs(peak)
		val sjfinal = StringJoiner(" ")
		sjfinal.add("? ${finalqset.size}")

		for(k in finalqset){
			sjfinal.add("$k")
		}

		println(sjfinal)
		System.out.flush()

		val (xqfinal,dqfinal) = f.readLine().split(" ").map{it.toInt()}

		println("! $ans $xqfinal")
		System.out.flush()

		val verdict = f.readLine()

	}
}