#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;
using ld = long double;
static ull Cbinom[53][53];
// ranks in order 2..A (Ace last) to make 10-J-Q-K-A consecutive,
// and handle A-2-3-4-5 via wrap check at Ace.
static const string RANKS = "23456789TJQKA";
int rIndex(char r) {
return (int)RANKS.find(r);
}
int sIndex(char s) {
if (s == 'c') return 0;
if (s == 'd') return 1;
if (s == 'h') return 2;
return 3; // 's'
}
struct RunTrans {
// next_run[run_state][presence_mask], hit if any suit completes length-5 here
int next_run[625][16];
bool hit[625][16];
RunTrans() {
// decode run_state into 4 base-5 digits
int dig[625][4];
for (int st = 0; st < 625; st++) {
int x = st;
for (int s = 0; s < 4; s++) {
dig[st][s] = x % 5;
x /= 5;
}
}
for (int st = 0; st < 625; st++) {
for (int mask = 0; mask < 16; mask++) {
bool found = false;
int nd[4];
for (int s = 0; s < 4; s++) {
bool present = (mask >> s) & 1;
int d = dig[st][s];
if (present) {
if (d == 4) found = true; // 4 + present => 5 in a row
nd[s] = min(4, d + 1);
} else {
nd[s] = 0;
}
}
int enc = 0, mul = 1;
for (int s = 0; s < 4; s++) {
enc += nd[s] * mul;
mul *= 5;
}
next_run[st][mask] = enc;
hit[st][mask] = found;
}
}
}
};
static RunTrans RT;
// all subsets of a 4-bit mask, each with its popcount
static vector<pair<int,int>> subOf[16];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// binom
for (int n = 0; n <= 52; n++) {
Cbinom[n][0] = Cbinom[n][n] = 1;
for (int k = 1; k < n; k++) {
Cbinom[n][k] = Cbinom[n-1][k-1] + Cbinom[n-1][k];
}
}
// subsets
for (int m = 0; m < 16; m++) {
int sub = m;
while (true) {
subOf[m].push_back({sub, __builtin_popcount((unsigned)sub)});
if (sub == 0) break;
sub = (sub - 1) & m;
}
}
int m;
cin >> m;
string h1, h2;
cin >> h1 >> h2;
int n;
cin >> n;
vector<string> b(n);
for (int i = 0; i < n; i++) cin >> b[i];
// known_mask[r] = 4-bit suits present among fixed known cards
int known_mask[13] = {0};
auto addKnown = [&](const string& c) {
int r = rIndex(c[0]);
int s = sIndex(c[1]);
known_mask[r] |= (1 << s);
};
addKnown(h1);
addKnown(h2);
int k = 0;
for (auto &x : b) {
if (x == "?") k++;
else addKnown(x);
}
int avail_mask[13];
int R = 0;
for (int r = 0; r < 13; r++) {
avail_mask[r] = (~known_mask[r]) & 0b1111;
R += __builtin_popcount((unsigned)avail_mask[r]);
}
ull total = Cbinom[R][k];
// decide mode
enum Mode { FK_ONLY, SF_ONLY, ALL_THREE };
Mode mode;
if (m == 1 || m == 3 || m == 5) mode = FK_ONLY;
else if (m == 4 || m == 6 || m == 7 || m == 8) mode = SF_ONLY;
else mode = ALL_THREE;
ull favorable = 0;
if (mode == FK_ONLY) {
// dp0[j]=ways with no four-kind yet, dp1[j]=ways with four-kind already
vector<ull> dp0(k+1, 0), dp1(k+1, 0);
dp0[0] = 1;
for (int r = 0; r < 13; r++) {
int a = __builtin_popcount((unsigned)avail_mask[r]);
int kn = __builtin_popcount((unsigned)known_mask[r]);
vector<ull> ndp0(k+1, 0), ndp1(k+1, 0);
// already true
for (int j = 0; j <= k; j++) if (dp1[j]) {
for (int t = 0; t <= a && j+t <= k; t++) {
ndp1[j+t] += dp1[j] * Cbinom[a][t];
}
}
// not yet
for (int j = 0; j <= k; j++) if (dp0[j]) {
for (int t = 0; t <= a && j+t <= k; t++) {
ull ways = Cbinom[a][t];
if (kn + t == 4) ndp1[j+t] += dp0[j] * ways;
else ndp0[j+t] += dp0[j] * ways;
}
}
dp0.swap(ndp0);
dp1.swap(ndp1);
}
favorable = dp1[k];
}
if (mode == SF_ONLY) {
const int SS = 625 * 16; // run_state * 16 + wheel_mask
auto enc = [&](int run, int wheel){ return run*16 + wheel; };
vector<ull> dpFalse((k+1)*SS, 0), dpFalse2((k+1)*SS, 0);
vector<ull> dpTrue(k+1, 0), dpTrue2(k+1, 0);
dpFalse[0*SS + enc(0, 15)] = 1; // wheel_mask starts as all 1s (possible), AND over ranks 2..5.
for (int r = 0; r < 13; r++) {
fill(dpFalse2.begin(), dpFalse2.end(), 0);
fill(dpTrue2.begin(), dpTrue2.end(), 0);
int km = known_mask[r];
int am = avail_mask[r];
int a = __builtin_popcount((unsigned)am);
// true transitions can ignore suit pattern => just choose t cards among a
for (int j = 0; j <= k; j++) if (dpTrue[j]) {
for (int t = 0; t <= a && j+t <= k; t++) {
dpTrue2[j+t] += dpTrue[j] * Cbinom[a][t];
}
}
// false transitions enumerate subsets (<=16)
for (int j = 0; j <= k; j++) {
ull *row = &dpFalse[j*SS];
for (int st = 0; st < SS; st++) {
ull val = row[st];
if (!val) continue;
int run = st / 16;
int wheel = st % 16;
for (auto [sub, t] : subOf[am]) {
if (j + t > k) continue;
int presence = km | sub;
int run2 = RT.next_run[run][presence];
bool hit = RT.hit[run][presence];
int wheel2 = wheel;
if (r <= 3) wheel2 = wheel & presence; // ranks 2..5
// wheel A2345 detected at Ace
if (r == 12 && (wheel & presence)) hit = true;
if (hit) dpTrue2[j+t] += val;
else dpFalse2[(j+t)*SS + enc(run2, wheel2)] += val;
}
}
}
dpFalse.swap(dpFalse2);
dpTrue.swap(dpTrue2);
}
favorable = dpTrue[k];
}
if (mode == ALL_THREE) {
// state: run(0..624), wheel(0..15), pairCnt(0..2), hasTrip(0/1)
const int SS = 625 * 16 * 3 * 2;
auto enc = [&](int run, int wheel, int pairCnt, int hasTrip) {
return (((run * 16 + wheel) * 3 + pairCnt) * 2 + hasTrip);
};
vector<ull> dpFalse((k+1)*SS, 0), dpFalse2((k+1)*SS, 0);
vector<ull> dpTrue(k+1, 0), dpTrue2(k+1, 0);
dpFalse[0*SS + enc(0, 15, 0, 0)] = 1;
for (int r = 0; r < 13; r++) {
fill(dpFalse2.begin(), dpFalse2.end(), 0);
fill(dpTrue2.begin(), dpTrue2.end(), 0);
int km = known_mask[r];
int am = avail_mask[r];
int a = __builtin_popcount((unsigned)am);
int kn = __builtin_popcount((unsigned)km);
// true: only choose counts matter
for (int j = 0; j <= k; j++) if (dpTrue[j]) {
for (int t = 0; t <= a && j+t <= k; t++) {
dpTrue2[j+t] += dpTrue[j] * Cbinom[a][t];
}
}
// false: enumerate subsets for SF tracking
for (int j = 0; j <= k; j++) {
ull *row = &dpFalse[j*SS];
for (int st = 0; st < SS; st++) {
ull val = row[st];
if (!val) continue;
int tmp = st;
int hasTrip = tmp % 2; tmp /= 2;
int pairCnt = tmp % 3; tmp /= 3;
int wheel = tmp % 16;
int run = tmp / 16;
for (auto [sub, t] : subOf[am]) {
if (j + t > k) continue;
int presence = km | sub;
int run2 = RT.next_run[run][presence];
bool win = RT.hit[run][presence];
int wheel2 = wheel;
if (r <= 3) wheel2 = wheel & presence;
// wheel A2345 at Ace
if (r == 12 && (wheel & presence)) win = true;
int c = kn + t; // total cards of this rank in final set
if (c == 4) win = true; // four of a kind
int pairCnt2 = pairCnt + (c >= 2 ? 1 : 0);
if (pairCnt2 > 2) pairCnt2 = 2;
int hasTrip2 = hasTrip || (c >= 3);
if (hasTrip2 && pairCnt2 == 2) win = true; // full house
if (win) dpTrue2[j+t] += val;
else dpFalse2[(j+t)*SS + enc(run2, wheel2, pairCnt2, hasTrip2)] += val;
}
}
}
dpFalse.swap(dpFalse2);
dpTrue.swap(dpTrue2);
}
favorable = dpTrue[k];
}
ld ans = (total == 0 ? 0.0L : (ld)favorable / (ld)total);
cout << fixed << setprecision(15) << (double)ans << "\n";
return 0;
}