#include<bits/stdc++.h>
#define FOR(i, a, b) for (int i = (a), _b = (b); i <= _b; i++)
#define FORD(i, b, a) for (int i = (b), _a = (a); i >= _a; i--)
#define REP(i, n) for (int i = 0, _n = (n); i < _n; i++)
#define FORE(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); i++)
#define ALL(v) (v).begin(), (v).end()
#define IS_INF(x) (std::isinf(x))
#define IS_NAN(x) (std::isnan(x))
#define fi first
#define se second
#define MASK(i) (1LL << (i))
#define BIT(x, i) (((x) >> (i)) & 1)
#define div ___div
#define next ___next
#define prev ___prev
#define left ___left
#define right ___right
#define __builtin_popcount __builtin_popcountll
using namespace std;
template<class X, class Y>
bool minimize(X &x, const Y &y) {
X eps = 1e-9;
if (x > y + eps) {
x = y;
return true;
} else return false;
}
template<class X, class Y>
bool maximize(X &x, const Y &y) {
X eps = 1e-9;
if (x + eps < y) {
x = y;
return true;
} else return false;
}
template<class T>
T Abs(const T &x) {
return (x < 0 ? -x : x);
}
/* Author: Van Hanh Pham */
/** END OF TEMPLATE - ACTUAL SOLUTION COMES HERE **/
#define HEXA_MASK(i) MASK((i) << 2)
#define HEXA_DIGIT(x, i) (((x) >> ((i) << 2)) & 15)
#define CLEAR_HEXA_DIGIT(x, i) ((x) & ~(15 << ((i) << 2)))
#define SET_HEXA_DIGIT(x, i, d) (CLEAR_HEXA_DIGIT(x, i) ^ ((d) << ((i) << 2)))
#define LENGTH 5
#define BLANK 10
#define VALUE 100100
vector<int> primes[LENGTH + 1][HEXA_MASK(LENGTH) + 1];
bool notPrime[VALUE];
// least significant digit in x becomes most significant digit in the hexa code
int toHexa(int x, int numDigit) {
int res = 0;
REP(love, numDigit) {
res = (res << 4) ^ (x % 10);
x /= 10;
}
return x > 0 ? -1 : res;
}
void prepare(void) {
REP(i, 2) notPrime[i] = true;
FOR(i, 2, VALUE - 1) if (!notPrime[i]) for (int j = 2 * i; j < VALUE; j += i) notPrime[j] = true;
FOR(i, 2, VALUE - 1) if (!notPrime[i]) FOR(length, 1, LENGTH) {
int code = toHexa(i, length);
if (code < 0) continue;
REP(mask, MASK(length)) {
int newCode = code;
REP(i, length) if (BIT(mask, i)) newCode = SET_HEXA_DIGIT(newCode, i, BLANK);
primes[length][newCode].push_back(code);
}
}
}
int res;
void backtrack(vector<int> &state, int filled) {
int numRow = state.size();
if (__builtin_popcount(filled) == numRow) {
res++;
return;
}
int row = -1, numCandidate = VALUE;
if (!BIT(filled, numRow - 1)) {
row = numRow - 1;
numCandidate = primes[numRow][state[row]].size();
} else {
REP(i, numRow) if (!BIT(filled, i)) {
int tmpCandidate = primes[numRow][state[i]].size();
if (minimize(numCandidate, tmpCandidate)) row = i;
}
}
if (numCandidate == 0) return;
if (__builtin_popcount(filled) == numRow - 1) {
res += numCandidate;
return;
}
int oldState = state[row];
vector<int> &candidates = primes[numRow][oldState];
FORE(it, candidates) {
REP(j, numRow) {
// state[row][j] = state[j][row] = HEXA_DIGIT(*it, j)
state[row] = SET_HEXA_DIGIT(state[row], j, HEXA_DIGIT(*it, j));
state[j] = SET_HEXA_DIGIT(state[j], row, HEXA_DIGIT(*it, j));
}
backtrack(state, filled | MASK(row));
}
state[row] = oldState;
REP(i, numRow) state[i] = SET_HEXA_DIGIT(state[i], row, HEXA_DIGIT(oldState, i));
}
int numDigit(int x) {
return x < 10 ? 1 : numDigit(x / 10) + 1;
}
int solve(int x) {
int numRow = numDigit(x);
int code = toHexa(x, numRow);
vector<int> state(numRow, 0);
REP(i, numRow) REP(j, numRow) // state[i][j] = BLANK
state[i] = SET_HEXA_DIGIT(state[i], j, BLANK);
REP(i, numRow) {
// state[0][i] = state[i][0] = HEXA_DIGIT(code, i)
state[0] = SET_HEXA_DIGIT(state[0], i, HEXA_DIGIT(code, i));
state[i] = SET_HEXA_DIGIT(state[i], 0, HEXA_DIGIT(code, i));
}
res = 0;
backtrack(state, MASK(0));
return res;
}
int main(void) {
#ifdef ONLINE_JUDGE
freopen("primetable.inp", "r", stdin);
freopen("primetable.out", "w", stdout);
#endif // ONLINE_JUDGE
prepare();
int t; scanf("%d", &t);
REP(love, t) {
int x; scanf("%d", &x);
printf("%d ", solve(x));
}
printf("\n");
return 0;
}
/*** LOOK AT MY CODE. MY CODE IS AMAZING :D ***/
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KI2RlZmluZSBGT1IoaSwgYSwgYikgZm9yIChpbnQgaSA9IChhKSwgX2IgPSAoYik7IGkgPD0gX2I7IGkrKykKI2RlZmluZSBGT1JEKGksIGIsIGEpIGZvciAoaW50IGkgPSAoYiksIF9hID0gKGEpOyBpID49IF9hOyBpLS0pCiNkZWZpbmUgUkVQKGksIG4pIGZvciAoaW50IGkgPSAwLCBfbiA9IChuKTsgaSA8IF9uOyBpKyspCiNkZWZpbmUgRk9SRShpLCB2KSBmb3IgKF9fdHlwZW9mKCh2KS5iZWdpbigpKSBpID0gKHYpLmJlZ2luKCk7IGkgIT0gKHYpLmVuZCgpOyBpKyspCiNkZWZpbmUgQUxMKHYpICh2KS5iZWdpbigpLCAodikuZW5kKCkKI2RlZmluZSBJU19JTkYoeCkgICAoc3RkOjppc2luZih4KSkKI2RlZmluZSBJU19OQU4oeCkgICAoc3RkOjppc25hbih4KSkKI2RlZmluZSBmaSAgIGZpcnN0CiNkZWZpbmUgc2UgICBzZWNvbmQKI2RlZmluZSBNQVNLKGkpICgxTEwgPDwgKGkpKQojZGVmaW5lIEJJVCh4LCBpKSAoKCh4KSA+PiAoaSkpICYgMSkKI2RlZmluZSBkaXYgICBfX19kaXYKI2RlZmluZSBuZXh0ICAgX19fbmV4dAojZGVmaW5lIHByZXYgICBfX19wcmV2CiNkZWZpbmUgbGVmdCAgIF9fX2xlZnQKI2RlZmluZSByaWdodCAgIF9fX3JpZ2h0CiNkZWZpbmUgX19idWlsdGluX3BvcGNvdW50IF9fYnVpbHRpbl9wb3Bjb3VudGxsCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnRlbXBsYXRlPGNsYXNzIFgsIGNsYXNzIFk+CiAgICBib29sIG1pbmltaXplKFggJngsIGNvbnN0IFkgJnkpIHsKICAgICAgICBYIGVwcyA9IDFlLTk7CiAgICAgICAgaWYgKHggPiB5ICsgZXBzKSB7CiAgICAgICAgICAgIHggPSB5OwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGVsc2UgcmV0dXJuIGZhbHNlOwogICAgfQp0ZW1wbGF0ZTxjbGFzcyBYLCBjbGFzcyBZPgogICAgYm9vbCBtYXhpbWl6ZShYICZ4LCBjb25zdCBZICZ5KSB7CiAgICAgICAgWCBlcHMgPSAxZS05OwogICAgICAgIGlmICh4ICsgZXBzIDwgeSkgewogICAgICAgICAgICB4ID0geTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHJldHVybiBmYWxzZTsKICAgIH0KdGVtcGxhdGU8Y2xhc3MgVD4KICAgIFQgQWJzKGNvbnN0IFQgJngpIHsKICAgICAgICByZXR1cm4gKHggPCAwID8gLXggOiB4KTsKICAgIH0KCi8qIEF1dGhvcjogVmFuIEhhbmggUGhhbSAqLwoKLyoqIEVORCBPRiBURU1QTEFURSAtIEFDVFVBTCBTT0xVVElPTiBDT01FUyBIRVJFICoqLwoKI2RlZmluZSBIRVhBX01BU0soaSkgTUFTSygoaSkgPDwgMikKI2RlZmluZSBIRVhBX0RJR0lUKHgsIGkpICgoKHgpID4+ICgoaSkgPDwgMikpICYgMTUpCiNkZWZpbmUgQ0xFQVJfSEVYQV9ESUdJVCh4LCBpKSAoKHgpICYgfigxNSA8PCAoKGkpIDw8IDIpKSkKI2RlZmluZSBTRVRfSEVYQV9ESUdJVCh4LCBpLCBkKSAoQ0xFQVJfSEVYQV9ESUdJVCh4LCBpKSBeICgoZCkgPDwgKChpKSA8PCAyKSkpCgojZGVmaW5lIExFTkdUSCAgIDUKI2RlZmluZSBCTEFOSyAgIDEwCiNkZWZpbmUgVkFMVUUgICAxMDAxMDAKdmVjdG9yPGludD4gcHJpbWVzW0xFTkdUSCArIDFdW0hFWEFfTUFTSyhMRU5HVEgpICsgMV07CmJvb2wgbm90UHJpbWVbVkFMVUVdOwoKLy8gbGVhc3Qgc2lnbmlmaWNhbnQgZGlnaXQgaW4geCBiZWNvbWVzIG1vc3Qgc2lnbmlmaWNhbnQgZGlnaXQgaW4gdGhlIGhleGEgY29kZQppbnQgdG9IZXhhKGludCB4LCBpbnQgbnVtRGlnaXQpIHsKICAgIGludCByZXMgPSAwOwogICAgUkVQKGxvdmUsIG51bURpZ2l0KSB7CiAgICAgICAgcmVzID0gKHJlcyA8PCA0KSBeICh4ICUgMTApOwogICAgICAgIHggLz0gMTA7CiAgICB9CiAgICByZXR1cm4geCA+IDAgPyAtMSA6IHJlczsKfQoKdm9pZCBwcmVwYXJlKHZvaWQpIHsKICAgIFJFUChpLCAyKSBub3RQcmltZVtpXSA9IHRydWU7CiAgICBGT1IoaSwgMiwgVkFMVUUgLSAxKSBpZiAoIW5vdFByaW1lW2ldKSBmb3IgKGludCBqID0gMiAqIGk7IGogPCBWQUxVRTsgaiArPSBpKSBub3RQcmltZVtqXSA9IHRydWU7CgogICAgRk9SKGksIDIsIFZBTFVFIC0gMSkgaWYgKCFub3RQcmltZVtpXSkgRk9SKGxlbmd0aCwgMSwgTEVOR1RIKSB7CiAgICAgICAgaW50IGNvZGUgPSB0b0hleGEoaSwgbGVuZ3RoKTsKICAgICAgICBpZiAoY29kZSA8IDApIGNvbnRpbnVlOwoKICAgICAgICBSRVAobWFzaywgTUFTSyhsZW5ndGgpKSB7CiAgICAgICAgICAgIGludCBuZXdDb2RlID0gY29kZTsKICAgICAgICAgICAgUkVQKGksIGxlbmd0aCkgaWYgKEJJVChtYXNrLCBpKSkgbmV3Q29kZSA9IFNFVF9IRVhBX0RJR0lUKG5ld0NvZGUsIGksIEJMQU5LKTsKICAgICAgICAgICAgcHJpbWVzW2xlbmd0aF1bbmV3Q29kZV0ucHVzaF9iYWNrKGNvZGUpOwogICAgICAgIH0KICAgIH0KfQoKaW50IHJlczsKdm9pZCBiYWNrdHJhY2sodmVjdG9yPGludD4gJnN0YXRlLCBpbnQgZmlsbGVkKSB7CiAgICBpbnQgbnVtUm93ID0gc3RhdGUuc2l6ZSgpOwogICAgaWYgKF9fYnVpbHRpbl9wb3Bjb3VudChmaWxsZWQpID09IG51bVJvdykgewogICAgICAgIHJlcysrOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpbnQgcm93ID0gLTEsIG51bUNhbmRpZGF0ZSA9IFZBTFVFOwogICAgaWYgKCFCSVQoZmlsbGVkLCBudW1Sb3cgLSAxKSkgewogICAgICAgIHJvdyA9IG51bVJvdyAtIDE7CiAgICAgICAgbnVtQ2FuZGlkYXRlID0gcHJpbWVzW251bVJvd11bc3RhdGVbcm93XV0uc2l6ZSgpOwogICAgfSBlbHNlIHsKICAgICAgICBSRVAoaSwgbnVtUm93KSBpZiAoIUJJVChmaWxsZWQsIGkpKSB7CiAgICAgICAgICAgIGludCB0bXBDYW5kaWRhdGUgPSBwcmltZXNbbnVtUm93XVtzdGF0ZVtpXV0uc2l6ZSgpOwogICAgICAgICAgICBpZiAobWluaW1pemUobnVtQ2FuZGlkYXRlLCB0bXBDYW5kaWRhdGUpKSByb3cgPSBpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAobnVtQ2FuZGlkYXRlID09IDApIHJldHVybjsKICAgIGlmIChfX2J1aWx0aW5fcG9wY291bnQoZmlsbGVkKSA9PSBudW1Sb3cgLSAxKSB7CiAgICAgICAgcmVzICs9IG51bUNhbmRpZGF0ZTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaW50IG9sZFN0YXRlID0gc3RhdGVbcm93XTsKCiAgICB2ZWN0b3I8aW50PiAmY2FuZGlkYXRlcyA9IHByaW1lc1tudW1Sb3ddW29sZFN0YXRlXTsKICAgIEZPUkUoaXQsIGNhbmRpZGF0ZXMpIHsKICAgICAgICBSRVAoaiwgbnVtUm93KSB7CiAgICAgICAgICAgIC8vIHN0YXRlW3Jvd11bal0gPSBzdGF0ZVtqXVtyb3ddID0gSEVYQV9ESUdJVCgqaXQsIGopCiAgICAgICAgICAgIHN0YXRlW3Jvd10gPSBTRVRfSEVYQV9ESUdJVChzdGF0ZVtyb3ddLCBqLCBIRVhBX0RJR0lUKCppdCwgaikpOwogICAgICAgICAgICBzdGF0ZVtqXSA9IFNFVF9IRVhBX0RJR0lUKHN0YXRlW2pdLCByb3csIEhFWEFfRElHSVQoKml0LCBqKSk7CiAgICAgICAgfQogICAgICAgIGJhY2t0cmFjayhzdGF0ZSwgZmlsbGVkIHwgTUFTSyhyb3cpKTsKICAgIH0KCiAgICBzdGF0ZVtyb3ddID0gb2xkU3RhdGU7CiAgICBSRVAoaSwgbnVtUm93KSBzdGF0ZVtpXSA9IFNFVF9IRVhBX0RJR0lUKHN0YXRlW2ldLCByb3csIEhFWEFfRElHSVQob2xkU3RhdGUsIGkpKTsKfQoKaW50IG51bURpZ2l0KGludCB4KSB7CiAgICByZXR1cm4geCA8IDEwID8gMSA6IG51bURpZ2l0KHggLyAxMCkgKyAxOwp9CgppbnQgc29sdmUoaW50IHgpIHsKICAgIGludCBudW1Sb3cgPSBudW1EaWdpdCh4KTsKICAgIGludCBjb2RlID0gdG9IZXhhKHgsIG51bVJvdyk7CiAgICB2ZWN0b3I8aW50PiBzdGF0ZShudW1Sb3csIDApOwoKICAgIFJFUChpLCBudW1Sb3cpIFJFUChqLCBudW1Sb3cpIC8vIHN0YXRlW2ldW2pdID0gQkxBTksKICAgICAgICBzdGF0ZVtpXSA9IFNFVF9IRVhBX0RJR0lUKHN0YXRlW2ldLCBqLCBCTEFOSyk7CgogICAgUkVQKGksIG51bVJvdykgewogICAgICAgIC8vIHN0YXRlWzBdW2ldID0gc3RhdGVbaV1bMF0gPSBIRVhBX0RJR0lUKGNvZGUsIGkpCiAgICAgICAgc3RhdGVbMF0gPSBTRVRfSEVYQV9ESUdJVChzdGF0ZVswXSwgaSwgSEVYQV9ESUdJVChjb2RlLCBpKSk7CiAgICAgICAgc3RhdGVbaV0gPSBTRVRfSEVYQV9ESUdJVChzdGF0ZVtpXSwgMCwgSEVYQV9ESUdJVChjb2RlLCBpKSk7CiAgICB9CgogICAgcmVzID0gMDsKICAgIGJhY2t0cmFjayhzdGF0ZSwgTUFTSygwKSk7CiAgICByZXR1cm4gcmVzOwp9CgppbnQgbWFpbih2b2lkKSB7CiNpZmRlZiBPTkxJTkVfSlVER0UKICAgIGZyZW9wZW4oInByaW1ldGFibGUuaW5wIiwgInIiLCBzdGRpbik7CiAgICBmcmVvcGVuKCJwcmltZXRhYmxlLm91dCIsICJ3Iiwgc3Rkb3V0KTsKI2VuZGlmIC8vIE9OTElORV9KVURHRQoKICAgIHByZXBhcmUoKTsKICAgIGludCB0OyBzY2FuZigiJWQiLCAmdCk7CiAgICBSRVAobG92ZSwgdCkgewogICAgICAgIGludCB4OyBzY2FuZigiJWQiLCAmeCk7CiAgICAgICAgcHJpbnRmKCIlZCAiLCBzb2x2ZSh4KSk7CiAgICB9CiAgICBwcmludGYoIlxuIik7CiAgICByZXR1cm4gMDsKfQoKLyoqKiBMT09LIEFUIE1ZIENPREUuIE1ZIENPREUgSVMgQU1BWklORyA6RCAqKiov