#include #include using namespace std; int main() { int p,t; cin >> p >> t; string abbr[t]; bitset<26> team[t]; for (int i = 0; i < t; i++) { team[i].reset(); cin >> abbr[i]; for (char c:abbr[i]) { team[i].set(c-'A'); } } // Brute force: try all possible subsets of the t teams: int max = pow(2,t); int best = 0; bitset<26> univ(pow(2,p)-1); for (int i = 1; i < max; i++) { bitset<26> u = univ; bitset<26> subset(i); // I don't know how to iterate over just the set bits in a bitset, so // convert to a string and iterate over '1's in the string: string s = subset.to_string(); reverse(s.begin(),s.end()); // so bits are in same orientation as bitset int temp = subset.count(); if (temp <= best) continue; // only check bigger subsets than best so far bool success = true; for (int j = s.find_first_of("1"); j != s.npos; j = s.find_first_of("1",j+1)) { // see if any duplicate letters: if (team[j].count() < abbr[j].length()) { success = false; break; } if ((u & team[j]) == team[j]) { u ^= team[j]; } else { success = false; break; } } if (success) { best = temp; } } cout << best << endl; }