#include #include #include #include using namespace std; #define pb push_back #define mp make_pair #define eb emplace_back #define all(a) begin(a), end(a) #define has(a, b) (a.find(b) != a.end()) #define fora(i, n) for(int i = 0; i < n; i++) #define forb(i, n) for(int i = 1; i <= n; i++) #define forc(a, b) for(const auto &a : b) #define ford(i, n) for(int i = n; i >= 0; i--) #define maxval(t) numeric_limits::max() #define minval(t) numeric_limits::min() #define imin(a, b) a = min(a, b) #define imax(a, b) a = max(a, b) #define sz(x) (int)(x).size() #define pvec(v) copy(all(v), ostream_iterator(cout, " ")) #define dbgs(x) #x << " = " << x #define dbgs2(x, y) dbgs(x) << ", " << dbgs(y) #define dbgs3(x, y, z) dbgs2(x, y) << ", " << dbgs(z) #define dbgs4(w, x, y, z) dbgs3(w, x, y) << ", " << dbgs(z) using ll = long long; using ld = long double; string ans; vector lo, hi; vector> forbidden; vector forced; vector filled; int n, m; vector ltrs; mt19937 rng(43); bool choose(int li, int i, int poss); bool canput(int c, int i) { return !filled[i] && !forbidden[c][i]; } bool backtrack(int li, int i, int poss); bool backtrack(int li) { if (li > 0 && lo[ltrs[li - 1]] > 0) { return false; } if (li == 26) return true; int poss = 0; fora(i, n) if (canput(ltrs[li], i)) ++poss; bool ans = backtrack(li, 0, poss); return ans; } bool backtrack(int li, int i, int poss) { if (i == n) { return backtrack(li + 1); } if (lo[ltrs[li]] > poss) { return false; } if (filled[i]) return backtrack(li, i + 1, poss); if (hi[ltrs[li]] == 0) { return backtrack(li + 1); } if (forbidden[ltrs[li]][i]) { return backtrack(li, i + 1, poss); } if (choose(li, i, poss)) { return true; } return max(0ll, lo[ltrs[li]]) < poss && backtrack(li, i + 1, poss - 1); } bool choose(int li, int i, int poss) { int c = ltrs[li]; filled[i] = true; ans[i] = (char)(c + 'a'); --lo[c]; --hi[c]; bool res = backtrack(li, i + 1, poss - 1); filled[i] = false; ++lo[c]; ++hi[c]; return res; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> m >> n; ltrs = vector(26); iota(all(ltrs), 0); shuffle(all(ltrs), rng); vector perm(n); iota(all(perm), 0); shuffle(all(perm), rng); vector inv(n); fora(i, n) { inv[perm[i]] = i; } --m; ans = string(n, '0'); forced = vector(n); forbidden = vector>(26, vector(n)); lo = vector(26); hi = vector(26, n); fora(_, m) { string ss, tt; cin >> ss >> tt; string s(n, '0'), t(n, '0'); fora(i, n) { s[i] = ss[perm[i]]; t[i] = tt[perm[i]]; } vector gy(26), b(26); vector seen(26); fora(i, n) { int l = s[i] - 'a'; if (t[i] == 'G') { ++gy[l]; ans[i] = s[i]; forced[i] = true; } else if (t[i] == 'Y') { ++gy[l]; forbidden[l][i] = true; } else { ++b[l]; forbidden[l][i] = true; } } fora(l, 26) { imax(lo[l], gy[l]); if (b[l] > 0) { imin(hi[l], gy[l]); } } } fora(i, n) { if (forced[i]) { int l = ans[i] - 'a'; --lo[l]; --hi[l]; } } filled = forced; backtrack(0); string aans(n, '0'); fora(i, n) aans[i] = ans[inv[i]]; cout << aans << endl; }