#include<bits/stdc++.h>
using namespace std;

#define fo(i,n)         for(int i=0;i<n;i++)
#define fo2(i,n)        for(int i=n-1;i>=0;i--)
#define Fo(i,k,n)       for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1)
#define ll              long long
#define si(x)	        scanf("%d",&x)
#define sl(x)	        scanf("%lld",&x)
#define ss(s)	        scanf("%s",s)
#define pi(x)	        printf("%d\n",x)
#define pi2(x)          printf("%d ",x)
#define pl(x)	        printf("%lld\n",x)
#define pl2(x)          printf("%lld ",x)
#define ps(s)	        printf("%s\n",s)
#define pn              printf("\n")
#define deb(x)          cout << #x << "=" << x << endl
#define deb2(x, y)      cout << #x << "=" << x << " , " << #y << "=" << y << endl
#define pb              push_back
#define F               first
#define S               second
#define all(x)          x.begin(), x.end()
#define clr(x)          memset(x, 0, sizeof(x))
#define sortall(x)      sort(all(x))
#define tr(it, a)       for(auto it = a.begin(); it != a.end(); it++)
#define PI              3.1415926535897932384626

typedef pair<int, int>ii;
typedef pair<ll, ll>pl;
typedef vector<int>vi;
typedef vector<ll>vl;
typedef vector<ii>vii;
typedef vector<pl>vpl;
typedef vector<vi>vvi;
typedef vector<vl>vvl;

/*int mpow(int base, int exp);
ll binpow(ll base , ll exp);
void ipgraph(int n, int m);
void dfs(int u);*/

const int mod = 1000000007;
const int N = 3e5+5, M = N;

//vi g[N];
//bool vis[N];

map<int,int>mm;

void solve()
{
    ll n, m, x;

    sl(n);

    ll res=0;

    vl v;

    fo(i,n)
    {
        sl(m);

        if(mm[m] == 0) v.push_back(m),mm[m]++;
    }

    sort(v.begin() , v.end());

    for(int i=0 ; i<n-1 ; i++)
    {
        if(v[i] < 0) x = -v[i] , res-=1;
        else x=v[i];

        int pos=lower_bound(v.begin(),v.end(),2LL*x) - v.begin();

        if(v[pos] > 2*x || pos>=n) pos--;

        //deb2(pos,v[i]);

        res += (pos-i);
    }

    pl(res);
}

int main()
{
    int t = 1;

    //si(t);

    while(t--)
    {
        solve();
    }

    return 0;
}

/*void dfs(int u) //DFS
{
    vis[u] = 1;

	for(int v:g[u])
    {
		if (!vis[v])
           dfs(v);
	}

	vis[u] = 0;
}

void ipgraph(int n, int m) //GRAPH INPUT
{
	int i, u, v;

	while(m--)
    {
		si(u); si(v);
		g[u].pb(v);
		g[v].pb(u);
	}
}

ll binpow(ll base, ll exp)
{
    ll res = 1;
    while (exp > 0)
    {
        if (exp & 1)
            res = res * base;
        base = base * base;
        exp >>= 1;
    }
    return res;
}

int mpow(int base, int exp)
{
    base %= mod;
    int result = 1;
    while (exp > 0)
    {
       if (exp & 1) result = ((ll)result * base) % mod;
       base = ((ll)base * base) % mod;
       exp >>= 1;
    }
    return result;
}
*/

//    #include <chrono>
//    using namespace std::chrono;
//    auto start = high_resolution_clock::now();
//    auto stop = high_resolution_clock::now();
//    auto duration = duration_cast<milliseconds>(stop - start);
//    cout << duration.count() << endl;
//#ifdef _DEBUG
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
//#endif


#include<bits/stdc++.h>
using namespace std;

#define fo(i,n)         for(int i=0;i<n;i++)
#define fo2(i,n)        for(int i=n-1;i>=0;i--)
#define Fo(i,k,n)       for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1)
#define ll              long long
#define si(x)	        scanf("%d",&x)
#define sl(x)	        scanf("%lld",&x)
#define ss(s)	        scanf("%s",s)
#define pi(x)	        printf("%d\n",x)
#define pi2(x)          printf("%d ",x)
#define pl(x)	        printf("%lld\n",x)
#define pl2(x)          printf("%lld ",x)
#define ps(s)	        printf("%s\n",s)
#define pn              printf("\n")
#define deb(x)          cout << #x << "=" << x << endl
#define deb2(x, y)      cout << #x << "=" << x << " , " << #y << "=" << y << endl
#define pb              push_back
#define F               first
#define S               second
#define all(x)          x.begin(), x.end()
#define clr(x)          memset(x, 0, sizeof(x))
#define sortall(x)      sort(all(x))
#define tr(it, a)       for(auto it = a.begin(); it != a.end(); it++)
#define PI              3.1415926535897932384626

typedef pair<int, int>ii;
typedef pair<ll, ll>pl;
typedef vector<int>vi;
typedef vector<ll>vl;
typedef vector<ii>vii;
typedef vector<pl>vpl;
typedef vector<vi>vvi;
typedef vector<vl>vvl;

/*int mpow(int base, int exp);
ll binpow(ll base , ll exp);
void ipgraph(int n, int m);
void dfs(int u);*/

const int mod = 1000000007;
const int N = 3e5+5, M = N;

//vi g[N];
//bool vis[N];

void solve()
{
    ll n, m;

    sl(n);

    ll res=0;

    vl v;

    fo(i,n)
    {
        sl(m);

        if(m<0) m=-m;

        v.push_back(m);
    }

    sort(v.begin() , v.end());

    for(int i=0 ; i<n ; i++)
    {
        int pos=lower_bound(v.begin(),v.end(),2LL*v[i]) - v.begin();

        if(pos>=n) pos=n-1;

        if(v[pos] > 2*v[i]) pos--;

        //deb2(pos,v[i]);

        res += (pos-i);
    }

    pl(res);
}

int main()
{
    int t = 1;

    //si(t);

    while(t--)
    {
        solve();
    }

    return 0;
}

/*void dfs(int u) //DFS
{
    vis[u] = 1;

	for(int v:g[u])
    {
		if (!vis[v])
           dfs(v);
	}

	vis[u] = 0;
}

void ipgraph(int n, int m) //GRAPH INPUT
{
	int i, u, v;

	while(m--)
    {
		si(u); si(v);
		g[u].pb(v);
		g[v].pb(u);
	}
}

ll binpow(ll base, ll exp)
{
    ll res = 1;
    while (exp > 0)
    {
        if (exp & 1)
            res = res * base;
        base = base * base;
        exp >>= 1;
    }
    return res;
}

int mpow(int base, int exp)
{
    base %= mod;
    int result = 1;
    while (exp > 0)
    {
       if (exp & 1) result = ((ll)result * base) % mod;
       base = ((ll)base * base) % mod;
       exp >>= 1;
    }
    return result;
}
*/

//    #include <chrono>
//    using namespace std::chrono;
//    auto start = high_resolution_clock::now();
//    auto stop = high_resolution_clock::now();
//    auto duration = duration_cast<milliseconds>(stop - start);
//    cout << duration.count() << endl;
//#ifdef _DEBUG
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
//#endif


#include<bits/stdc++.h>
using namespace std;

#define fo(i,n)         for(int i=0;i<n;i++)
#define fo2(i,n)        for(int i=n-1;i>=0;i--)
#define Fo(i,k,n)       for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1)
#define ll              long long
#define si(x)	        scanf("%d",&x)
#define sl(x)	        scanf("%lld",&x)
#define ss(s)	        scanf("%s",s)
#define pi(x)	        printf("%d\n",x)
#define pi2(x)          printf("%d ",x)
#define pl(x)	        printf("%lld\n",x)
#define pl2(x)          printf("%lld ",x)
#define ps(s)	        printf("%s\n",s)
#define pn              printf("\n")
#define deb(x)          cout << #x << "=" << x << endl
#define deb2(x, y)      cout << #x << "=" << x << " , " << #y << "=" << y << endl
#define pb              push_back
#define F               first
#define S               second
#define all(x)          x.begin(), x.end()
#define clr(x)          memset(x, 0, sizeof(x))
#define sortall(x)      sort(all(x))
#define tr(it, a)       for(auto it = a.begin(); it != a.end(); it++)
#define PI              3.1415926535897932384626

typedef pair<int, int>ii;
typedef pair<ll, ll>pl;
typedef vector<int>vi;
typedef vector<ll>vl;
typedef vector<ii>vii;
typedef vector<pl>vpl;
typedef vector<vi>vvi;
typedef vector<vl>vvl;

/*int mpow(int base, int exp);
ll binpow(ll base , ll exp);
void ipgraph(int n, int m);
void dfs(int u);*/

const int mod = 1000000007;
const int N = 3e5+5, M = N;

//vi g[N];
//bool vis[N];

map<int,int>mm;

void solve()
{
    ll n, m, x;

    sl(n);

    ll res=0;

    vl v;

    fo(i,n)
    {
        sl(m);

        if(mm[m] == 0) v.push_back(m),mm[m]++;
    }

    sort(v.begin() , v.end());

    for(int i=0 ; i<n-1 ; i++)
    {
        if(v[i] < 0) x = -v[i];
        else x=v[i];

        int pos=lower_bound(v.begin(),v.end(),2LL*x) - v.begin();

        if(pos >= n) pos=n-1;

        if(v[pos] > 2*x || pos>=n) pos--;

        //deb2(pos,v[i]);

        res += (pos-i);

        if(v[i]<0 && mm[x]>=1) res-=1;
    }

    pl(res);
}

int main()
{
    int t = 1;

    //si(t);

    while(t--)
    {
        solve();
    }

    return 0;
}

/*void dfs(int u) //DFS
{
    vis[u] = 1;

	for(int v:g[u])
    {
		if (!vis[v])
           dfs(v);
	}

	vis[u] = 0;
}

void ipgraph(int n, int m) //GRAPH INPUT
{
	int i, u, v;

	while(m--)
    {
		si(u); si(v);
		g[u].pb(v);
		g[v].pb(u);
	}
}

ll binpow(ll base, ll exp)
{
    ll res = 1;
    while (exp > 0)
    {
        if (exp & 1)
            res = res * base;
        base = base * base;
        exp >>= 1;
    }
    return res;
}

int mpow(int base, int exp)
{
    base %= mod;
    int result = 1;
    while (exp > 0)
    {
       if (exp & 1) result = ((ll)result * base) % mod;
       base = ((ll)base * base) % mod;
       exp >>= 1;
    }
    return result;
}
*/

//    #include <chrono>
//    using namespace std::chrono;
//    auto start = high_resolution_clock::now();
//    auto stop = high_resolution_clock::now();
//    auto duration = duration_cast<milliseconds>(stop - start);
//    cout << duration.count() << endl;
//#ifdef _DEBUG
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
//#endif


#include<bits/stdc++.h>
using namespace std;

#define fo(i,n)         for(int i=0;i<n;i++)
#define fo2(i,n)        for(int i=n-1;i>=0;i--)
#define Fo(i,k,n)       for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1)
#define ll              long long
#define si(x)	        scanf("%d",&x)
#define sl(x)	        scanf("%lld",&x)
#define ss(s)	        scanf("%s",s)
#define pi(x)	        printf("%d\n",x)
#define pi2(x)          printf("%d ",x)
#define pl(x)	        printf("%lld\n",x)
#define pl2(x)          printf("%lld ",x)
#define ps(s)	        printf("%s\n",s)
#define pn              printf("\n")
#define deb(x)          cout << #x << "=" << x << endl
#define deb2(x, y)      cout << #x << "=" << x << " , " << #y << "=" << y << endl
#define pb              push_back
#define F               first
#define S               second
#define all(x)          x.begin(), x.end()
#define clr(x)          memset(x, 0, sizeof(x))
#define sortall(x)      sort(all(x))
#define tr(it, a)       for(auto it = a.begin(); it != a.end(); it++)
#define PI              3.1415926535897932384626

typedef pair<int, int>ii;
typedef pair<ll, ll>pl;
typedef vector<int>vi;
typedef vector<ll>vl;
typedef vector<ii>vii;
typedef vector<pl>vpl;
typedef vector<vi>vvi;
typedef vector<vl>vvl;

/*int mpow(int base, int exp);
ll binpow(ll base , ll exp);
void ipgraph(int n, int m);
void dfs(int u);*/

const int mod = 1000000007;
const int N = 3e5+5, M = N;

//vi g[N];
//bool vis[N];

map<int,int>mm;

void solve()
{
    ll n, m, x;

    sl(n);

    ll res=0;

    vl v;

    fo(i,n)
    {
        sl(m);

        if(mm[m] == 0) v.push_back(m),mm[m]++;
    }

    sort(v.begin() , v.end());

    for(int i=0 ; i<n-1 ; i++)
    {
        if(v[i] < 0) x = -v[i];
        else x=v[i];

        int pos=lower_bound(v.begin(),v.end(),2LL*x) - v.begin();

        if(pos >= n) pos=n-1;

        if(v[pos] > 2*x || pos>=n) pos--;

        //deb2(pos,v[i]);

        res += (pos-i);

        //if(v[i]<0 && mm[x]>=1) res-=1;

        if(mm[0]>=1 && v[i]<0) res-=1;

        //deb2(v[i] , res);
    }

    pl(res);
}

int main()
{
    int t = 1;

    //si(t);

    while(t--)
    {
        solve();
    }

    return 0;
}

/*void dfs(int u) //DFS
{
    vis[u] = 1;

	for(int v:g[u])
    {
		if (!vis[v])
           dfs(v);
	}

	vis[u] = 0;
}

void ipgraph(int n, int m) //GRAPH INPUT
{
	int i, u, v;

	while(m--)
    {
		si(u); si(v);
		g[u].pb(v);
		g[v].pb(u);
	}
}

ll binpow(ll base, ll exp)
{
    ll res = 1;
    while (exp > 0)
    {
        if (exp & 1)
            res = res * base;
        base = base * base;
        exp >>= 1;
    }
    return res;
}

int mpow(int base, int exp)
{
    base %= mod;
    int result = 1;
    while (exp > 0)
    {
       if (exp & 1) result = ((ll)result * base) % mod;
       base = ((ll)base * base) % mod;
       exp >>= 1;
    }
    return result;
}
*/

//    #include <chrono>
//    using namespace std::chrono;
//    auto start = high_resolution_clock::now();
//    auto stop = high_resolution_clock::now();
//    auto duration = duration_cast<milliseconds>(stop - start);
//    cout << duration.count() << endl;
//#ifdef _DEBUG
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
//#endif


#include<bits/stdc++.h>
using namespace std;

#define fo(i,n)         for(int i=0;i<n;i++)
#define fo2(i,n)        for(int i=n-1;i>=0;i--)
#define Fo(i,k,n)       for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1)
#define ll              long long
#define si(x)	        scanf("%d",&x)
#define sl(x)	        scanf("%lld",&x)
#define ss(s)	        scanf("%s",s)
#define pi(x)	        printf("%d\n",x)
#define pi2(x)          printf("%d ",x)
#define pl(x)	        printf("%lld\n",x)
#define pl2(x)          printf("%lld ",x)
#define ps(s)	        printf("%s\n",s)
#define pn              printf("\n")
#define deb(x)          cout << #x << "=" << x << endl
#define deb2(x, y)      cout << #x << "=" << x << " , " << #y << "=" << y << endl
#define pb              push_back
#define F               first
#define S               second
#define all(x)          x.begin(), x.end()
#define clr(x)          memset(x, 0, sizeof(x))
#define sortall(x)      sort(all(x))
#define tr(it, a)       for(auto it = a.begin(); it != a.end(); it++)
#define PI              3.1415926535897932384626

typedef pair<int, int>ii;
typedef pair<ll, ll>pl;
typedef vector<int>vi;
typedef vector<ll>vl;
typedef vector<ii>vii;
typedef vector<pl>vpl;
typedef vector<vi>vvi;
typedef vector<vl>vvl;

/*int mpow(int base, int exp);
ll binpow(ll base , ll exp);
void ipgraph(int n, int m);
void dfs(int u);*/

const int mod = 1000000007;
const int N = 3e5+5, M = N;

//vi g[N];
//bool vis[N];

map<int,int>mm;

void solve()
{
    ll n, m, x;

    sl(n);

    ll res=0;

    vl v;

    fo(i,n)
    {
        sl(m);

        if(mm[m] == 0) v.push_back(m),mm[m]++;
    }

    sort(v.begin() , v.end());

    for(int i=0 ; i<n-1 ; i++)
    {
        if(v[i] < 0) x = -v[i];
        else x=v[i];

        int pos=lower_bound(v.begin(),v.end(),2LL*x) - v.begin();

        if(pos >= n) pos=n-1;

        if(v[pos] > 2*x || pos>=n) pos--;

        //deb2(pos,v[i]);

        res += (pos-i);

        if(v[i]<0 && mm[x]>=1) res-=1;

        if(mm[0]>=1 && v[i]<0) res-=1;
    }

    pl(res);
}

int main()
{
    int t = 1;

    //si(t);

    while(t--)
    {
        solve();
    }

    return 0;
}

/*void dfs(int u) //DFS
{
    vis[u] = 1;

	for(int v:g[u])
    {
		if (!vis[v])
           dfs(v);
	}

	vis[u] = 0;
}

void ipgraph(int n, int m) //GRAPH INPUT
{
	int i, u, v;

	while(m--)
    {
		si(u); si(v);
		g[u].pb(v);
		g[v].pb(u);
	}
}

ll binpow(ll base, ll exp)
{
    ll res = 1;
    while (exp > 0)
    {
        if (exp & 1)
            res = res * base;
        base = base * base;
        exp >>= 1;
    }
    return res;
}

int mpow(int base, int exp)
{
    base %= mod;
    int result = 1;
    while (exp > 0)
    {
       if (exp & 1) result = ((ll)result * base) % mod;
       base = ((ll)base * base) % mod;
       exp >>= 1;
    }
    return result;
}
*/

//    #include <chrono>
//    using namespace std::chrono;
//    auto start = high_resolution_clock::now();
//    auto stop = high_resolution_clock::now();
//    auto duration = duration_cast<milliseconds>(stop - start);
//    cout << duration.count() << endl;
//#ifdef _DEBUG
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
//#endif


from collections import deque
def NC_Dij(lis,start):

    ret = [float("inf")] * len(lis)
    ret[start] = 0

    q = deque([start])
    plis = [i for i in range(len(lis))]

    while len(q) > 0:
        now = q.popleft()

        for nex in lis[now]:

            if ret[nex] > ret[now] + 1:
                ret[nex] = ret[now] + 1
                plis[nex] = now
                q.append(nex)

    return ret,plis

tt = int(input())

for loop in range(tt):

    n = int(input())
    lis = [ [] for i in range(n)]

    for i in range(n-1):

        v,u = map(int,input().split())
        v -= 1
        u -= 1

        lis[v].append(u)
        lis[u].append(v)

    print ("?",n,*[i+1 for i in range(n)] , flush=True)

    x1,d1 = map(int,input().split())
    x1 -= 1

    dlis,plis = NC_Dij(lis,x1)

    r = max(dlis)+1
    l = 0

    dic = {}
    dic[0] = x1

    while r-l != 1:

        m = (l+r)//2
        #print (l,r,m)

        nodes = []
        for i in range(n):
            if dlis[i] == m:
                nodes.append(i+1)

        print ("?",len(nodes), *nodes , flush=True)
        nx,nd = map(int,input().split())
        nx -= 1

        dic[m] = nx
        if nd == d1:
            l = m
        else:
            r = m

    ans1 = dic[l]
    dlis2,plis2 = NC_Dij(lis,ans1)
    nodes = []
    for i in range(n):
        if dlis2[i] == d1:
            nodes.append(i+1)
    print ("?",len(nodes), *nodes , flush=True)
    ans2,tmp = map(int,input().split())

    print ("!",ans1+1,ans2 , flush=True)

    ret = input()


from collections import deque as dq
def NC_Dij(lis,start):
    ret = [float("inf")] * len(lis);ret[start] = 0;q = dq([start]);plis = [i for i in range(len(lis))]
    while len(q) > 0:
        now = q.popleft()
        for nex in lis[now]:
            if ret[nex] > ret[now] + 1:ret[nex] = ret[now] + 1;plis[nex] = now;q.append(nex)
    return ret,plis
for loop in range(int(input())):
    n = int(input());lis = [ [] for i in range(n)]
    for i in range(n-1):v,u = map(int,input().split());v -= 1;u -= 1;lis[v].append(u);lis[u].append(v)
    print ("?",n,*[i+1 for i in range(n)] , flush=True);x1,d1 = map(int,input().split());x1 -= 1;dlis,plis = NC_Dij(lis,x1);r,l,dic = max(dlis)+1,0,{};dic[0] = x1
    while r-l != 1:
        m,nodes = (l+r)//2,[]
        for i in range(n):
            if dlis[i] == m:nodes.append(i+1)
        print ("?",len(nodes), *nodes , flush=True);nx,nd = map(int,input().split());nx -= 1;dic[m] = nx
        if nd == d1:l = m
        else:r = m
    ans1,nodes = dic[l],[];dlis2,plis2 = NC_Dij(lis,ans1)
    for i in range(n):
        if dlis2[i] == d1:nodes.append(i+1)
    print ("?",len(nodes), *nodes , flush=True);ans2,tmp = map(int,input().split());print ("!",ans1+1,ans2 , flush=True);ret = input()


from sys import stdout
from queue import Queue
t = int(input())
for _ in range(t):
	n = int(input())
	G = [[] for i in range(n)]
	for i in range(n - 1):
		v, u = map(int, input().split())
		v -= 1; u -= 1;
		G[v].append(u)
		G[u].append(v)
	dep = [0] * n

	def dfs(v, pr):
		for u in G[v]:
			if (u != pr):
				dep[u] = dep[v] + 1
				dfs(u, v)

	dfs(0, 0)
	print("?", n, *list(range(1, n + 1)))
	stdout.flush()
	tmp, dist = map(int, input().split())
	max_dep = max(dep)
	R = max_dep + 1; L = 0
	while R - L > 1:
		mid = (L + R) // 2
		vers = []
		for i in range(n):
			if dep[i] >= mid:
				vers.append(i + 1)
		print("?", len(vers), *vers)
		stdout.flush()
		tmp, cur_dist = map(int, input().split())
		if cur_dist == dist:
			L = mid
		else:
			R = mid
	vers = []
	for i in range(n):
		if dep[i] == L:
			vers.append(i + 1)
	print("?", len(vers), *vers);
	stdout.flush()
	v, tmp = map(int, input().split())
	v -= 1
	q = Queue()
	dist_v = [2 * n] * n
	dist_v[v] = 0
	q.put(v)
	while not q.empty():
		cur = q.get()
		for u in G[cur]:
			if dist_v[u] > dist_v[cur] + 1:
				dist_v[u] = dist_v[cur] + 1
				q.put(u)
	vers = []
	for i in range(n):
		if dist_v[i] == dist:
			vers.append(i + 1)
	print("?", len(vers), *vers)
	stdout.flush()
	u, tmp = map(int, input().split())
	u -= 1
	print("!", u + 1, v + 1)
	stdout.flush()
	tmp = input()


import sys
input = sys.stdin.readline
inputr = lambda: input().rstrip('\n')

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

for _ in range(int(input())):
	n = int(input())
	adj = [[] for _ in range(n)]
	for _ in range(n-1):
		u, v = map(int, input().split())
		u -= 1
		v -= 1
		adj[u].append(v)
		adj[v].append(u)

	root, tdist = query(range(n))

	D = [-1] * n
	D[root] = 0
	Q = [root]
	while Q:
		i = Q.pop()
		for j in adj[i]:
			if D[j] == -1:
				D[j] = D[i] + 1
				Q.append(j)

	lo = 0
	hi = n #tdist//2 + 1
	first = -1
	while lo < hi:
		m = (lo + hi) // 2

		q = [i for i in range(n) if D[i] == m]
		if not q:
			hi = m
			continue

		r, d = query(q)
		if d == tdist:
			first = r
			lo = m + 1
		else:
			hi = m

	assert first != -1

	V = [False] * n
	q = []
	V[first] = True
	Q = [(first, 0)]
	while Q:
		i, d = Q.pop()
		if d == tdist:
			q.append(i)
		else:
			for j in adj[i]:
				if not V[j]:
					V[j] = True
					Q.append((j, d+1))

	print('!', first+1, query(q)[0]+1, flush=True)
	assert inputr() == 'Correct'


#include <stdio.h>
#include <stdlib.h>

#define N	1000

int max(int a, int b) { return a > b ? a : b; }

int i_;

int query(int *ii, int n) {
	int h, x;

	printf("? %d", n);
	for (h = 0; h < n; h++)
		printf(" %d", ii[h] + 1);
	printf("\n"), fflush(stdout);
	scanf("%d%d", &i_, &x), i_--;
	return x;
}

int *oj[N], oo[N], sz[N], dd[N], n;

void add(int i, int j) {
	int o = oo[i]++;

	if (o >= 2 && (o & o - 1) == 0)
		oj[i] = realloc(oj[i], o * 2 * sizeof *oj[i]);
	oj[i][o] = j;
}

int c;

void dfs1(int p, int i) {
	int o, centroid;

	sz[i] = 1, centroid = 1;
	for (o = 0; o < oo[i]; o++) {
		int j = oj[i][o];

		if (j != p) {
			dfs1(i, j);
			if (sz[j] * 2 > n)
				centroid = 0;
			sz[i] += sz[j];
		}
	}
	if ((n - sz[i]) * 2 > n)
		centroid = 0;
	if (centroid)
		c = i;
}

void dfs2(int p, int i, int d) {
	int o;

	dd[i] = d;
	for (o = 0; o < oo[i]; o++) {
		int j = oj[i][o];

		if (j != p)
			dfs2(i, j, d + 1);
	}
}

int main() {
	int t;

	scanf("%d", &t);
	while (t--) {
		static char verdict[16];
		static int ii[N];
		int cnt, h, i, j, l, lower, upper, u, v;

		scanf("%d", &n);
		for (i = 0; i < n; i++)
			oj[i] = malloc(2 * sizeof *oj[i]), oo[i] = 0;
		for (h = 0; h < n - 1; h++) {
			scanf("%d%d", &i, &j), i--, j--;
			add(i, j), add(j, i);
		}
		dfs1(-1, 0);
		dfs2(-1, c, 0);
		for (i = 0; i < n; i++)
			ii[i] = i;
		lower = 0, upper = 0;
		for (i = 0; i < n; i++)
			upper = max(upper, dd[i] + 1);
		l = query(ii, n), u = i_;
		while (upper - lower > 1) {
			int d = (lower + upper) / 2;

			cnt = 0;
			for (i = 0; i < n; i++)
				if (dd[i] >= d)
					ii[cnt++] = i;
			if (query(ii, cnt) == l)
				lower = d, u = i_;
			else
				upper = d;
		}
		dfs2(-1, u, 0);
		cnt = 0;
		for (i = 0; i < n; i++)
			if (dd[i] == l)
				ii[cnt++] = i;
		query(ii, cnt), v = i_;
		printf("! %d %d\n", u + 1, v + 1), fflush(stdout);
		scanf("%s", verdict);
		for (i = 0; i < n; i++)
			free(oj[i]);
	}
	return 0;
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int cnt, n, tu, tv;
    int[][] tdist;
    string response;
    const int MAX = 1000;
    Random rnd = new Random(13);
    List<int>[] g;

    int[] GetDistances(int x)
    {
        var ret = Enumerable.Repeat(-1, n).ToArray();
        ret[x] = 0;
        var q = new Queue<int>();
        q.Enqueue(x);
        while (q.Count > 0)
        {
            int u = q.Dequeue();
            foreach (int e in g[u])
                if (ret[e] == -1)
                {
                    ret[e] = ret[u] + 1;
                    q.Enqueue(e);
                }
        }
        return ret;
    }

    void Reset()
    {
        n = 1000;
        g = Init<List<int>>(n);
        for (int i = 1; i < n; i++)
        {
            int u = rnd.Next(i);
            int v = i;
            g[u].Add(v);
            g[v].Add(u);
        }
        cnt = 0;
        tu = rnd.Next(n);
        tv = rnd.Next(n);
        while (tu == tv)
            tv = rnd.Next(n);

        tdist = new int[n][];
        for (int i = 0; i < n; i++)
            tdist[i] = GetDistances(i);
    }

    void Say(string s)
    {
#if DEBUG
        var split = s.Split(' ');
        if (split[0] == "!")
        {
            int qu = int.Parse(split[1]) - 1;
            int qv = int.Parse(split[2]) - 1;
            if (qu == tu && qv == tv || qu == tv && qv == tu)
            {
                Console.WriteLine("Correct answer in {0} attempts", cnt);
                response = "Correct";
            }
            else
            {
                response = "Incorrect";
            }
        }
        else
        {
            if (cnt >= 14)
                throw new Exception("Too many questions");
            cnt++;
            int size = int.Parse(split[1]);
            int min = int.MaxValue;
            var cands = new List<int>();
            for (int i = 0; i < size; i++)
            {
                int o = int.Parse(split[i + 2]) - 1;
                int sum = tdist[tu][o] + tdist[tv][o];
                if (sum == min)
                {
                    cands.Add(o);
                }
                else if (sum < min)
                {
                    cands = new List<int> { o };
                    min = sum;
                }
            }
            response = string.Format("{0} {1}", cands[rnd.Next(cands.Count)] + 1, min);
        }
#else
        Write(s);
        writer.Flush();
#endif
    }

    string Listen()
    {
#if DEBUG
        return response;
#else
        return reader.ReadLine();
#endif
    }

    public void Solve()
    {
#if DEBUG
#else
        n = ReadInt();
        g = Init<List<int>>(n);
        for (int i = 1; i < n; i++)
        {
            int u = ReadInt() - 1;
            int v = ReadInt() - 1;
            g[u].Add(v);
            g[v].Add(u);
        }
#endif

        Say(string.Format("? {0} {1}", n, string.Join(" ", Enumerable.Range(1, n))));
        var resp = Listen().Split(' ').Select(int.Parse).ToArray();
        int len = resp[1];
        int center = resp[0] - 1;
        var d = GetDistances(center);

        Func<int, int[]> fun = v =>
        {
            var list = new List<int>();
            for (int i = 0; i < n; i++)
                if (d[i] == v)
                    list.Add(i + 1);
            if (list.Count == 0)
            {
                return null;
            }

            Say(string.Format("? {0} {1}", list.Count, string.Join(" ", list)));
            resp = Listen().Split(' ').Select(int.Parse).ToArray();
            return resp;
        };

        resp = null;
        int lo = len / 2, hi = len;
        while (lo < hi)
        {
            int mid = (lo + hi + 1) / 2;
            fun(mid);

            if (resp == null || resp[1] > len)
                hi = mid - 1;
            else
                lo = mid;
        }

        fun(lo);

        center = resp[0] - 1;
        d = GetDistances(center);
        fun(len);
        Say(string.Format("! {0} {1}", center + 1, resp[0]));
        if (Listen() != "Correct")
            throw new Exception();
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());

#if DEBUG

        var solver = new Solver();
        for (int iter = 0; iter < 20; iter++)
        {
            solver.Reset();
            try
            {
                solver.Solve();
            }
            catch (Exception ex)
            {
                Write(ex);
            }
        }
#else
        try
        {
            for (int tt = ReadInt(); tt > 0; tt--)
                new Solver().Solve();
        }
        catch (Exception ex)
        {
            throw;
        }
#endif
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0) currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++) matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++) ret[i][j] = matrix[j][i]; }
        return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++) lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array) writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++) ret[i] = new T(); return ret; }
    #endregion
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int cnt, n, tu, tv;
    int[][] tdist;
    string response;
    const int MAX = 1000;
    Random rnd = new Random(13);
    List<int>[] g;

    int[] GetDistances(int x)
    {
        var ret = Enumerable.Repeat(-1, n).ToArray();
        ret[x] = 0;
        var q = new Queue<int>();
        q.Enqueue(x);
        while (q.Count > 0)
        {
            int u = q.Dequeue();
            foreach (int e in g[u])
                if (ret[e] == -1)
                {
                    ret[e] = ret[u] + 1;
                    q.Enqueue(e);
                }
        }
        return ret;
    }

    void Reset()
    {
        n = 1000;
        g = Init<List<int>>(n);
        for (int i = 1; i < n; i++)
        {
            int u = rnd.Next(i);
            int v = i;
            g[u].Add(v);
            g[v].Add(u);
        }
        cnt = 0;
        tu = rnd.Next(n);
        tv = rnd.Next(n);
        while (tu == tv)
            tv = rnd.Next(n);

        tdist = new int[n][];
        for (int i = 0; i < n; i++)
            tdist[i] = GetDistances(i);
    }

    void Say(string s)
    {
#if DEBUG
        var split = s.Split(' ');
        if (split[0] == "!")
        {
            int qu = int.Parse(split[1]) - 1;
            int qv = int.Parse(split[2]) - 1;
            if (qu == tu && qv == tv || qu == tv && qv == tu)
            {
                Console.WriteLine("Correct answer in {0} attempts", cnt);
                response = "Correct";
            }
            else
            {
                response = "Incorrect";
            }
        }
        else
        {
            if (cnt >= 14)
                throw new Exception("Too many questions");
            cnt++;
            int size = int.Parse(split[1]);
            int min = int.MaxValue;
            var cands = new List<int>();
            for (int i = 0; i < size; i++)
            {
                int o = int.Parse(split[i + 2]) - 1;
                int sum = tdist[tu][o] + tdist[tv][o];
                if (sum == min)
                {
                    cands.Add(o);
                }
                else if (sum < min)
                {
                    cands = new List<int> { o };
                    min = sum;
                }
            }
            response = string.Format("{0} {1}", cands[rnd.Next(cands.Count)] + 1, min);
        }
#else
        Write(s);
        writer.Flush();
#endif
    }

    string Listen()
    {
#if DEBUG
        return response;
#else
        return reader.ReadLine();
#endif
    }

    public void Solve()
    {
#if DEBUG
#else
        n = ReadInt();
        g = Init<List<int>>(n);
        for (int i = 1; i < n; i++)
        {
            int u = ReadInt() - 1;
            int v = ReadInt() - 1;
            g[u].Add(v);
            g[v].Add(u);
        }
#endif

        Say(string.Format("? {0} {1}", n, string.Join(" ", Enumerable.Range(1, n))));
        var resp = Listen().Split(' ').Select(int.Parse).ToArray();
        int len = resp[1];
        int center = resp[0] - 1;
        var d = GetDistances(center);

        Func<int, int[]> fun = v =>
        {
            var list = new List<int>();
            for (int i = 0; i < n; i++)
                if (d[i] == v)
                    list.Add(i + 1);
            if (list.Count == 0)
            {
                return null;
            }

            Say(string.Format("? {0} {1}", list.Count, string.Join(" ", list)));
            resp = Listen().Split(' ').Select(int.Parse).ToArray();
            return resp;
        };

        resp = null;
        int lo = len / 2, hi = len;
        while (lo < hi)
        {
            int mid = (lo + hi + 1) / 2;
            fun(mid);

            if (resp == null || resp[1] > len)
                hi = mid - 1;
            else
                lo = mid;
        }

        if (resp == null || resp[1] > len)
            fun(lo);

        center = resp[0] - 1;
        d = GetDistances(center);
        fun(len);
        Say(string.Format("! {0} {1}", center + 1, resp[0]));
        if (Listen() != "Correct")
            throw new Exception();
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());

#if DEBUG

        var solver = new Solver();
        for (int iter = 0; iter < 20; iter++)
        {
            solver.Reset();
            try
            {
                solver.Solve();
            }
            catch (Exception ex)
            {
                Write(ex);
            }
        }
#else
        try
        {
            for (int tt = ReadInt(); tt > 0; tt--)
                new Solver().Solve();
        }
        catch (Exception ex)
        {
            throw;
        }
#endif
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0) currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++) matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++) ret[i][j] = matrix[j][i]; }
        return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++) lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array) writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++) ret[i] = new T(); return ret; }
    #endregion
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int cnt, n, tu, tv;
    int[][] tdist;
    string response;
    const int MAX = 1000;
    Random rnd = new Random(13);
    List<int>[] g;

    int[] GetDistances(int x)
    {
        var ret = Enumerable.Repeat(-1, n).ToArray();
        ret[x] = 0;
        var q = new Queue<int>();
        q.Enqueue(x);
        while (q.Count > 0)
        {
            int u = q.Dequeue();
            foreach (int e in g[u])
                if (ret[e] == -1)
                {
                    ret[e] = ret[u] + 1;
                    q.Enqueue(e);
                }
        }
        return ret;
    }

    void Reset()
    {
        n = 1000;
        g = Init<List<int>>(n);
        for (int i = 1; i < n; i++)
        {
            int u = rnd.Next(i);
            int v = i;
            g[u].Add(v);
            g[v].Add(u);
        }
        cnt = 0;
        tu = rnd.Next(n);
        tv = rnd.Next(n);
        while (tu == tv)
            tv = rnd.Next(n);

        tdist = new int[n][];
        for (int i = 0; i < n; i++)
            tdist[i] = GetDistances(i);
    }

    void Say(string s)
    {
#if DEBUG
        var split = s.Split(' ');
        if (split[0] == "!")
        {
            int qu = int.Parse(split[1]) - 1;
            int qv = int.Parse(split[2]) - 1;
            if (qu == tu && qv == tv || qu == tv && qv == tu)
            {
                Console.WriteLine("Correct answer in {0} attempts", cnt);
                response = "Correct";
            }
            else
            {
                response = "Incorrect";
            }
        }
        else
        {
            if (cnt >= 14)
                throw new Exception("Too many questions");
            cnt++;
            int size = int.Parse(split[1]);
            int min = int.MaxValue;
            var cands = new List<int>();
            for (int i = 0; i < size; i++)
            {
                int o = int.Parse(split[i + 2]) - 1;
                int sum = tdist[tu][o] + tdist[tv][o];
                if (sum == min)
                {
                    cands.Add(o);
                }
                else if (sum < min)
                {
                    cands = new List<int> { o };
                    min = sum;
                }
            }
            response = string.Format("{0} {1}", cands[rnd.Next(cands.Count)] + 1, min);
        }
#else
        Write(s);
        writer.Flush();
#endif
    }

    string Listen()
    {
#if DEBUG
        return response;
#else
        return reader.ReadLine();
#endif
    }

    public void Solve()
    {
#if DEBUG
#else
        n = ReadInt();
        g = Init<List<int>>(n);
        for (int i = 1; i < n; i++)
        {
            int u = ReadInt() - 1;
            int v = ReadInt() - 1;
            g[u].Add(v);
            g[v].Add(u);
        }
#endif

        Say(string.Format("? {0} {1}", n, string.Join(" ", Enumerable.Range(1, n))));
        var resp = Listen().Split(' ').Select(int.Parse).ToArray();
        int len = resp[1];
        int center = resp[0] - 1;
        var d = GetDistances(center);

        Func<int, int[]> fun = v =>
        {
            var list = new List<int>();
            for (int i = 0; i < n; i++)
                if (d[i] == v)
                    list.Add(i + 1);
            if (list.Count == 0)
            {
                return null;
            }

            Say(string.Format("? {0} {1}", list.Count, string.Join(" ", list)));
            resp = Listen().Split(' ').Select(int.Parse).ToArray();
            return resp;
        };

        int lo = len / 2, hi = len;
        while (lo < hi)
        {
            int mid = (lo + hi + 1) / 2;
            fun(mid);

            if (resp == null || resp[1] > len)
                hi = mid - 1;
            else
                lo = mid;
        }

        if (resp == null || resp[1] > len)
            fun(lo);

        center = resp[0] - 1;
        d = GetDistances(center);
        fun(len);
        Say(string.Format("! {0} {1}", center + 1, resp[0]));
        if (Listen() != "Correct")
            throw new Exception();
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());

#if DEBUG

        var solver = new Solver();
        for (int iter = 0; iter < 20; iter++)
        {
            solver.Reset();
            try
            {
                solver.Solve();
            }
            catch (Exception ex)
            {
                Write(ex);
            }
        }
#else
        try
        {
            for (int tt = ReadInt(); tt > 0; tt--)
                new Solver().Solve();
        }
        catch (Exception ex)
        {
            throw;
        }
#endif
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0) currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++) matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++) ret[i][j] = matrix[j][i]; }
        return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++) lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array) writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++) ret[i] = new T(); return ret; }
    #endregion
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int cnt, n, tu, tv;
    int[][] tdist;
    string response;
    const int MAX = 1000;
    Random rnd = new Random(13);
    List<int>[] g;

    int[] GetDistances(int x)
    {
        var ret = Enumerable.Repeat(-1, n).ToArray();
        ret[x] = 0;
        var q = new Queue<int>();
        q.Enqueue(x);
        while (q.Count > 0)
        {
            int u = q.Dequeue();
            foreach (int e in g[u])
                if (ret[e] == -1)
                {
                    ret[e] = ret[u] + 1;
                    q.Enqueue(e);
                }
        }
        return ret;
    }

    void Reset()
    {
        n = 100;
        g = Init<List<int>>(n);
        for (int i = 1; i < n; i++)
        {
            int u = rnd.Next(i);
            int v = i;
            g[u].Add(v);
            g[v].Add(u);
        }
        cnt = 0;
        tu = rnd.Next(n);
        tv = rnd.Next(n);
        while (tu == tv)
            tv = rnd.Next(n);

        tdist = new int[n][];
        for (int i = 0; i < n; i++)
            tdist[i] = GetDistances(i);
    }

    void Say(string s)
    {
#if DEBUG
        var split = s.Split(' ');
        if (split[0] == "!")
        {
            int qu = int.Parse(split[1]) - 1;
            int qv = int.Parse(split[2]) - 1;
            if (qu == tu && qv == tv || qu == tv && qv == tu)
            {
                Console.WriteLine("Correct answer in {0} attempts", cnt);
                response = "Correct";
            }
            else
            {
                response = "Incorrect";
            }
        }
        else
        {
            if (cnt >= 14)
                throw new Exception("Too many questions");
            cnt++;
            int size = int.Parse(split[1]);
            int min = int.MaxValue;
            var cands = new List<int>();
            for (int i = 0; i < size; i++)
            {
                int o = int.Parse(split[i + 2]) - 1;
                int sum = tdist[tu][o] + tdist[tv][o];
                if (sum == min)
                {
                    cands.Add(o);
                }
                else if (sum < min)
                {
                    cands = new List<int> { o };
                    min = sum;
                }
            }
            response = string.Format("{0} {1}", cands[rnd.Next(cands.Count)] + 1, min);
        }
#else
        Write(s);
        writer.Flush();
#endif
    }

    string Listen()
    {
#if DEBUG
        return response;
#else
        return reader.ReadLine();
#endif
    }

    public void Solve()
    {
#if DEBUG
#else
        n = ReadInt();
        g = Init<List<int>>(n);
        for (int i = 1; i < n; i++)
        {
            int u = ReadInt() - 1;
            int v = ReadInt() - 1;
            g[u].Add(v);
            g[v].Add(u);
        }
#endif

        Say(string.Format("? {0} {1}", n, string.Join(" ", Enumerable.Range(1, n))));
        var resp = Listen().Split(' ').Select(int.Parse).ToArray();
        int len = resp[1];
        int center = resp[0] - 1;
        var d = GetDistances(center);

        Action<int> fun = v =>
        {
            var list = new List<int>();
            for (int i = 0; i < n; i++)
                if (d[i] == v)
                    list.Add(i + 1);
            if (list.Count == 0)
            {
                resp = null;
                return;
            }

            Say(string.Format("? {0} {1}", list.Count, string.Join(" ", list)));
            resp = Listen().Split(' ').Select(int.Parse).ToArray();
        };

        resp = null;
        int lo = len / 2, hi = len;
        while (lo < hi)
        {
            int mid = (lo + hi + 1) / 2;
            fun(mid);

            if (resp == null || resp[1] > len)
                hi = mid - 1;
            else
                lo = mid;
        }

        fun(lo);

        center = resp[0] - 1;
        d = GetDistances(center);
        fun(len);
        Say(string.Format("! {0} {1}", center + 1, resp[0]));
        if (Listen() != "Correct")
            throw new Exception();
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());

#if DEBUG

        var solver = new Solver();
        for (int iter = 0; iter < 1000; iter++)
        {
            solver.Reset();
            try
            {
                solver.Solve();
            }
            catch (Exception ex)
            {
                Write(ex);
            }
        }
#else
        try
        {
            for (int tt = ReadInt(); tt > 0; tt--)
                new Solver().Solve();
        }
        catch (Exception ex)
        {
            throw;
        }
#endif
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0) currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++) matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++) ret[i][j] = matrix[j][i]; }
        return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++) lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array) writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++) ret[i] = new T(); return ret; }
    #endregion
}


using System;
using System.Collections.Generic;
using System.Linq;
using CompLib.Util;

public class Program
{
    public void Solve()
    {
        var sc = new Scanner();
        int t = sc.NextInt();
        for (int i = 0; i < t; i++)
        {
            Q(sc);
        }
    }

    private int N;
    private List<int>[] E;

    void Q(Scanner sc)
    {
        N = sc.NextInt();
        E = new List<int>[N];
        for (int i = 0; i < N; i++)
        {
            E[i] = new List<int>();
        }

        for (int i = 0; i < N - 1; i++)
        {
            int u = sc.NextInt() - 1;
            int v = sc.NextInt() - 1;
            E[u].Add(v);
            E[v].Add(u);
        }

        // 木
        // 2つnode選ばれる s,t

        // クエリ 11回まで ノードの集合aを聞く
        // 集合の内、dist(s, a_i) + dist(t, a_i) が最小になるnode,和を返す

        // s,tはどれか?

        // path s-t上を選ぶ
        // dist(s, t)

        // 適当な葉を聞く

        // 全部聞く
        // dist(s, t), s-t上の頂点
        int[] all = new int[N];
        for (int i = 0; i < N; i++)
        {
            all[i] = i;
        }

        int root, dist;
        (root, dist) = Query(all, sc);

        // rootを根にして、木をつくる

        // D 根からの距離、ノードのリスト
        var d1 = new List<List<int>>();

        Go(root, -1, 0, d1);

        int ok = (dist + 1) / 2;
        int ng = d1.Count;

        int d = ok;
        int s;
        (s, _) = Query(d1[ok].ToArray(), sc);
        while (ng - ok > 1)
        {
            int mid = (ok + ng) / 2;
            int node, sum;
            (node, sum) = Query(d1[mid].ToArray(), sc);
            if (sum == dist)
            {
                ok = mid;
                if (d < mid)
                {
                    d = mid;
                    s = node;
                }
            }
            else
            {
                ng = mid;
            }
        }

        // sが確定した
        // sから距離distの頂点

        List<List<int>> d2 = new List<List<int>>();
        Go(s, -1, 0, d2);

        int f;
        (f, _) = Query(d2[dist].ToArray(), sc);

        Console.WriteLine($"! {s + 1} {f + 1}");
        sc.Next();
    }

    void Go(int cur, int par, int depth, List<List<int>> d)
    {
        if (d.Count <= depth)
        {
            d.Add(new List<int>());
        }

        d[depth].Add(cur);
        foreach (int to in E[cur])
        {
            if (to == par) continue;
            Go(to, cur, depth + 1, d);
        }
    }

    (int node, int dist) Query(int[] ar, Scanner sc)
    {
        Console.WriteLine($"? {ar.Length} {string.Join(" ", ar.Select(i => i + 1))}");
        return (sc.NextInt() - 1, sc.NextInt());
    }

    public static void Main(string[] args) => new Program().Solve();
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s = Console.ReadLine();
                while (s.Length == 0)
                {
                    s = Console.ReadLine();
                }

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


#[allow(unused_imports)]
use std::cmp::{max, min};
use std::io::{stdin, stdout, BufWriter, Write};

#[derive(Default)]
struct Scanner {
buffer: Vec<String>,
}
impl Scanner {
	fn next<T: std::str::FromStr>(&mut self) -> T {
		loop {
			if let Some(token) = self.buffer.pop() {
				return token.parse().ok().expect("Failed parse");
			}
			let mut input = String::new();
			stdin().read_line(&mut input).expect("Failed read");
			self.buffer = input.split_whitespace().rev().map(String::from).collect();
		}
	}
}

fn dfs(p0: usize, p: usize, fat:usize, g: &Vec<Vec<usize> >, dist: &mut Vec<Vec<usize> > ){
	for i in g[p].iter() {
		if *i!=fat {
			dist[p0][*i]=dist[p0][p]+1;
			dfs(p0,*i,p,g,dist);
		}
	}
}

fn main() {
	let mut scan = Scanner::default();
	let out = &mut BufWriter::new(stdout());
	let t = scan.next::<u64>();
	for _ in 0..t {
		let n = scan.next::<usize>();
		let mut g = vec![Vec::<usize>::new();n];
		for _ in 1..n {
			let u = scan.next::<usize>()-1;
			let v = scan.next::<usize>()-1;
			g[u].push(v);
			g[v].push(u);
		}
		let mut dist = vec![vec![0usize;n];n];
		for i in 0..n {
			dfs(i,i,n,&g,&mut dist);
		}
		let mut q = Vec::<usize>::new();
		for i in 0..n {
			q.push(i+1);
		}
		write!(out,"? {}",q.len()).ok();
		for i in q.iter() {
			write!(out," {}",*i).ok();
		}
		q.clear();
		write!(out,"\n").ok();
		out.flush().unwrap();
		let mut u = scan.next::<usize>()-1;
		let d = scan.next::<usize>();
		let mut v = u;
		while dist[u][v] != d {
			for i in 0..n {
				if dist[u][i]+dist[v][i]!=dist[u][v] && min(dist[u][i],dist[v][i]) >= (1+d-dist[u][v])/2 {
					q.push(i+1);
				}
			}
			write!(out,"? {}",q.len()).ok();
			for i in q.iter() {
				write!(out," {}",*i).ok();
			}
			q.clear();
			write!(out,"\n").ok();
			out.flush().unwrap();
			let x = scan.next::<usize>()-1;
			if dist[x][u]<dist[x][v] {
				u=x;
			} else {
				v=x;
			}
			scan.next::<usize>();
		}
		writeln!(out,"! {} {}",u+1,v+1).ok();
		out.flush().unwrap();
	}
}


#[allow(unused_imports)]
use std::cmp::{max, min};
use std::io::{stdin, stdout, BufWriter, Write};

#[derive(Default)]
struct Scanner {
buffer: Vec<String>,
}
impl Scanner {
	fn next<T: std::str::FromStr>(&mut self) -> T {
		loop {
			if let Some(token) = self.buffer.pop() {
				return token.parse().ok().expect("Failed parse");
			}
			let mut input = String::new();
			stdin().read_line(&mut input).expect("Failed read");
			self.buffer = input.split_whitespace().rev().map(String::from).collect();
		}
	}
}

fn dfs(p0: usize, p: usize, fat:usize, g: &Vec<Vec<usize> >, dist: &mut Vec<Vec<usize> > ){
	for i in g[p].iter() {
		if *i!=fat {
			dist[p0][*i]=dist[p0][p]+1;
			dfs(p0,*i,p,g,dist);
		}
	}
}

fn main() {
	let mut scan = Scanner::default();
	let out = &mut BufWriter::new(stdout());
	let t = scan.next::<u64>();
	let mut q = Vec::<usize>::new();
	for _ in 0..t {
		let n = scan.next::<usize>();
		let mut g = vec![Vec::<usize>::new();n];
		for _ in 1..n {
			let u = scan.next::<usize>()-1;
			let v = scan.next::<usize>()-1;
			g[u].push(v);
			g[v].push(u);
		}
		let mut dist = vec![vec![0usize;n];n];
		for i in 0..n {
			dfs(i,i,n,&g,&mut dist);
		}

		for i in 0..n {
			q.push(i+1);
		}
		write!(out,"? {}",q.len()).ok();
		for i in q.iter() {
			write!(out," {}",*i).ok();
		}
		q.clear();
		write!(out,"\n").ok();
		out.flush().unwrap();
		let mut u = scan.next::<usize>()-1;
		let d = scan.next::<usize>();
		let mut v = u;

		while dist[u][v] != d {
			if dist[u][v] > d {
				loop {}
			}

			for i in 0..n {
				if dist[u][i]+dist[v][i]!=dist[u][v] && min(dist[u][i],dist[v][i]) >= (1+d-dist[u][v])/2 {
					q.push(i+1);
				}
			}
			write!(out,"? {}",q.len()).ok();
			for i in q.iter() {
				write!(out," {}",*i).ok();
			}
			q.clear();
			write!(out,"\n").ok();
			out.flush().unwrap();

			let cacca = scan.next::<i32>();
			if cacca==-1 {
				scan.next::<i32>();
				return;
			}
			let x = (cacca-1) as usize;

			if dist[x][u]<dist[x][v] {
				u=x;
			} else {
				v=x;
			}
			scan.next::<usize>();
		}
		writeln!(out,"! {} {}",u+1,v+1).ok();
		out.flush().unwrap();
		let s =scan.next::<String>();
		if s == "Incorrect" {
			return;
		}
	}
}


use std::io::Write;

fn read() -> Vec<usize> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().split_whitespace().map(|s| s.parse().unwrap()).collect()
}

fn solve() {
    let n = read()[0];
    let mut g = vec![vec![]; n];
    for _ in 1..n {
        let a = read();
        let x = a[0] - 1;
        let y = a[1] - 1;
        g[x].push(y);
        g[y].push(x);
    }
    let mut query_cnt = 0;
    let mut query = |v: &[usize]| -> (usize, u32) {
        assert!(query_cnt < 14);
        assert!(v.len() > 0);
        query_cnt += 1;
        let mut s = String::new();
        s.push_str(&format!("? {}", v.len()));
        for v in v.iter() {
            s.push_str(&format!(" {}", *v + 1));
        }
        println!("{}", s);
        std::io::stdout().flush().ok();
        let a = read();
        (a[0] - 1, a[1] as u32)
    };
    let ask = (0..n).collect::<Vec<_>>();
    let (mid, dis) = query(&ask);
    let mut dp = vec![0; n];
    let mut stack = vec![(mid, mid)];
    while let Some((v, p)) = stack.pop() {
        for &u in g[v].iter() {
            if u != p {
                dp[u] = dp[v] + 1;
                stack.push((u, v));
            }
        }
    }
    let mut ok = (0, mid);
    let mut ng = *dp.iter().max().unwrap();
    while ng - ok.0 > 1 {
        let m = (ok.0 + ng) / 2;
        let mut a = vec![];
        for (v, d) in dp.iter().enumerate() {
            if *d == m {
                a.push(v);
            }
        }
        let (x, w) = query(&a);
        if w == dis {
            ok = (m, x);
        } else {
            ng = m;
        }
    }
    let mut dp = vec![0; n];
    let mut stack = vec![(ok.1, ok.1)];
    while let Some((v, p)) = stack.pop() {
        for &u in g[v].iter() {
            if u != p {
                dp[u] = dp[v] + 1;
                stack.push((u, v));
            }
        }
    }
    let mut a = vec![];
    for (v, d) in dp.iter().enumerate() {
        if *d == dis {
            a.push(v);
        }
    }
    let (x, _) = query(&a);
    println!("! {} {}", x + 1, ok.1 + 1);
    std::io::stdout().flush().ok();
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    assert!(s.trim().eq("Correct"));
}

fn run() {
    let t = read()[0];
    for _ in 0..t {
        solve();
    }
}

fn main() {
    run();
}


use std::io::Write;

fn read() -> Vec<usize> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().split_whitespace().map(|s| s.parse().unwrap()).collect()
}

fn solve() {
    let n = read()[0];
    let mut g = vec![vec![]; n];
    for _ in 1..n {
        let a = read();
        let x = a[0] - 1;
        let y = a[1] - 1;
        g[x].push(y);
        g[y].push(x);
    }
    let mut query_cnt = 0;
    let mut query = |v: &[usize]| -> (usize, u32) {
        assert!(query_cnt < 14);
        assert!(v.len() > 0);
        query_cnt += 1;
        let mut s = String::new();
        s.push_str(&format!("? {}", v.len()));
        for v in v.iter() {
            s.push_str(&format!(" {}", *v + 1));
        }
        println!("{}", s);
        std::io::stdout().flush().ok();
        let a = read();
        (a[0] - 1, a[1] as u32)
    };
    let ask = (0..n).collect::<Vec<_>>();
    let (mid, dis) = query(&ask);
    let mut dp = vec![0; n];
    let mut stack = vec![(mid, mid)];
    while let Some((v, p)) = stack.pop() {
        for &u in g[v].iter() {
            if u != p {
                dp[u] = dp[v] + 1;
                stack.push((u, v));
            }
        }
    }
    let mut ok = (0, mid);
    let mut ng = dis + 1;
    while ng - ok.0 > 1 {
        let m = (ok.0 + ng) / 2;
        let mut a = vec![];
        for (v, d) in dp.iter().enumerate() {
            if *d == m {
                a.push(v);
            }
        }
        let (x, w) = query(&a);
        if w == dis {
            ok = (m, x);
        } else {
            ng = m;
        }
    }
    let mut dp = vec![0; n];
    let mut stack = vec![(ok.1, ok.1)];
    while let Some((v, p)) = stack.pop() {
        for &u in g[v].iter() {
            if u != p {
                dp[u] = dp[v] + 1;
                stack.push((u, v));
            }
        }
    }
    let mut a = vec![];
    for (v, d) in dp.iter().enumerate() {
        if *d == dis {
            a.push(v);
        }
    }
    let (x, _) = query(&a);
    println!("! {} {}", x + 1, ok.1 + 1);
    std::io::stdout().flush().ok();
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    assert!(s.trim().eq("Correct"));
}

fn run() {
    let t = read()[0];
    for _ in 0..t {
        solve();
    }
}

fn main() {
    run();
}


use std::io::Write;

fn read() -> Vec<usize> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().split_whitespace().map(|s| s.parse().unwrap()).collect()
}

fn solve() {
    let n = read()[0];
    let mut g = vec![vec![]; n];
    for _ in 1..n {
        let a = read();
        let x = a[0] - 1;
        let y = a[1] - 1;
        g[x].push(y);
        g[y].push(x);
    }
    let mut query_cnt = 0;
    let mut query = |v: &[usize]| -> (usize, u32) {
        assert!(query_cnt < 14);
        assert!(v.len() > 0);
        query_cnt += 1;
        let mut s = String::new();
        s.push_str(&format!("? {}", v.len()));
        for v in v.iter() {
            s.push_str(&format!(" {}", *v + 1));
        }
        println!("{}", s);
        std::io::stdout().flush().ok();
        let a = read();
        (a[0] - 1, a[1] as u32)
    };
    let ask = (0..n).collect::<Vec<_>>();
    let (mid, dis) = query(&ask);
    let mut dp = vec![0; n];
    let mut stack = vec![(mid, mid)];
    while let Some((v, p)) = stack.pop() {
        for &u in g[v].iter() {
            if u != p {
                dp[u] = dp[v] + 1;
                stack.push((u, v));
            }
        }
    }
    let mut ok = (0, mid);
    let mut ng = *dp.iter().max().unwrap() + 1;
    while ng - ok.0 > 1 {
        let m = (ok.0 + ng) / 2;
        let mut a = vec![];
        for (v, d) in dp.iter().enumerate() {
            if *d == m {
                a.push(v);
            }
        }
        let (x, w) = query(&a);
        if w == dis {
            ok = (m, x);
        } else {
            ng = m;
        }
    }
    let mut dp = vec![0; n];
    let mut stack = vec![(ok.1, ok.1)];
    while let Some((v, p)) = stack.pop() {
        for &u in g[v].iter() {
            if u != p {
                dp[u] = dp[v] + 1;
                stack.push((u, v));
            }
        }
    }
    let mut a = vec![];
    for (v, d) in dp.iter().enumerate() {
        if *d == dis {
            a.push(v);
        }
    }
    let (x, _) = query(&a);
    println!("! {} {}", x + 1, ok.1 + 1);
    std::io::stdout().flush().ok();
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    assert!(s.trim().eq("Correct"));
}

fn run() {
    let t = read()[0];
    for _ in 0..t {
        solve();
    }
}

fn main() {
    run();
}


use std::io::Write;

fn read() -> Vec<usize> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().split_whitespace().map(|s| s.parse().unwrap()).collect()
}

fn solve() {
    let n = read()[0];
    let mut g = vec![vec![]; n];
    for _ in 1..n {
        let a = read();
        let x = a[0] - 1;
        let y = a[1] - 1;
        g[x].push(y);
        g[y].push(x);
    }
    let mut query_cnt = 0;
    let mut query = |v: &[usize]| -> (usize, u32) {
        assert!(query_cnt < 14);
        query_cnt += 1;
        let mut s = String::new();
        s.push_str(&format!("? {}", v.len()));
        for v in v.iter() {
            s.push_str(&format!(" {}", *v + 1));
        }
        println!("{}", s);
        std::io::stdout().flush().ok();
        let a = read();
        (a[0] - 1, a[1] as u32)
    };
    let ask = (0..n).collect::<Vec<_>>();
    let (mid, dis) = query(&ask);
    let mut dp = vec![0; n];
    let mut stack = vec![(mid, mid)];
    while let Some((v, p)) = stack.pop() {
        for &u in g[v].iter() {
            if u != p {
                dp[u] = dp[v] + 1;
                stack.push((u, v));
            }
        }
    }
    let mut ok = (0, mid);
    let mut ng = dis + 1;
    while ng - ok.0 > 1 {
        let m = (ok.0 + ng) / 2;
        let mut a = vec![];
        for (v, d) in dp.iter().enumerate() {
            if *d == m {
                a.push(v);
            }
        }
        let (x, w) = query(&a);
        if w == dis {
            ok = (m, x);
        } else {
            ng = m;
        }
    }
    let mut dp = vec![0; n];
    let mut stack = vec![(ok.1, ok.1)];
    while let Some((v, p)) = stack.pop() {
        for &u in g[v].iter() {
            if u != p {
                dp[u] = dp[v] + 1;
                stack.push((u, v));
            }
        }
    }
    let mut a = vec![];
    for (v, d) in dp.iter().enumerate() {
        if *d == dis {
            a.push(v);
        }
    }
    let (x, _) = query(&a);
    println!("! {} {}", x + 1, ok.1 + 1);
    std::io::stdout().flush().ok();
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    assert!(s.trim().eq("Correct"));
}

fn run() {
    let t = read()[0];
    for _ in 0..t {
        solve();
    }
}

fn main() {
    run();
}


import sys
range = xrange
input = sys.stdin.readline

def query(A, state = -1):
    if not A:
        print state
        sys.exit()
    print '?', len(A), ' '.join(str(a + 1) for a in A)
    sys.stdout.flush()
    x,d = [int(x) for x in input().split()]
    return x - 1, d

def ans(x0, x1):
    print '!', x0 + 1, x1 + 1
    sys.stdout.flush()
    input()

def bfser(root, coupl):
    n = len(coupl)

    bfs = [root]
    depth = [-1] * n
    depth[root] = 0
    for node in bfs:
        for nei in coupl[node]:
            if depth[nei] == -1:
                depth[nei] = depth[node] + 1
                bfs.append(node)
    atdepth = [[] for _ in range(n)]
    for node in range(n):
        atdepth[depth[node]].append(node)
    return depth, atdepth

t = int(input())
for _ in range(t):
    n = int(input())
    coupl = [[] for _ in range(n)]
    for _ in range(n - 1):
        u,v = [int(x) - 1 for x in input().split()]
        coupl[u].append(v)
        coupl[v].append(u)
    leaves = [node for node in range(n) if len(coupl[node]) <= 1]

    y,d0 = query(list(range(n)))

    depth, atdepth = bfser(y, coupl)

    b = min(d0, max(depth[leaf] for leaf in leaves))
    a = min(d0 + 1 >> 1, b)
    while a < b:
        c = a + b + 1 >> 1
        x0, d = query(atdepth[c], -2)
        if d > d0:
            b = c - 1
        else:
            a = c

    x0,_ = query(atdepth[a], -3)

    depth, atdepth = bfser(x0, coupl)

    x1,_ = query(atdepth[d0], -4)

    ans(x0,x1)


import sys
range = xrange
input = sys.stdin.readline

def query(A):
    print '?', ' '.join(str(a + 1) for a in A)
    sys.stdout.flush()
    x,d = [int(x) for x in input().split()]
    return x - 1, d

t = int(input())
for _ in range(t):
    n = int(input())
    coupl = [[] for _ in range(n)]
    for _ in range(n - 1):
        u,v = [int(x) - 1 for x in input().split()]
        coupl[u].append(v)
        coupl[v].append(u)

    _,d0 = query(list(range(n)))

    leaves = [node for node in range(n) if len(coupl[node]) <= 1]

    depth = [-1]*n
    for node in leaves:
        depth[node] = 0
    bfs = list(leaves)
    for node in bfs:
        for nei in coupl[node]:
            if depth[nei] == -1:
                depth[nei] = depth[node] + 1
                bfs.append(nei)

    y,d = query(leaves)
    d -= d0
    while depth[y] != d:
        for nei in coupl[y]:
            if depth[nei] > depth[y]:
                y = nei
                break

     # y is one of the nodes on the path
     root = y
     bad = [0]*n
     while not all(bad[nei] for nei in coupl[root]):
        found2 = [0] * n
        P = [-1] * n
        bfs = [root]
        found2[root] = 1

        for node in bfs:
            for nei in coupl[node]:
                if not found2[nei] and not bad[nei]:
                    bfs.append(nei)
                    P[nei] = node
                    found2[nei] = 1

        children = [1]*n
        for node in reversed(bfs):
            if P[node] >= 0:
                children[P[node]] += children[node]

        besti = 0
        splitter = n + 1
        for node in bfs:
            val = 0
            if P[node] >= 0:
                val = max(val, children[bfs[0]] - children[node] + 1)
            for nei in coupl[node]:
                if nei != P[node] and not bad[nei]:
                    val = max(val, children[nei])
            if val < splitter:
                besti = i
                splitter = val

        B = []
        for nei in coupl[besti]:
            if nei != P[besti] and not bad[nei]:
                B.append(nei)
        x,d2 = query(B)
        if d0 == d2:
            bad[root] = 1
            root = x
        else:
            for nei in B:
                bad[nei] = 1

    print '!', y + 1, root + 1
    sys.stdout.flush()


import sys
range = xrange
input = sys.stdin.readline

def query(A):
    print '?', len(A), ' '.join(str(a + 1) for a in A)
    sys.stdout.flush()
    x,d = [int(x) for x in input().split()]
    return x - 1, d

def ans(x0, x1):
    print '!', x0 + 1, x1 + 1
    sys.stdout.flush()
    input()

def bfser(root, coupl):
    n = len(coupl)

    bfs = [root]
    depth = [-1] * n
    depth[root] = 0
    for node in bfs:
        for nei in coupl[node]:
            if depth[nei] == -1:
                depth[nei] = depth[node] + 1
                bfs.append(node)
    atdepth = [[] for _ in range(n)]
    for node in range(n):
        atdepth[depth[node]].append(node)
    return depth, atdepth

t = int(input())
for _ in range(t):
    n = int(input())
    coupl = [[] for _ in range(n)]
    for _ in range(n - 1):
        u,v = [int(x) - 1 for x in input().split()]
        coupl[u].append(v)
        coupl[v].append(u)
    leaves = [node for node in range(n) if len(coupl[node]) <= 1]

    y,d0 = query(list(range(n)))

    depth, atdepth = bfser(y, coupl)

    b = min(d0, max(depth[leaf] for leaf in leaves))
    a = min(d0 + 1 >> 1, b)
    while a < b:
        c = a + b + 1 >> 1
        x0, d = query(atdepth[c])
        if d > d0:
            b = c - 1
        else:
            a = c

    x0,_ = query(atdepth[a])

    depth, atdepth = bfser(x0, coupl)

    x1,_ = query(atdepth[d0])

    ans(x0,x1)


import sys
range = xrange
input = sys.stdin.readline

def query(A, state = -1):
    if not A:
        print state
        sys.exit()
    print '?', len(A), ' '.join(str(a + 1) for a in A)
    sys.stdout.flush()
    x,d = [int(x) for x in input().split()]
    return x - 1, d

def ans(x0, x1):
    print '!', x0 + 1, x1 + 1
    sys.stdout.flush()
    input()

def bfser(root, coupl):
    n = len(coupl)

    bfs = [root]
    depth = [-1] * n
    depth[root] = 0
    for node in bfs:
        for nei in coupl[node]:
            if depth[nei] == -1:
                depth[nei] = depth[node] + 1
                bfs.append(nei)
    atdepth = [[] for _ in range(n)]
    for node in range(n):
        atdepth[depth[node]].append(node)
    return depth, atdepth

t = int(input())
for _ in range(t):
    n = int(input())
    coupl = [[] for _ in range(n)]
    for _ in range(n - 1):
        u,v = [int(x) - 1 for x in input().split()]
        coupl[u].append(v)
        coupl[v].append(u)
    leaves = [node for node in range(n) if len(coupl[node]) <= 1]

    y,d0 = query(list(range(n)))

    depth, atdepth = bfser(y, coupl)

    b = min(d0, max(depth[leaf] for leaf in leaves))
    a = min(d0 + 1 >> 1, b)
    while a < b:
        c = a + b + 1 >> 1
        x0, d = query(atdepth[c], -2)
        if d > d0:
            b = c - 1
        else:
            a = c

    x0,_ = query(atdepth[a], -3)

    depth, atdepth = bfser(x0, coupl)

    x1,_ = query(atdepth[d0], -4)

    ans(x0,x1)


import sys
range = xrange
input = sys.stdin.readline

def query(A):
    print '?', ' '.join(str(a + 1) for a in A)
    sys.stdout.flush()
    x,d = [int(x) for x in input().split()]
    return x - 1, d

def ans(x0, x1):
    print '!', x0 + 1, x1 + 1
    sys.stdout.flush()
    input()

def bfser(root, coupl):
    n = len(coupl)

    bfs = [root]
    depth = [-1] * n
    depth[root] = 0
    for node in bfs:
        for nei in coupl[node]:
            if depth[nei] == -1:
                depth[nei] = depth[node] + 1
                bfs.append(node)
    atdepth = [[] for _ in range(n)]
    for node in range(n):
        atdepth[depth[node]].append(node)
    return depth, atdepth

t = int(input())
for _ in range(t):
    n = int(input())
    coupl = [[] for _ in range(n)]
    for _ in range(n - 1):
        u,v = [int(x) - 1 for x in input().split()]
        coupl[u].append(v)
        coupl[v].append(u)
    leaves = [node for node in range(n) if len(coupl[node]) <= 1]

    y,d0 = query(list(range(n)))

    depth, atdepth = bfser(y, coupl)

    a = max(d0 + 1 >> 1, min(depth[leaf] for leaf in leaves))
    b = min(d0, max(depth[leaf] for leaf in leaves))
    while a < b:
        c = a + b + 1 >> 1
        x0, d = query(atdepth[c])
        if d > d0:
            b = c - 1
        else:
            a = c

    x0,_ = query(atdepth[a])

    depth, atdepth = bfser(x0, coupl)

    x1,_ = query(atdepth[d0])

    ans(x0,x1)


import sys
range = xrange
input = sys.stdin.readline

def query(A):
    print '?', len(A), ' '.join(str(a + 1) for a in A)
    sys.stdout.flush()
    x,d = [int(x) for x in input().split()]
    return x - 1, d

def ans(x0, x1):
    print '!', x0 + 1, x1 + 1
    sys.stdout.flush()
    input()

def bfser(root, coupl):
    n = len(coupl)

    bfs = [root]
    depth = [-1] * n
    depth[root] = 0
    for node in bfs:
        for nei in coupl[node]:
            if depth[nei] == -1:
                depth[nei] = depth[node] + 1
                bfs.append(nei)
    atdepth = [[] for _ in range(n)]
    for node in range(n):
        atdepth[depth[node]].append(node)
    return depth, atdepth

t = int(input())
for _ in range(t):
    n = int(input())
    coupl = [[] for _ in range(n)]
    for _ in range(n - 1):
        u,v = [int(x) - 1 for x in input().split()]
        coupl[u].append(v)
        coupl[v].append(u)
    leaves = [node for node in range(n) if len(coupl[node]) <= 1]

    y,d0 = query(list(range(n)))

    depth, atdepth = bfser(y, coupl)

    b = min(d0, max(depth))
    a = min(d0 + 1 >> 1, b)
    ax0 = None
    while a < b:
        c = a + b + 1 >> 1
        x0, d = query(atdepth[c])
        if d > d0:
            b = c - (d - d0)
        else:
            a = c
            ax0 = x0

    if ax0 is None:
        x0,_ = query(atdepth[a])

    depth, atdepth = bfser(x0, coupl)

    x1,_ = query(atdepth[d0])

    ans(x0,x1)


import sys
range = xrange
input = sys.stdin.readline

def query(A):
    print '?', len(A), ' '.join(str(a + 1) for a in A)
    sys.stdout.flush()
    x,d = [int(x) for x in input().split()]
    return x - 1, d

def ans(x0, x1):
    print '!', x0 + 1, x1 + 1
    sys.stdout.flush()
    input()

def bfser(root, coupl):
    n = len(coupl)

    bfs = [root]
    depth = [-1] * n
    depth[root] = 0
    for node in bfs:
        for nei in coupl[node]:
            if depth[nei] == -1:
                depth[nei] = depth[node] + 1
                bfs.append(node)
    atdepth = [[] for _ in range(n)]
    for node in range(n):
        atdepth[depth[node]].append(node)
    return depth, atdepth

t = int(input())
for _ in range(t):
    n = int(input())
    coupl = [[] for _ in range(n)]
    for _ in range(n - 1):
        u,v = [int(x) - 1 for x in input().split()]
        coupl[u].append(v)
        coupl[v].append(u)
    leaves = [node for node in range(n) if len(coupl[node]) <= 1]

    y,d0 = query(list(range(n)))

    depth, atdepth = bfser(y, coupl)

    a = max(d0 + 1 >> 1, min(depth[leaf] for leaf in leaves))
    b = min(d0, max(depth[leaf] for leaf in leaves))
    while a < b:
        c = a + b + 1 >> 1
        x0, d = query(atdepth[c])
        if d > d0:
            b = c - 1
        else:
            a = c

    x0,_ = query(atdepth[a])

    depth, atdepth = bfser(x0, coupl)

    x1,_ = query(atdepth[d0])

    ans(x0,x1)


import sys
range = xrange
input = sys.stdin.readline

def query(A):
    print '?', len(A), ' '.join(str(a + 1) for a in A)
    sys.stdout.flush()
    x,d = [int(x) for x in input().split()]
    return x - 1, d

def ans(x0, x1):
    print '!', x0 + 1, x1 + 1
    sys.stdout.flush()
    input()

def bfser(root, coupl):
    n = len(coupl)

    bfs = [root]
    depth = [-1] * n
    depth[root] = 0
    for node in bfs:
        for nei in coupl[node]:
            if depth[nei] == -1:
                depth[nei] = depth[node] + 1
                bfs.append(nei)
    atdepth = [[] for _ in range(n)]
    for node in range(n):
        atdepth[depth[node]].append(node)
    return depth, atdepth

t = int(input())
for _ in range(t):
    n = int(input())
    coupl = [[] for _ in range(n)]
    for _ in range(n - 1):
        u,v = [int(x) - 1 for x in input().split()]
        coupl[u].append(v)
        coupl[v].append(u)
    leaves = [node for node in range(n) if len(coupl[node]) <= 1]

    y,d0 = query(list(range(n)))

    depth, atdepth = bfser(y, coupl)

    b = min(d0, max(depth))
    a = min(d0 + 1 >> 1, b)
    ax0 = None
    while a < b:
        c = a + b + 1 >> 1
        x0, d = query(atdepth[c])
        if d > d0:
            b = c - 1
        else:
            a = c
            ax0 = x0

    if ax0 is None:
        x0,_ = query(atdepth[a])
    else:
        x0 = ax0

    depth, atdepth = bfser(x0, coupl)

    x1,_ = query(atdepth[d0])

    ans(x0,x1)


import sys
from collections import deque

def debug(*args):
    return
    global t
    print("\033[0;31m", end="", file=sys.stderr)
    print(t, *args, file=sys.stderr)
    print("\033[0m", end="", file=sys.stderr)
    sys.stderr.flush()

def query(nodes):
    print(
        "?", len(nodes), " ".join(map(str, nodes)), file=sys.stdout,
    )
    sys.stdout.flush()

    result = input().strip()
    while not result:
        result = input().strip()
    result = [int(x) for x in result.split(" ")]

    debug("Query:", nodes, "\tResult:", result)
    return result

def solve(N, edges):
    def bfs(source, getNbr):
        q = deque([source])
        dist = {source: 0}
        while q:
            node = q.popleft()
            d = dist[node]
            for nbr in getNbr(node):
                if nbr not in dist:
                    q.append(nbr)
                    dist[nbr] = d + 1
        return dist

    graph = [[] for i in range(N + 1)]
    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)

    def getNbr(u):
        return graph[u]

    # Query for all nodes first
    # This gives us a node on the path between node1 and node2 and the distance between them
    # Any subsequent queries containing nodes on the path will return the same dist
    root, pathDist = query(list(range(1, N + 1)))

    # Root the tree and group the nodes based on their levels
    dist = bfs(root, getNbr)

    # Binary search to find the node that is farther away from root
    node1 = None
    # lo = pathDist // 2  # the farther node is at least pathDist/2 away
    lo = 1
    hi = min(pathDist, max(dist.values()))
    while lo <= hi:
        mid = (lo + hi) // 2
        results = query([k for k, v in dist.items() if v == mid])
        if results[1] == pathDist:
            lo = mid + 1
            if not node1 or dist[node1] < dist[results[0]]:
                node1 = results[0]
        else:
            hi = mid - 1

    # Then know node2 must be pathDist away
    dist = bfs(node1, getNbr)
    node2 = query([k for k, v in dist.items() if v == pathDist])[0]

    print("! " + str(node1) + " " + str(node2), file=sys.stdout)
    sys.stdout.flush()

    result = input().strip()
    while not result:
        result = input().strip()
    assert result == "Correct"

if __name__ == "__main__":
    T = int(input())
    for t in range(T):
        (N,) = [int(x) for x in input().split()]
        edges = [[int(x) for x in input().split()] for i in range(N - 1)]  # 1-indexed
        solve(N, edges)


import sys
from collections import deque

def debug(*args):
    return
    global t
    print("\033[0;31m", end="", file=sys.stderr)
    print(t, *args, file=sys.stderr)
    print("\033[0m", end="", file=sys.stderr)
    sys.stderr.flush()

def query(nodes):
    print(
        "?", len(nodes), " ".join(map(str, nodes)), file=sys.stdout,
    )
    sys.stdout.flush()

    result = input().strip()
    while not result:
        result = input().strip()
    result = [int(x) for x in result.split(" ")]

    debug("Query:", nodes, "\tResult:", result)
    return result

def solve(N, edges):
    def bfs(source, getNbr):
        q = deque([source])
        dist = {source: 0}
        while q:
            node = q.popleft()
            d = dist[node]
            for nbr in getNbr(node):
                if nbr not in dist:
                    q.append(nbr)
                    dist[nbr] = d + 1
        return dist

    graph = [[] for i in range(N + 1)]
    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)

    def getNbr(u):
        return graph[u]

    # Query for all nodes first
    # This gives us a node on the path between node1 and node2 and the distance between them
    # Any subsequent queries containing nodes on the path will return the same dist
    root, pathDist = query(list(range(1, N + 1)))

    # Root the tree and group the nodes based on their levels
    dist = bfs(root, getNbr)

    # Binary search to find the node that is farther away from root
    node1 = None
    lo = pathDist // 2  # the farther node is at least pathDist/2 away
    hi = min(pathDist, max(dist.values()))
    while lo <= hi:
        mid = (lo + hi) // 2
        results = query([k for k, v in dist.items() if v == mid])
        if results[1] == pathDist:
            lo = mid + 1
            node1 = results[0]
        else:
            hi = mid - 1

    # Then know node2 must be pathDist away
    dist = bfs(node1, getNbr)
    node2 = query([k for k, v in dist.items() if v == pathDist])[1]

    print("! " + str(node1) + " " + str(node2), file=sys.stdout)
    sys.stdout.flush()

    result = input().strip()
    while not result:
        result = input().strip()
    assert result == "Correct"

if __name__ == "__main__":
    T = int(input())
    for t in range(T):
        (N,) = [int(x) for x in input().split()]
        edges = [[int(x) for x in input().split()] for i in range(N - 1)]  # 1-indexed
        solve(N, edges)


import sys
input = sys.stdin.readline
inputr = lambda: input().rstrip('\n')

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

for _ in range(int(input())):
	n = int(input())
	adj = [[] for _ in range(n)]
	for _ in range(n-1):
		u, v = map(int, input().split())
		u -= 1
		v -= 1
		adj[u].append(v)
		adj[v].append(u)

	root, tdist = query(range(n))

	D = [-1] * n
	D[root] = 0
	Q = [root]
	while Q:
		i = Q.pop()
		for j in adj[i]:
			if D[j] == -1:
				D[j] = D[i] + 1
				Q.append(j)

	lo = 0
	hi = n #tdist//2 + 1
	first = -1
	while lo < hi:
		m = (lo + hi) // 2

		q = [i for i in range(n) if D[i] == m]
		if not q:
			hi = m
			continue

		r, d = query(q)
		if d == tdist:
			first = r
			lo = m + 1
		else:
			hi = m

	assert first != -1

	V = [False] * n
	q = []
	V[first] = True
	Q = [(first, 0)]
	while Q:
		i, d = Q.pop()
		if d == tdist:
			q.append(i)
		else:
			for j in adj[i]:
				if not V[j]:
					V[j] = True
					Q.append((j, d+1))

	print('!', first+1, query(q)[0]+1, flush=True)
	assert inputr() == 'Correct'


mod = 1000000007
eps = 10**-9

def main():
    import sys
    from collections import deque
    input = sys.stdin.readline

    debug = 0

    def ask(A):
        if debug:
            aa = 0
            d = 10000
            for a in A:
                if ds[a] + dt[a] < d:
                    d = ds[a] + dt[a]
                    aa = a
            return aa, d
        else:
            query = ["?", len(A)]
            query.extend(A)
            print(*query)
            sys.stdout.flush()
            a, d = map(int, input().split())
            if a == d == -1:
                exit()
            return a, d

    for _ in range(int(input())):
        N = int(input())
        adj = [[] for _ in range(N+1)]
        for _ in range(N-1):
            a, b = map(int, input().split())
            adj[a].append(b)
            adj[b].append(a)
        if debug:
            s, t = map(int, input().split())
            ds = [-1] * (N+1)
            que = deque()
            que.append(s)
            ds[s] = 0
            while que:
                v = que.popleft()
                for u in adj[v]:
                    if ds[u] == -1:
                        que.append(u)
                        ds[u] = ds[v] + 1
            dt = [-1] * (N + 1)
            que.append(t)
            dt[t] = 0
            while que:
                v = que.popleft()
                for u in adj[v]:
                    if dt[u] == -1:
                        que.append(u)
                        dt[u] = dt[v] + 1
        v0, d = ask(list(range(1, N+1)))
        que = deque()
        que.append(v0)
        dist = [-1] * (N+1)
        dist[v0] = 0
        par = [0] * (N+1)
        while que:
            v = que.popleft()
            for u in adj[v]:
                if dist[u] == -1:
                    dist[u] = dist[v]+1
                    que.append(u)
                    par[u] = v
        dist_list = [[] for _ in range(N + 1)]
        for v in range(1, N+1):
            dist_list[dist[v]].append(v)
        v1 = v0
        seen = [0] * (N+1)
        seen[v0] = 1
        while d:
            dd = (d+1) // 2
            A = []
            for u in dist_list[dist[v0] + dd]:
                if not seen[u]:
                    A.append(u)
            if v0 != v1:
                for u in dist_list[dist[v1] + dd]:
                    if not seen[u]:
                        A.append(u)
            a, _ = ask(A)
            aa = a
            for _ in range(dd):
                seen[aa] = 1
                aa = par[aa]
            if aa == v0:
                v0 = a
            else:
                v1 = a
            d -= dd
        print(*["!", v0, v1])
        sys.stdout.flush()
        verdict = input().rstrip('\n')
        if verdict == "Incorrect":
            exit()

if __name__ == '__main__':
    main()


from sys import stdout
from queue import Queue
t = int(input())
for _ in range(t):
	n = int(input())
	G = [[] for i in range(n)]
	for i in range(n - 1):
		v, u = map(int, input().split())
		v -= 1; u -= 1;
		G[v].append(u)
		G[u].append(v)
	dep = [0] * n

	def dfs(v, pr):
		for u in G[v]:
			if (u != pr):
				dep[u] = dep[v] + 1
				dfs(u, v)

	dfs(0, 0)
	print("?", n, *list(range(1, n + 1)))
	stdout.flush()
	tmp, dist = map(int, input().split())
	max_dep = max(dep)
	R = max_dep + 1; L = 0
	while R - L > 1:
		mid = (L + R) // 2
		vers = []
		for i in range(n):
			if dep[i] >= mid:
				vers.append(i + 1)
		print("?", len(vers), *vers)
		stdout.flush()
		tmp, cur_dist = map(int, input().split())
		if cur_dist == dist:
			L = mid
		else:
			R = mid
	vers = []
	for i in range(n):
		if dep[i] == L:
			vers.append(i + 1)
	print("?", len(vers), *vers);
	stdout.flush()
	v, tmp = map(int, input().split())
	v -= 1
	q = Queue()
	dist_v = [2 * n] * n
	dist_v[v] = 0
	q.put(v)
	while not q.empty():
		cur = q.get()
		for u in G[cur]:
			if dist_v[u] > dist_v[cur] + 1:
				dist_v[u] = dist_v[cur] + 1
				q.put(u)
	vers = []
	for i in range(n):
		if dist_v[i] == dist:
			vers.append(i + 1)
	print("?", len(vers), *vers)
	stdout.flush()
	u, tmp = map(int, input().split())
	u -= 1
	print("!", u + 1, v + 1)
	stdout.flush()
	tmp = input()


from sys import stdout
from queue import Queue
t = int(input())
for _ in range(t):
	n = int(input())
	G = [[] for i in range(n)]
	for i in range(n - 1):
		v, u = map(int, input().split())
		v -= 1; u -= 1;
		G[v].append(u)
		G[u].append(v)
	dep = [0] * n

	def dfs(v, pr):
		for u in G[v]:
			if (u != pr):
				dep[u] = dep[v] + 1
				dfs(u, v)

	dfs(0, 0)
	print("?", n, *list(range(1, n + 1)))
	stdout.flush()
	tmp, dist = map(int, input().split())
	max_dep = max(dep)
	v = 0
	R = max_dep + 1; L = 0
	while R - L > 1:
		mid = (L + R) // 2
		vers = []
		for i in range(n):
			if dep[i] >= mid:
				vers.append(i + 1)
		print("?", len(vers), *vers)
		stdout.flush()
		tmp, cur_dist = map(int, input().split())
		if cur_dist == dist:
			L = mid
			v = tmp
		else:
			R = mid
	v -= 1
	q = Queue()
	dist_v = [2 * n] * n
	dist_v[v] = 0
	q.put(v)
	while not q.empty():
		cur = q.get()
		for u in G[cur]:
			if dist_v[u] > dist_v[cur] + 1:
				dist_v[u] = dist_v[cur] + 1
				q.put(u)
	vers = []
	for i in range(n):
		if dist_v[i] == dist:
			vers.append(i + 1)
	print("?", len(vers), *vers)
	stdout.flush()
	u, tmp = map(int, input().split())
	u -= 1
	print("!", u + 1, v + 1)
	stdout.flush()
	tmp = input()


from sys import stdout
from queue import Queue
import random
t = int(input())
for _ in range(t):
	n = int(input())
	G = [[] for i in range(n)]
	for i in range(n - 1):
		v, u = map(int, input().split())
		v -= 1; u -= 1;
		G[v].append(u)
		G[u].append(v)
	dep = [0] * n

	def dfs(v, pr):
		for u in G[v]:
			if (u != pr):
				dep[u] = dep[v] + 1
				dfs(u, v)

	dfs(random.randint(0, n - 1), -1)
	print("?", n, *list(range(1, n + 1)))
	stdout.flush()
	tmp, dist = map(int, input().split())
	max_dep = max(dep)
	v = 0
	R = max_dep + 1; L = 0
	while R - L > 1:
		mid = (L + R) // 2
		vers = []
		for i in range(n):
			if dep[i] >= mid:
				vers.append(i + 1)
		print("?", len(vers), *vers)
		stdout.flush()
		tmp, cur_dist = map(int, input().split())
		if cur_dist == dist:
			L = mid
			v = tmp
		else:
			R = mid
	v -= 1
	q = Queue()
	dist_v = [2 * n] * n
	dist_v[v] = 0
	q.put(v)
	while not q.empty():
		cur = q.get()
		for u in G[cur]:
			if dist_v[u] > dist_v[cur] + 1:
				dist_v[u] = dist_v[cur] + 1
				q.put(u)
	vers = []
	for i in range(n):
		if dist_v[i] == dist:
			vers.append(i + 1)
	print("?", len(vers), *vers)
	stdout.flush()
	u, tmp = map(int, input().split())
	u -= 1
	print("!", u + 1, v + 1)
	stdout.flush()
	tmp = input()


import sys
input = sys.stdin.readline
inputr = lambda: input().rstrip('\n')

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

for _ in range(int(input())):
	n = int(input())
	adj = [[] for _ in range(n)]
	for _ in range(n-1):
		u, v = map(int, input().split())
		u -= 1
		v -= 1
		adj[u].append(v)
		adj[v].append(u)

	root, tdist = query(range(n))

	D = [-1] * n
	D[root] = 0
	Q = [root]
	while Q:
		i = Q.pop()
		for j in adj[i]:
			if D[j] == -1:
				D[j] = D[i] + 1
				Q.append(j)

	lo = 0
	hi = tdist//2 + 1
	first = -1
	while lo < hi:
		m = (lo + hi) // 2

		r, d = query([i for i in range(n) if D[i] == m])
		if d == tdist:
			first = r
			lo = m + 1
		else:
			hi = m

	assert first != -1

	q = {i for i in range(n) if D[i] == tdist-D[first]}
	q.discard(first)

	print('!', first+1, query(q)[0]+1, flush=True)
	assert inputr() == 'Correct'


import sys
input = sys.stdin.readline
inputr = lambda: input().rstrip('\n')

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

for _ in range(int(input())):
	n = int(input())
	adj = [[] for _ in range(n)]
	for _ in range(n-1):
		u, v = map(int, input().split())
		u -= 1
		v -= 1
		adj[u].append(v)
		adj[v].append(u)

	root, tdist = query(range(n))

	D = [-1] * n
	D[root] = 0
	Q = [root]
	while Q:
		i = Q.pop()
		for j in adj[i]:
			if D[j] == -1:
				D[j] = D[i] + 1
				Q.append(j)

	lo = 0
	hi = tdist//2 + 1
	first = -1
	while lo < hi:
		m = (lo + hi) // 2

		q = [i for i in range(n) if D[i] == m]
		if not q:
			hi = m
			continue

		r, d = query(q)
		if d == tdist:
			first = r
			lo = m + 1
		else:
			hi = m

	assert first != -1

	q = {i for i in range(n) if D[i] == tdist-D[first]}
	q.discard(first)
	assert q

	print('!', first+1, query(q)[0]+1, flush=True)
	assert inputr() == 'Correct'


import sys
input = sys.stdin.readline
inputr = lambda: input().rstrip('\n')

def query(l):
	print('?', len(l), ' '.join(map(lambda v: str(v+1), l)), flush=True)
	x, d = map(int, input().split())
	assert x != -1
	return x-1, d

for _ in range(int(input())):
	n = int(input())
	adj = [[] for _ in range(n)]
	for _ in range(n-1):
		u, v = map(int, input().split())
		u -= 1
		v -= 1
		adj[u].append(v)
		adj[v].append(u)

	root, tdist = query(range(n))

	D = [-1] * n
	D[root] = 0
	Q = [root]
	while Q:
		i = Q.pop()
		for j in adj[i]:
			if D[j] == -1:
				D[j] = D[i] + 1
				Q.append(j)

	lo = 0
	hi = tdist//2 + 1
	first = -1
	while lo < hi:
		m = (lo + hi) // 2

		q = [i for i in range(n) if D[i] == m]
		if not q:
			hi = m
			continue

		r, d = query(q)
		if d == tdist:
			first = r
			lo = m + 1
		else:
			hi = m

	assert first != -1

	q = {i for i in range(n) if D[i] == tdist-D[first]}
	q.discard(first)
	assert q

	print('!', first+1, query(q)[0]+1, flush=True)
	assert inputr() == 'Correct'