#include #include #include using namespace std; template class y_combinator_result { Fun fun_; public: template explicit y_combinator_result(T &&fun): fun_(std::forward(fun)) {} template decltype(auto) operator()(Args &&...args) { return fun_(std::ref(*this), std::forward(args)...); } }; template decltype(auto) y_combinator(Fun &&fun) { return y_combinator_result>(std::forward(fun)); } int main() { auto getidx = [&](const string& s) -> int { int ret = 0; for(auto out: s) { ret *= 3; if(out == 'X') ret += 1; else if(out == 'O') ret += 2; } return ret; }; vector> dp(19683); fill(dp.begin(), dp.end(), pair(-1, -1)); string s = "........."; auto win = [&](char ch) -> bool { if(s[0] == ch && s[3] == ch && s[6] == ch) return true; if(s[1] == ch && s[4] == ch && s[7] == ch) return true; if(s[2] == ch && s[5] == ch && s[8] == ch) return true; if(s[0] == ch && s[1] == ch && s[2] == ch) return true; if(s[3] == ch && s[4] == ch && s[5] == ch) return true; if(s[6] == ch && s[7] == ch && s[8] == ch) return true; if(s[0] == ch && s[4] == ch && s[8] == ch) return true; if(s[2] == ch && s[4] == ch && s[6] == ch) return true; return false; }; auto dfs = y_combinator([&](auto self) -> void { int idx = getidx(s); if(dp[idx].first >= 0) return; dp[idx].first = 0; dp[idx].second = 0; int xc = 0; int oc = 0; for(auto out: s) if(out == 'X') xc++; else if(out == 'O') oc++; if(xc > oc && win('X')) {dp[idx].first = 1; return;} if(xc == oc && win('O')) {dp[idx].second = 1; return;} for(int i = 0; i < 9; i++) if(s[i] != '.') continue; else { if(xc == oc) s[i] = 'X'; else s[i] = 'O'; int nidx = getidx(s); self(); dp[idx].first += dp[nidx].first; dp[idx].second += dp[nidx].second; s[i] = '.'; } }); dfs(); ios_base::sync_with_stdio(false); cin.tie(NULL); int t; cin >> t; while(t--) { cin >> s; int idx = getidx(s); cout << dp[idx].first << " " << dp[idx].second << "\n"; } }