#include #include #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)); } void die() { cout << "0\n"; exit(0); } int main() { int n; cin >> n; vector words(n); vector edges; vector ret(3); auto dfs = y_combinator([&](auto self, int curr) -> bool { if(curr == 18) return true; for(int i = 0; i < 3; i++) { if(__builtin_popcount(ret[i]) == 6) continue; if(ret[i] & edges[curr]) continue; ret[i] |= 1 << curr; if(self(curr+1)) return true; ret[i] ^= 1 << curr; } return false; }); map freq; for(auto& out: words) { cin >> out; sort(out.begin(), out.end()); map inner; for(auto out2: out) { if(++inner[out2] > 1) die(); } for(auto [k, v]: inner) freq[k] = max(freq[k], v); } string base = ""; { char ch = 'a'; while(freq.size() < 18) { if(!freq.count(ch)) freq[ch] = 1; ch++; } } { for(auto [k, v]: freq) for(int i = 0; i < v; i++) base += k; if(base.size() > 18) die(); } while(base.size() < 18) base += "z"; edges.resize(base.size()); for(auto out: words) { vector indices; int idx = 0; for(auto out2: out) { while(base[idx] != out2) idx++; indices.push_back(idx++); } for(auto out2: indices) for(auto out3: indices) { if(out2 == out3) break; edges[out2] |= 1 << out3; edges[out3] |= 1 << out2; } } if(!dfs(0)) die(); for(int i = 0; i < 3; i++) { for(int a = 0; a < 18; a++) if(ret[i] & (1<