#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N = 100010;
const int MX = 123456;
const int mod = (int)1e9 + 7;
const int base = 97;
const unsigned long long BS1 = 10000019ULL;
const int INF = (1 << 29);
template <class T>
inline void fastScan(T &x) {
  register char c = getchar();
  int neg = 0;
  x = 0;
  for (; (c < 48 || c > 57) && (c != '-'); c = getchar())
    ;
  if (c == '-') {
    neg = 1;
    c = getchar();
  }
  for (; c > 47 && c < 58; c = getchar()) {
    x = (x << 1) + (x << 3) + c - 48;
  }
  if (neg) x = -x;
}
int n, k;
int mxInd, mxVal;
int prob;
char s[15];
int Ans[1234];
vector<int> vec[1234], ques;
void doFlash() { fflush(stdout); }
int askQ() {
  printf("?");
  doFlash();
  printf(" %d", ques.size());
  doFlash();
  for (int i = 0; i < ques.size(); i++) {
    printf(" %d", ques[i]);
    doFlash();
  }
  printf("\n");
  doFlash();
  int ans;
  fastScan(ans);
  return ans;
}
void go(int l, int r) {
  if (l > r) return;
  if (l == r) {
    mxInd = l;
    return;
  }
  int lft = 0, rgt = 0;
  int mid = (l + r) / 2;
  ques.clear();
  for (int i = l; i <= mid; i++) {
    ques.push_back(i);
  }
  if (ques.size() > 0) lft = askQ();
  if (lft == mxVal) {
    go(l, mid);
  } else {
    go(mid + 1, r);
  }
}
void print() {
  printf("!");
  doFlash();
  for (int i = 1; i <= k; i++) {
    printf(" %d", Ans[i]);
    doFlash();
  }
  printf("\n");
  doFlash();
  scanf("%s", s);
}
int main() {
  int tt;
  fastScan(tt);
  while (tt--) {
    fastScan(n);
    fastScan(k);
    for (int i = 0; i <= n; i++) {
      vec[i].clear();
    }
    for (int i = 1; i <= k; i++) {
      int sz;
      fastScan(sz);
      for (int j = 1; j <= sz; j++) {
        int x;
        fastScan(x);
        vec[i].push_back(x);
      }
    }
    ques.clear();
    for (int i = 1; i <= n; i++) {
      ques.push_back(i);
    }
    mxVal = askQ();
    go(1, n);
    prob = 0;
    for (int i = 1; i <= k; i++) {
      int have = 0;
      for (int j = 0; j < vec[i].size(); j++) {
        if (vec[i][j] == mxInd) {
          have = 1;
          break;
        }
      }
      if (have == 0) {
        Ans[i] = mxVal;
      } else {
        prob = i;
      }
    }
    if (prob > 0) {
      ques.clear();
      sort(vec[prob].begin(), vec[prob].end());
      for (int i = 1, j = 0; i <= n; i++) {
        if (j < vec[prob].size() && (i == vec[prob][j])) {
          j++;
          continue;
        }
        ques.push_back(i);
      }
      mxVal = askQ();
      Ans[prob] = mxVal;
    }
    print();
  }
  return 0;
}
