#include <iostream>
#include <sstream>
#include <vector>
#include <tuple>
#include <cstdint>
#include <string>
#include <algorithm>
#include <map>
typedef std::tuple<std::uint64_t, std::uint64_t> RData;
typedef std::tuple<char, char> Data;
typedef std::vector<Data> DType;
DType GetInput(std::istream& is) {
char A = 0;
char B = 0;
DType D;
while (is >> A) {
if (!(is >> B)) break;
D.push_back({A,B});
}
return D;
}
template<int N>
bool IsMatch(DType& D) {
for (std::size_t i = 0; i < D.size(); i++) {
if (std::get<N>(D.front()) != std::get<N>(D[i])) return false;
}
return true;
}
bool Calc_rec(DType A,DType B, RData& R, std::size_t Depth) {
if (Depth == 0) {
if (IsMatch<0>(A))std::get<0>(R)++;
if (IsMatch<1>(A))std::get<1>(R)++;
return true;
}
if (!(IsMatch<0>(A) || IsMatch<1>(A))) return false;
for (std::size_t i = 0; i < B.size(); i++) {
A.push_back(B[i]);
B.erase(B.begin()+i);
Calc_rec(A, B, R, Depth - 1);
B.push_back(A.back());
A.pop_back();
std::sort(B.begin(), B.end());
}
return false;
}
template<int N>
std::size_t Count(DType& D) {
std::map<char, std::size_t> M;
std::size_t C = 0;
for (auto& o : D) {
M[std::get<N>(o)]++;
}
for (auto& o : M) {
C = std::max(o.second, C);
}
return C;
}
RData Calc(DType& D) {
RData R{ 0,0 };
std::sort(D.begin(), D.end());
std::size_t A = Count<0>(D);
std::size_t B = Count<1>(D);
std::size_t C = std::max(A, B);
for (std::size_t i = 2; i<C+1; i++) {
Calc_rec(DType(), D, R, i);
}
return R;
}
bool Show(std::string& S, RData& R) {
std::cout << S << ':' << std::get<0>(R) << ',' << std::get<1>(R) << std::endl;
return true;
}
int main() {
{
std::string S = "DAD2HAH3";
std::stringstream ss(S);
DType D = GetInput(ss);
RData R = Calc(D);
Show(S, R);
}
{
std::string S = "DAD3D8D9DJH5H8HKSASKCAC5C8CK";
std::stringstream ss(S);
DType D = GetInput(ss);
RData R = Calc(D);
Show(S, R);
}
{
std::string S = "SAS2S3S4S5S6S7S8S9C2C3C4C5C6C7C8C9CT";
std::stringstream ss(S);
DType D = GetInput(ss);
RData R = Calc(D);
Show(S, R);
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8Y3N0ZGludD4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPG1hcD4KCnR5cGVkZWYgc3RkOjp0dXBsZTxzdGQ6OnVpbnQ2NF90LCBzdGQ6OnVpbnQ2NF90PiBSRGF0YTsKdHlwZWRlZiBzdGQ6OnR1cGxlPGNoYXIsIGNoYXI+IERhdGE7CnR5cGVkZWYgc3RkOjp2ZWN0b3I8RGF0YT4gRFR5cGU7CgpEVHlwZSBHZXRJbnB1dChzdGQ6OmlzdHJlYW0mIGlzKSB7CgljaGFyIEEgPSAwOwoJY2hhciBCID0gMDsKCURUeXBlIEQ7CgoJd2hpbGUgKGlzID4+IEEpIHsKCQlpZiAoIShpcyA+PiBCKSkgYnJlYWs7CgkJRC5wdXNoX2JhY2soe0EsQn0pOwoJfQoKCXJldHVybiBEOwp9Cgp0ZW1wbGF0ZTxpbnQgTj4KYm9vbCBJc01hdGNoKERUeXBlJiBEKSB7Cglmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgRC5zaXplKCk7IGkrKykgewoJCWlmIChzdGQ6OmdldDxOPihELmZyb250KCkpICE9IHN0ZDo6Z2V0PE4+KERbaV0pKSByZXR1cm4gZmFsc2U7Cgl9CglyZXR1cm4gdHJ1ZTsKfQoKYm9vbCBDYWxjX3JlYyhEVHlwZSBBLERUeXBlIEIsIFJEYXRhJiBSLCBzdGQ6OnNpemVfdCBEZXB0aCkgewoKCWlmIChEZXB0aCA9PSAwKSB7CgkJaWYgKElzTWF0Y2g8MD4oQSkpc3RkOjpnZXQ8MD4oUikrKzsKCQlpZiAoSXNNYXRjaDwxPihBKSlzdGQ6OmdldDwxPihSKSsrOwoJCXJldHVybiB0cnVlOwoJfQoJaWYgKCEoSXNNYXRjaDwwPihBKSB8fCBJc01hdGNoPDE+KEEpKSkgcmV0dXJuIGZhbHNlOwoKCWZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCBCLnNpemUoKTsgaSsrKSB7CgkJQS5wdXNoX2JhY2soQltpXSk7CgkJQi5lcmFzZShCLmJlZ2luKCkraSk7CgkJQ2FsY19yZWMoQSwgQiwgUiwgRGVwdGggLSAxKTsKCQlCLnB1c2hfYmFjayhBLmJhY2soKSk7CgkJQS5wb3BfYmFjaygpOwoJCXN0ZDo6c29ydChCLmJlZ2luKCksIEIuZW5kKCkpOwoJfQoKCXJldHVybiBmYWxzZTsKfQoKdGVtcGxhdGU8aW50IE4+CnN0ZDo6c2l6ZV90IENvdW50KERUeXBlJiBEKSB7CglzdGQ6Om1hcDxjaGFyLCBzdGQ6OnNpemVfdD4gTTsKCXN0ZDo6c2l6ZV90IEMgPSAwOwoJZm9yIChhdXRvJiBvIDogRCkgewoJCU1bc3RkOjpnZXQ8Tj4obyldKys7Cgl9CgoJZm9yIChhdXRvJiBvIDogTSkgewoJCUMgPSBzdGQ6Om1heChvLnNlY29uZCwgQyk7Cgl9CglyZXR1cm4gQzsKfQoKUkRhdGEgQ2FsYyhEVHlwZSYgRCkgewoJUkRhdGEgUnsgMCwwIH07CgoJc3RkOjpzb3J0KEQuYmVnaW4oKSwgRC5lbmQoKSk7CgoJc3RkOjpzaXplX3QgQSA9IENvdW50PDA+KEQpOwoJc3RkOjpzaXplX3QgQiA9IENvdW50PDE+KEQpOwoJc3RkOjpzaXplX3QgQyA9IHN0ZDo6bWF4KEEsIEIpOwoKCWZvciAoc3RkOjpzaXplX3QgaSA9IDI7IGk8QysxOyBpKyspIHsKCQlDYWxjX3JlYyhEVHlwZSgpLCBELCBSLCBpKTsKCX0KCXJldHVybiBSOwoKfQoKYm9vbCBTaG93KHN0ZDo6c3RyaW5nJiBTLCBSRGF0YSYgUikgewoJc3RkOjpjb3V0IDw8IFMgPDwgJzonIDw8IHN0ZDo6Z2V0PDA+KFIpIDw8ICcsJyA8PCBzdGQ6OmdldDwxPihSKSA8PCBzdGQ6OmVuZGw7CglyZXR1cm4gdHJ1ZTsKfQoKaW50IG1haW4oKSB7CgkKCXsKCQlzdGQ6OnN0cmluZyBTID0gIkRBRDJIQUgzIjsKCQlzdGQ6OnN0cmluZ3N0cmVhbSBzcyhTKTsKCQlEVHlwZSBEID0gR2V0SW5wdXQoc3MpOwoJCVJEYXRhIFIgPSBDYWxjKEQpOwoJCVNob3coUywgUik7Cgl9CgkKCXsKCQlzdGQ6OnN0cmluZyBTID0gIkRBRDNEOEQ5REpINUg4SEtTQVNLQ0FDNUM4Q0siOwoJCXN0ZDo6c3RyaW5nc3RyZWFtIHNzKFMpOwoJCURUeXBlIEQgPSBHZXRJbnB1dChzcyk7CgkJUkRhdGEgUiA9IENhbGMoRCk7CgkJU2hvdyhTLCBSKTsKCX0KCQoJewoJCXN0ZDo6c3RyaW5nIFMgPSAiU0FTMlMzUzRTNVM2UzdTOFM5QzJDM0M0QzVDNkM3QzhDOUNUIjsKCQlzdGQ6OnN0cmluZ3N0cmVhbSBzcyhTKTsKCQlEVHlwZSBEID0gR2V0SW5wdXQoc3MpOwoJCVJEYXRhIFIgPSBDYWxjKEQpOwoJCVNob3coUywgUik7Cgl9CgoJcmV0dXJuIDA7Cn0=