#include <bits/stdc++.h>   using namespace std;   const int MAXN = 610;   int n;   int anc[MAXN], depth[MAXN];   bool mark[MAXN];   vector<int> adj[MAXN];   vector<int> partitions[2];   map<vector<int>, int> ans;   queue<int> q;   int qtdEdges(vector<int> a) {     if (a.empty()) return 0;     sort(a.begin(), a.end());     if (ans[a] == 0) {       cout <<  ?   << (int)a.size() <<    ;       for (int i = 0; i < (int)a.size(); i++) cout << a[i] <<    ;       cout << endl;       cin >> ans[a];       ans[a]++;     }     return ans[a] - 1;   }   int qtdCrossEdges(vector<int> A, vector<int> B) {     vector<int> merge;     for (int i = 0; i < (int)A.size(); i++) merge.push_back(A[i]);     for (int i = 0; i < (int)B.size(); i++) merge.push_back(B[i]);     return qtdEdges(merge) - qtdEdges(A) - qtdEdges(B);   }   void add(int node, int p) {     q.push(node);     mark[node] = true;     anc[node] = p;     depth[node] = depth[p] + 1;     partitions[depth[node] % 2].push_back(node);   }   void findEdges(int root, vector<int> nodes, int qtd) {     if (qtd == 0) return;     if (nodes.empty()) return;     if ((int)nodes.size() == 1) {       add(nodes.front(), root);       return;     }     int sz = (int)nodes.size();     int m = sz / 2;     vector<int> leftNodes, rightNodes;     for (int i = 0; i < m; i++) leftNodes.push_back(nodes[i]);     for (int i = m; i < (int)nodes.size(); i++) rightNodes.push_back(nodes[i]);     findEdges(root, leftNodes, qtdCrossEdges(vector<int>(1, root), leftNodes));     findEdges(root, rightNodes, qtdCrossEdges(vector<int>(1, root), rightNodes));   }   int findEndpoint(vector<int> L, vector<int> R) {     if ((int)L.size() == 1) return L.front();     int sz = (int)L.size();     int m = sz / 2;     vector<int> leftNodes, rightNodes;     for (int i = 0; i < m; i++) leftNodes.push_back(L[i]);     for (int i = m; i < (int)L.size(); i++) rightNodes.push_back(L[i]);     if (qtdCrossEdges(leftNodes, R) != 0) return findEndpoint(leftNodes, R);     return findEndpoint(rightNodes, R);   }   void findBadEdge(vector<int> nodes, int& A, int& B) {     if (nodes.empty()) return;     int sz = (int)nodes.size();     int m = sz / 2;     vector<int> leftNodes, rightNodes;     for (int i = 0; i < m; i++) leftNodes.push_back(nodes[i]);     for (int i = m; i < (int)nodes.size(); i++) rightNodes.push_back(nodes[i]);     if (qtdEdges(leftNodes) != 0) {       findBadEdge(leftNodes, A, B);       return;     }     if (qtdEdges(rightNodes) != 0) {       findBadEdge(rightNodes, A, B);       return;     }     A = findEndpoint(leftNodes, rightNodes);     B = findEndpoint(rightNodes, vector<int>(1, A));   }   int main() {     cin >> n;     for (int i = 1; i <= n; i++) {       vector<int> aux(1, i);       ans[aux] = 1;     }     add(1, 0);     while (!q.empty()) {       vector<int> remain;       for (int i = 1; i <= n; i++)         if (!mark[i]) remain.push_back(i);       int cur = q.front();       q.pop();       findEdges(cur, remain, qtdCrossEdges(vector<int>(1, cur), remain));     }     int bad = -1;     for (int i = 0; i < 2; i++)       if (qtdEdges(partitions[i]) != 0) bad = i;     if (bad == -1) {       cout <<  Y   << (int)partitions[0].size() << endl;       for (int i = 0; i < (int)partitions[0].size(); i++)         cout << partitions[0][i] <<    ;       cout << endl;       return 0;     }     int A, B;     findBadEdge(partitions[bad], A, B);     if (depth[A] > depth[B]) swap(A, B);     vector<int> pathA, pathB;     while (depth[A] != depth[B]) pathB.push_back(B), B = anc[B];     while (A != B) {       pathA.push_back(A);       A = anc[A];       pathB.push_back(B);       B = anc[B];     }     pathA.push_back(A);     cout <<  N   << (int)pathA.size() + (int)pathB.size() << endl;     for (int i = 0; i < (int)pathA.size(); i++) cout << pathA[i] <<    ;     for (int i = (int)pathB.size() - 1; i >= 0; i--) cout << pathB[i] <<    ;     cout << endl;   }