#include <bits/stdc++.h>
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ld = long double;
using vi = std::vector<int>;
using pii = std::pair<int, int>;
using vvi = std::vector<vi>;
using vii = std::vector<pii>;
using vll = std::vector<ll>;
using pll = std::pair<ll, ll>;
template <typename T>
int sign(const T& t) {
  return (t > 0) - (t < 0);
}
template <typename T, typename U>
bool remax(T& a, U b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T, typename U>
bool remin(T& a, U b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
T gcd(T a, T b) {
  a = std::abs(a);
  b = std::abs(b);
  while (b) {
    a %= b;
    std::swap(a, b);
  }
  return a;
}
template <typename T>
T lcm(T a, T b) {
  a = std::abs(a);
  b = std::abs(b);
  return a / gcd(a, b) * b;
}
double get_time() { return static_cast<double>(clock()) / CLOCKS_PER_SEC; }
uint32_t mrand_32t() {
  static std::random_device rd;
  static std::mt19937 rng(rd());
  return rng();
}
uint64_t mrand_64t() {
  static std::random_device rd;
  static std::mt19937_64 rng(rd());
  return rng();
}
template <typename T>
void make_unique(std::vector<T>& v) {
  std::sort(std::begin(v), std::end(v));
  v.erase(std::unique(std::begin(v), std::end(v)), std::end(v));
}
namespace std {
template <typename A, typename B>
string to_string(const pair<A, B>& p) {
  string str;
  str += "(";
  str += to_string(p.first);
  str += ", ";
  str += to_string(p.second);
  str += ")";
  return str;
}
string to_string(bool value) { return value ? "true" : "false"; }
template <typename T>
string to_string(const vector<T>& vec) {
  string str = "{ ";
  bool first = true;
  for (const auto& it : vec) {
    if (!first) {
      str += ", ";
    }
    str += to_string(it);
    first = false;
  }
  str += " }";
  return str;
}
template <typename T>
string to_string(const set<T>& s) {
  string str = "{ ";
  bool first = true;
  for (const auto& it : s) {
    if (!first) {
      str += ", ";
    }
    str += to_string(it);
    first = false;
  }
  str += " }";
  return str;
}
template <typename K, typename V>
string to_string(const map<K, V>& m) {
  string str = "{ ";
  bool first = true;
  for (const auto& it : m) {
    if (!first) {
      str += ", ";
    }
    first = false;
    str += to_string(it.first);
    str += " -> ";
    str += to_string(it.second);
  }
  str += " }";
  return str;
}
string to_string(const string& s) { return "\"" + s + "\""; }
string to_string(const char* s) { return to_string(string(s)); }
string to_string(char ch) { return "\'" + string(1, ch) + "\'"; }
template <size_t N>
string to_string(const bitset<N>& b) {
  string res(N, '0');
  for (size_t i = 0; i < N; ++i) {
    res[i] = '0' + b[i];
  }
  return res;
}
template <typename T>
string to_string(const T& t) {
  std::stringstream ss;
  ss << t;
  return ss.str();
}
}  // namespace std
void debug_out() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  std::cerr << " " << std::to_string(H);
  debug_out(T...);
}
using namespace std;
int n;
bool read() {
  if (!(cin >> n)) {
    return 0;
  }
  return 1;
}
int ask(vi vs) {
  cout << "? " << int((vs).size()) << endl;
  for (int v : vs) {
    cout << v + 1 << " ";
  }
  cout << endl;
  int m;
  cin >> m;
  if (m == -1) {
    exit(0);
  }
  return m;
}
struct Ans {
  bool ok;
  vi vs;
  void print() const {
    if (ok) {
      cout << "Y ";
    } else {
      cout << "N ";
    }
    cout << int((vs).size()) << endl;
    for (int v : vs) {
      cout << v + 1 << " ";
    }
    cout << endl;
  }
};
void append(vi& a, const vi& b) {
  for (const auto& x : b) {
    a.push_back(x);
  }
}
vi merge(const vi& a, const vi& b) {
  vi c = a;
  append(c, b);
  return c;
}
Ans solve() {
  const auto get_edge = [&](const vi& vs, int v) {
    {
      vi cur = vs;
      cur.push_back(v);
      if (ask(cur) == 0) {
        return -1;
      }
    }
    int L = -1;
    int R = int((vs).size());
    while (L != R - 1) {
      int M = (L + R) / 2;
      auto cur = vi(vs.begin(), vs.begin() + (M + 1));
      cur.push_back(v);
      if (ask(cur) > 0) {
        R = M;
      } else {
        L = M;
      }
    }
    if (R == int((vs).size())) {
      return -1;
    }
    return vs.at(R);
  };
  vvi g(n);
  const function<bool(int, int, vi&, vi&)> dfs = [&](int v, int want, vi& was,
                                                     vi& path) -> bool {
    assert(!was[v]);
    was[v] = 1;
    path.push_back(v);
    if (v == want) {
      return 1;
    }
    for (int u : g[v]) {
      if (!was[u]) {
        if (dfs(u, want, was, path)) {
          return 1;
        }
      }
    }
    assert(path.back() == v);
    path.pop_back();
    return 0;
  };
  const auto addE = [&](int v, int u) {
    if (v == -1 || u == -1) {
      return;
    }
    g[v].push_back(u);
    g[u].push_back(v);
  };
  vi left___;
  vi right___;
  left___.push_back(0);
  vi used(n, 0);
  used[0] = 1;
  vi pref;
  while (1) {
    vi rest;
    for (int v = int(0); v < int(n); ++v) {
      if (!used[v]) {
        rest.push_back(v);
      }
    }
    if (rest.empty()) {
      break;
    }
    vi lr = left___;
    append(lr, right___);
    const int base = ask(lr);
    int L = -1;
    int R = int((rest).size());
    while (L != R - 1) {
      int M = (L + R) / 2;
      const int old = int((lr).size());
      append(lr, vi(rest.begin(), rest.begin() + (M + 1)));
      int xxx = ask(vi(rest.begin(), rest.begin() + (M + 1)));
      if (ask(lr) > base + xxx) {
        R = M;
      } else {
        L = M;
      }
      lr.resize(old);
    }
    if (R == int((rest).size())) {
      append(pref, left___);
      left___.clear();
      right___.clear();
      const int v = rest.at(0);
      used[v] = 1;
      left___.push_back(v);
      continue;
    }
    const int v = rest.at(R);
    used[v] = 1;
    int Lv = get_edge(left___, v);
    int Rv = get_edge(right___, v);
    if (Lv != -1 && Rv != -1) {
      vi was(n, 0);
      vi path;
      bool found = dfs(Lv, Rv, was, path);
      assert(found);
      path.push_back(v);
      return Ans{false, path};
    }
    addE(Lv, v);
    addE(Rv, v);
    if (Lv != -1) {
      right___.push_back(v);
    } else if (Rv != -1) {
      left___.push_back(v);
    } else {
      assert(0);
    }
  }
  append(pref, left___);
  return Ans{true, pref};
}
int main() {
  read();
  auto ans = solve();
  ans.print();
  return 0;
}
