#include <bits/stdc++.h>
using namespace std;
int n, x, y;
vector<int> vrh, nevrh, isto, razl;
int binarna(int l, int d, int sol, vector<int> koji) {
  if (l > d) return koji[sol];
  int mid = (l + d) / 2;
  printf("? %d ", mid + 1);
  for (int i = 0; i <= mid; i++) printf("%d ", koji[i]);
  fflush(stdout);
  int t;
  scanf("%d", &t);
  if (t == y || (t == (x ^ y))) {
    return binarna(l, mid - 1, mid, koji);
  }
  return binarna(mid + 1, d, sol, koji);
}
int gde;
int main() {
  scanf("%d %d %d", &n, &x, &y);
  for (int i = 1; i < 1000; i <<= 1) {
    vrh.clear();
    nevrh.clear();
    for (int j = 1; j <= n; j++) {
      if (j & i)
        vrh.push_back(j);
      else
        nevrh.push_back(j);
    }
    if (vrh.empty()) {
      isto.push_back(i);
      continue;
    }
    printf("? %d ", vrh.size());
    for (auto x : vrh) printf("%d ", x);
    fflush(stdout);
    int t;
    scanf("%d", &t);
    if (t == x || t == 0) {
      isto.push_back(i);
    } else {
      razl.push_back(i);
      if (gde) continue;
      if (vrh.size() < nevrh.size())
        gde = binarna(0, vrh.size() - 1, -1, vrh);
      else
        gde = binarna(0, nevrh.size() - 1, -1, nevrh);
    }
  }
  int drugi = 0;
  for (auto x : isto) drugi += x & gde;
  for (auto x : razl) drugi += (x & gde) ^ x;
  printf("! %d %d", min(gde, drugi), max(gde, drugi));
  fflush(stdout);
  return 0;
}
