// Author: Adam Polak // O(n) #include #include using namespace std; const int MAXL = 1e6; const int MOD = 1e9 + 9; char s1[MAXL + 1], s2[MAXL + 1], s3[MAXL + 1]; int n1, n2, n3; long long suf1[MAXL + 2], suf2[MAXL + 2], suf3[MAXL + 2], suf12[MAXL + 2], suf23[MAXL + 2]; int WaysEqual(char a, char b) { if (a == '?' && b == '?') return 26; return (a == '?' || b == '?' || a == b) ? 1 : 0; } int WaysLess(char a, char b) { if (a == '?' && b == '?') return 25 * 26 / 2; if (a != '?' && b != '?') return a < b ? 1 : 0; if (a == '?') return b >= 'a' ? (b - 'a') : 0; if (b == '?') return 'z' - a; } int WaysLessEqual(char a, char b, char c) { if (b != c && b != '?' && c != '?') return 0; if (b == '?') return WaysLess(a, c); else return WaysLess(a, b); } int WaysEqualLess(char a, char b, char c) { if (a != b && a != '?' && b != '?') return 0; if (b == '?') return WaysLess(a, c); else return WaysLess(b, c); } int WaysLessLess(char a, char b, char c) { int a_start = a == '?' ? 'a' : a; int a_end = a == '?' ? 'z' : a; int b_start = b == '?' ? 'a' : b; int b_end = b == '?' ? 'z' : b; int c_start = c == '?' ? 'a' : c; int c_end = c == '?' ? 'z' : c; int count = 0; for (int x = b_start; x <= b_end; ++x) count += max(0, min(a_end, x - 1) - a_start + 1) * max(0, c_end - max(c_start, x + 1) + 1); return count; } int main() { ios_base::sync_with_stdio(false); int Z; cin >> Z; while (Z--) { cin >> s1 >> s2 >> s3; n1 = strlen(s1); n2 = strlen(s2); n3 = strlen(s3); s1[n1] = s2[n2] = s3[n3] = 'a' - 1; suf1[n1 + 1] = 1; for (int i = n1; i >= 0; --i) suf1[i] = (suf1[i + 1] * (s1[i] == '?' ? 26 : 1)) % MOD; suf2[n2 + 1] = 1; for (int i = n2; i >= 0; --i) suf2[i] = (suf2[i + 1] * (s2[i] == '?' ? 26 : 1)) % MOD; suf3[n3 + 1] = 1; for (int i = n3; i >= 0; --i) suf3[i] = (suf3[i + 1] * (s3[i] == '?' ? 26 : 1)) % MOD; suf12[min(n1, n2) + 1] = 0; for (int i = min(n1, n2); i >= 0; --i) suf12[i] = ( WaysEqual(s1[i], s2[i]) * suf12[i + 1] + WaysLess(s1[i], s2[i]) * ((suf1[i + 1] * suf2[i + 1]) % MOD)) % MOD; suf23[min(n2, n3) + 1] = 0; for (int i = min(n2, n3); i >= 0; --i) suf23[i] = ( WaysEqual(s2[i], s3[i]) * suf23[i + 1] + WaysLess(s2[i], s3[i]) * ((suf2[i + 1] * suf3[i + 1]) % MOD)) % MOD; long long pref = 1; long long total = 0; for (int i = 0; i <= min(n1, min(n2, n3)); ++i) { long long count; count = pref; count = (count * WaysLessEqual(s1[i], s2[i], s3[i])) % MOD; count = (count * suf1[i + 1]) % MOD; count = (count * suf23[i + 1]) % MOD; total = (total + count) % MOD; count = pref; count = (count * WaysLessLess(s1[i], s2[i], s3[i])) % MOD; count = (count * suf1[i + 1]) % MOD; count = (count * suf2[i + 1]) % MOD; count = (count * suf3[i + 1]) % MOD; total = (total + count) % MOD; count = pref; count = (count * WaysEqualLess(s1[i], s2[i], s3[i])) % MOD; count = (count * suf12[i + 1]) % MOD; count = (count * suf3[i + 1]) % MOD; total = (total + count) % MOD; if (s1[i] == '?' && s2[i] == '?' && s3[i] == '?') pref = (pref * 26) % MOD; if ((s1[i] != '?' && s2[i] != '?' && s1[i] != s2[i]) || (s2[i] != '?' && s3[i] != '?' && s2[i] != s3[i]) || (s3[i] != '?' && s1[i] != '?' && s3[i] != s1[i])) break; } cout << total << endl; } }