#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <functional>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#if defined(_WIN32)
#include <windows.h>
#include <psapi.h>
#else
#include "sys/time.h"
#endif
namespace OY {
#define cin OY::inputHelper<1024, 20>::getInstance()
#define getchar() ({char c=cin.getChar_Checked();cin.next();c;})
#define cout OY::outputHelper<1048576>::getInstance()
#define putchar cout.putChar
#define endl '\n'
#define putlog(...) OY::printLog(", ", __VA_ARGS__)
template <uint64_t _BufferSize = 1024, uint64_t _BlockSize = 20>
class inputHelper {
FILE *m_filePtr;
char m_buf[_BufferSize], *m_end, *m_cursor;
bool m_ok;
void flush() {
uint64_t a = m_end - m_cursor;
if (a >= _BlockSize)
return;
memmove(m_buf, m_cursor, a);
uint64_t b = fread(m_buf + a, 1, _BufferSize - a, m_filePtr);
m_cursor = m_buf;
if (a + b < _BufferSize) {
m_end = m_buf + a + b;
*m_end = EOF;
}
}
public:
explicit inputHelper(const char *inputFileName) : m_ok(true) {
if (!*inputFileName)
m_filePtr = stdin;
else
m_filePtr = fopen(inputFileName, "rt");
m_end = m_cursor = m_buf + _BufferSize;
}
~inputHelper() {
fclose(m_filePtr);
}
static inputHelper<_BufferSize, _BlockSize> &getInstance() {
#ifdef OY_LOCAL
static inputHelper<_BufferSize, _BlockSize> s_obj("in.txt");
#else
static inputHelper<_BufferSize, _BlockSize> s_obj("");
#endif
return s_obj;
}
static constexpr bool isBlank(char c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\r';
}
static constexpr bool isEndline(char c) {
return c == '\n' || c == EOF;
}
const char &getChar_Checked() {
if (m_cursor < m_end)
return *m_cursor;
uint64_t b = fread(m_buf, 1, _BufferSize, m_filePtr);
m_cursor = m_buf;
if (b < _BufferSize) {
m_end = m_buf + b;
*m_end = EOF;
}
return *m_cursor;
}
const char &getChar_Unchecked() const {
return *m_cursor;
}
void next() {
++m_cursor;
}
void setState(bool _ok) {
m_ok = _ok;
}
template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
inputHelper<_BufferSize, _BlockSize> &operator>>(_Tp &ret) {
while (isBlank(getChar_Checked()))
next();
flush();
if (getChar_Unchecked() == '-') {
next();
if (isdigit(getChar_Unchecked())) {
ret = -(getChar_Unchecked() - '0');
while (next(), isdigit(getChar_Unchecked()))
ret = ret * 10 - (getChar_Unchecked() - '0');
} else
m_ok = false;
} else {
if (isdigit(getChar_Unchecked())) {
ret = getChar_Unchecked() - '0';
while (next(), isdigit(getChar_Unchecked()))
ret = ret * 10 + (getChar_Unchecked() - '0');
} else
m_ok = false;
}
return *this;
}
template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
inputHelper<_BufferSize, _BlockSize> &operator>>(_Tp &ret) {
while (isBlank(getChar_Checked()))
next();
flush();
if (isdigit(getChar_Unchecked())) {
ret = getChar_Unchecked() - '0';
while (next(), isdigit(getChar_Unchecked()))
ret = ret * 10 + (getChar_Unchecked() - '0');
} else
m_ok = false;
return *this;
}
template <typename _Tp, std::enable_if_t<std::is_floating_point_v<_Tp>> * = nullptr>
inputHelper<_BufferSize, _BlockSize> &operator>>(_Tp &ret) {
bool neg = false, integer = false, decimal = false;
while (isBlank(getChar_Checked()))
next();
flush();
if (getChar_Unchecked() == '-') {
neg = true;
next();
}
if (!isdigit(getChar_Unchecked()) && getChar_Unchecked() != '.') {
m_ok = false;
return *this;
}
if (isdigit(getChar_Unchecked())) {
integer = true;
ret = getChar_Unchecked() - '0';
while (next(), isdigit(getChar_Unchecked()))
ret = ret * 10 + (getChar_Unchecked() - '0');
}
if (getChar_Unchecked() == '.') {
next();
if (isdigit(getChar_Unchecked())) {
if (!integer)
ret = 0;
decimal = true;
_Tp unit = 0.1;
ret += unit * (getChar_Unchecked() - '0');
while (next(), isdigit(getChar_Unchecked())) {
unit *= 0.1;
ret += unit * (getChar_Unchecked() - '0');
}
}
}
if (!integer && !decimal)
m_ok = false;
else if (neg)
ret = -ret;
return *this;
}
inputHelper<_BufferSize, _BlockSize> &operator>>(char &ret) {
while (isBlank(getChar_Checked()))
next();
ret = getChar_Checked();
next();
return *this;
}
inputHelper<_BufferSize, _BlockSize> &operator>>(std::string &ret) {
while (isBlank(getChar_Checked()))
next();
if (getChar_Checked() != EOF) {
ret.clear();
do {
ret += getChar_Checked();
next();
} while (!isBlank(getChar_Checked()) && getChar_Unchecked() != EOF);
} else
m_ok = false;
return *this;
}
explicit operator bool() {
return m_ok;
}
};
template <uint64_t _BufferSize = 1048576>
class outputHelper {
FILE *m_filePtr = nullptr;
char m_buf[_BufferSize], *m_end, *m_cursor;
char m_tempBuf[50], *m_tempBufCursor, *m_tempBufDot;
uint64_t m_floatReserve, m_floatRatio;
public:
outputHelper(const char *outputFileName, int prec = 6) : m_end(m_buf + _BufferSize) {
if (!*outputFileName)
m_filePtr = stdout;
else
m_filePtr = fopen(outputFileName, "wt");
m_cursor = m_buf;
m_tempBufCursor = m_tempBuf;
precision(prec);
}
static outputHelper<_BufferSize> &getInstance() {
#ifdef OY_LOCAL
static outputHelper<_BufferSize> s_obj("out.txt");
#else
static outputHelper<_BufferSize> s_obj("");
#endif
return s_obj;
}
~outputHelper() {
flush();
fclose(m_filePtr);
}
void precision(int prec) {
m_floatReserve = prec;
m_floatRatio = pow(10, prec);
m_tempBufDot = m_tempBuf + prec;
}
outputHelper<_BufferSize> &flush() {
fwrite(m_buf, 1, m_cursor - m_buf, m_filePtr);
fflush(m_filePtr);
m_cursor = m_buf;
return *this;
}
void putChar(const char &c) {
if (m_cursor == m_end)
flush();
*m_cursor++ = c;
}
void putS(const char *c) {
while (*c)
putChar(*c++);
}
template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
outputHelper<_BufferSize> &operator<<(const _Tp &ret) {
_Tp _ret = _Tp(ret);
if (_ret >= 0) {
do {
*m_tempBufCursor++ = '0' + _ret % 10;
_ret /= 10;
} while (_ret);
do
putChar(*--m_tempBufCursor);
while (m_tempBufCursor > m_tempBuf);
} else {
putChar('-');
do {
*m_tempBufCursor++ = '0' - _ret % 10;
_ret /= 10;
} while (_ret);
do
putChar(*--m_tempBufCursor);
while (m_tempBufCursor > m_tempBuf);
}
return *this;
}
template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
outputHelper<_BufferSize> &operator<<(const _Tp &ret) {
_Tp _ret = _Tp(ret);
do {
*m_tempBufCursor++ = '0' + _ret % 10;
_ret /= 10;
} while (_ret);
do
putChar(*--m_tempBufCursor);
while (m_tempBufCursor > m_tempBuf);
return *this;
}
template <typename _Tp, std::enable_if_t<std::is_floating_point_v<_Tp>> * = nullptr>
outputHelper<_BufferSize> &operator<<(const _Tp &ret) {
if (ret < 0) {
putChar('-');
return *this << -ret;
}
_Tp _ret = ret * m_floatRatio;
uint64_t integer = _ret;
if (_ret - integer >= 0.4999999999)
integer++;
do {
*m_tempBufCursor++ = '0' + integer % 10;
integer /= 10;
} while (integer);
if (m_tempBufCursor > m_tempBufDot) {
do
putChar(*--m_tempBufCursor);
while (m_tempBufCursor > m_tempBufDot);
putChar('.');
} else {
putS("0.");
for (int i = m_tempBufDot - m_tempBufCursor; i--;)
putChar('0');
}
do
putChar(*--m_tempBufCursor);
while (m_tempBufCursor > m_tempBuf);
return *this;
}
outputHelper<_BufferSize> &operator<<(const char &ret) {
putChar(ret);
return *this;
}
outputHelper<_BufferSize> &operator<<(const std::string &ret) {
putS(ret.data());
return *this;
}
};
template <uint64_t _BufferSize, uint64_t _BlockSize>
inputHelper<_BufferSize, _BlockSize> &getline(inputHelper<_BufferSize, _BlockSize> &ih, std::string &ret) {
ret.clear();
if (ih.getChar_Checked() == EOF)
ih.setState(0);
else {
while (!inputHelper<_BufferSize, _BlockSize>::isEndline(ih.getChar_Checked())) {
ret += ih.getChar_Unchecked();
ih.next();
}
ih.next();
}
return ih;
}
template <typename D, typename T, typename... S>
void printLog(D delim, const T &x, S... rest) {
cout << x;
if constexpr(sizeof...(rest) > 0) {
cout << delim;
printLog(delim, rest...);
}
}
}
using OY::getline;
namespace OY {
template <typename _ModType>
struct Barrett {
_ModType m_P;
__uint128_t m_Pinv;
constexpr Barrett() = default;
constexpr explicit Barrett(_ModType __P) : m_P(__P), m_Pinv(-uint64_t(__P) / __P + 1) {}
constexpr _ModType mod() const {
return m_P;
}
constexpr _ModType mod(uint64_t __a) const {
__a -= uint64_t(m_Pinv * __a >> 64) * m_P + m_P;
if (__a >= m_P)
__a += m_P;
return __a;
}
constexpr _ModType raw_mod(uint64_t __a) const {
return __a % m_P;
}
constexpr _ModType multiply(uint64_t __a, uint64_t __b) const {
return mod(__a * __b);
}
constexpr _ModType multiply_128(uint64_t __a, uint64_t __b) const {
if (__builtin_clzll(__a) + __builtin_clzll(__b) >= 64)
return multiply(__a, __b);
return __uint128_t(__a) * __b % m_P;
}
constexpr _ModType multiply_ld(uint64_t __a, uint64_t __b) const {
if (__builtin_clzll(__a) + __builtin_clzll(__b) >= 64)
return multiply(__a, __b);
int64_t res = __a * __b - uint64_t(1.L / m_P * __a * __b) * m_P;
if (res < 0)
res += m_P;
else if (res >= m_P)
res -= m_P;
return res;
}
constexpr _ModType pow(uint64_t __a, uint64_t __n) const {
_ModType res = 1, b = mod(__a);
while (__n) {
if (__n & 1)
res = multiply(res, b);
b = multiply(b, b);
__n >>= 1;
}
return res;
}
constexpr _ModType pow_128(uint64_t __a, uint64_t __n) const {
_ModType res = 1, b = mod(__a);
while (__n) {
if (__n & 1)
res = multiply_128(res, b);
b = multiply_128(b, b);
__n >>= 1;
}
return res;
}
constexpr _ModType pow_ld(uint64_t __a, uint64_t __n) const {
_ModType res = 1, b = mod(__a);
while (__n) {
if (__n & 1)
res = multiply_ld(res, b);
b = multiply_ld(b, b);
__n >>= 1;
}
return res;
}
template <typename _Tp>
constexpr _Tp divide(_Tp __a) const {
if (__a < m_P)
return 0;
_Tp res = m_Pinv * __a >> 64;
if (__a - res * m_P >= m_P)
res++;
return res;
}
template <typename _Tp>
constexpr std::pair<_Tp, _Tp> divmod(_Tp __a) const {
_Tp quo = (__a * m_Pinv) >> 64, rem = __a - quo * m_P;
if (rem >= m_P) {
quo++;
rem -= m_P;
}
return {quo, rem};
}
};
using Barrett32 = Barrett<uint32_t>;
using Barrett64 = Barrett<uint64_t>;
}
namespace OY {
template <typename _ModType>
struct _MontgomeryTag;
template <>
struct _MontgomeryTag<uint32_t> {
using long_type = uint64_t;
static constexpr uint32_t limit = (1073741824u) - 1;
static constexpr uint32_t inv_loop = 4;
static constexpr uint32_t length = 32;
};
template <>
struct _MontgomeryTag<uint64_t> {
using long_type = __uint128_t;
static constexpr uint64_t limit = (1ull << 63) - 1;
static constexpr uint32_t inv_loop = 5;
static constexpr uint32_t length = 64;
};
template <typename _ModType>
struct Montgomery {
using _FastType = _ModType;
using _LongType = typename _MontgomeryTag<_ModType>::long_type;
_ModType m_P;
_ModType m_Pinv;
_ModType m_Ninv;
Barrett<_ModType> m_brt;
constexpr Montgomery() = default;
constexpr explicit Montgomery(_ModType __P) : m_P(__P), m_Pinv(__P), m_Ninv(-_LongType(__P) % __P),
m_brt(__P) {
assert((__P & 1) && __P > 1 && __P <= _MontgomeryTag<_ModType>::limit);
for (uint32_t i = 0; i < _MontgomeryTag<_ModType>::inv_loop; i++)
m_Pinv *= _ModType(2) - __P * m_Pinv;
}
constexpr _ModType mod() const {
return m_brt.mod();
}
constexpr _ModType mod(uint64_t __a) const {
return m_brt.mod(__a);
}
constexpr _ModType raw_mod(uint64_t __a) const {
return m_brt.raw_mod(__a);
}
constexpr _FastType init(uint64_t __a) const {
return reduce(_LongType(mod(__a)) * m_Ninv);
}
constexpr _FastType raw_init(uint64_t __a) const {
return reduce(_LongType(raw_mod(__a)) * m_Ninv);
}
constexpr _FastType reduce(_LongType __a) const {
_FastType res = (__a >> _MontgomeryTag<_ModType>::length) - _ModType(_LongType(_ModType(
__a) * m_Pinv) * m_P >> _MontgomeryTag<_ModType>::length);
if (res >= mod())
res += mod();
return res;
}
constexpr _ModType reduce(_FastType __a) const {
_ModType res = -_ModType(_LongType(__a * m_Pinv) * m_P >> _MontgomeryTag<_ModType>::length);
if (res >= mod())
res += mod();
return res;
}
constexpr _FastType multiply(_FastType __a, _FastType __b) const {
return reduce(_LongType(__a) * __b);
}
constexpr _FastType pow(_FastType __a, uint64_t __n) const {
_FastType res = reduce(_LongType(1) * m_Ninv);
while (__n) {
if (__n & 1)
res = multiply(res, __a);
__a = multiply(__a, __a);
__n >>= 1;
}
return res;
}
template <typename _Tp>
constexpr _Tp divide(_Tp __a) const {
return m_brt.divide(__a);
}
template <typename _Tp>
constexpr std::pair<_Tp, _Tp> divmod(_Tp __a) const {
return m_brt.divmod(__a);
}
};
using Montgomery32 = Montgomery<uint32_t>;
using Montgomery64 = Montgomery<uint64_t>;
}
namespace OY {
template <typename _Elem>
constexpr bool isPrime(_Elem n) {
if (std::is_same_v<_Elem, uint32_t> || n <= UINT32_MAX) {
if (n <= 1)
return false;
if (n == 2 || n == 7 || n == 61)
return true;
if (n % 2 == 0)
return false;
Barrett32 brt(n);
uint32_t d = (n - 1) >> __builtin_ctz(n - 1);
for (auto &&a : {
2, 7, 61
}) {
uint32_t s = d, y = brt.pow(a, s);
while (s != n - 1 && y != 1 && y != n - 1) {
y = brt.multiply(y, y);
s <<= 1;
}
if (y != n - 1 && s % 2 == 0)
return false;
}
return true;
} else {
// assert(n < 1ull < 63);
if (n % 2 == 0)
return false;
Montgomery64 mg(n);
uint64_t d = (n - 1) >> __builtin_ctzll(n - 1), one = mg.init(1);
for (auto &&a : {
2, 325, 9375, 28178, 450775, 9780504, 1795265022
}) {
uint64_t s = d, y = mg.pow(mg.init(a), s), t = mg.init(n - 1);
while (s != n - 1 && y != one && y != t) {
y = mg.multiply(y, y);
s <<= 1;
}
if (y != t && s % 2 == 0)
return false;
}
return true;
}
}
constexpr auto isPrime32 = isPrime<uint32_t>;
constexpr auto isPrime64 = isPrime<uint64_t>;
}
int main() {
uint64_t x;
while (cin >> x && x) {
if (OY::isPrime(x))
cout << "Y";
else
cout << "N";
cout << endl;
}
}