#include #include #include #include using namespace std; int solve(const vector> &V) { static map>, int> M; if (M.count(V)) return M[V]; if (V.size() == 0) return 0; vector>> transition(V.size()); vector mex; for (int i = 0; i < (int)V.size(); i++) for (int j = 0; j < (int)V[i].size(); ++j) if (V[i][j]) { for (int k = -1; k < j; ++k) { auto U = V[i]; U[j]--; if(k != -1)U[k]++; if (U.back() == 0) U.pop_back(); sort(U.begin(), U.end()); transition[i].push_back(U); } } int tot = 1; for(auto x: transition) tot *= x.size(); for(int y = 1; y> U; int ny = y; for(auto x: transition) { vector tar = x[ny % x.size()]; if(!tar.empty()) U.push_back(tar); ny /= x.size(); } sort(U.begin(), U.end()); mex.push_back(solve(U)); } sort(mex.begin(), mex.end()); mex.erase(unique(mex.begin(), mex.end()), mex.end()); for (int i = 0; i < (int)mex.size(); ++i) if (mex[i] != i) return M[V] = i; return M[V] = mex.size(); } int nimber(int x) { map M; if (M.count(x)) return M[x]; map> C; // add C_(p^k) auto add = [&](int p, int k) { if (!C.count(p)) C[p] = {}; if ((int)C[p].size() < k) C[p].resize(k); C[p][k - 1]++; }; // adds C_n auto add_n = [&](int n) { for (int p = 2; p * p <= n; p++) if (n % p == 0) { int k = 0; while (n % p == 0) { n /= p; ++k; } add(p, k); } if (n != 1) add(n, 1); }; // Divide into cyclic group // Z^{2^k} divides into C^{2} * C^{2^{k-2}} int k = 0; while (x %2 == 0) x /= 2, ++k; if (k > 1) add(2, 1); if (k > 2) add(2, k - 2); for (int p = 3; p * p <= x; p += 2) { if (x % p == 0) { x /= p; add_n(p - 1); int k = 0; while (x % p != 0) { x /= p; ++k; } add(p, k); } } if (x != 1) add(x, 1); vector> cyc; for (auto [a, b] : C) cyc.push_back(b); sort(cyc.begin(), cyc.end()); /*for(auto x: cyc) { for(auto y: x) cout << y << " "; cout << endl; }*/ return M[x] = solve(cyc); } int main() { int N; cin >> N; int a = 0; while (N--) { int k; cin >> k; a ^= nimber(k); } if(a) cout << "Y\n"; else cout << "X\n"; }