structTrie { int c[NUM][CHAR_NUM], val[NUM], fail[NUM], cnt;
voidinsert(char *s){ int len = strlen(s); int now = 0; for (int i = 0; i < len; i++) { // int v = s[i] - 'a'; int v = s[i] - '0'; if (!c[now][v])c[now][v] = ++cnt; now = c[now][v]; } val[now]++; }
voidbuild(){ queue<int> q; for (int i = 0; i < CHAR_NUM; i++)if (c[0][i])fail[c[0][i]] = 0, q.push(c[0][i]); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < CHAR_NUM; i++) if (c[u][i])fail[c[u][i]] = c[fail[u]][i], q.push(c[u][i]); else c[u][i] = c[fail[u]][i]; } }
intquery(char *s){ int len = strlen(s); int now = 0, ans = 0; for (int i = 0; i < len; i++) { // now = c[now][s[i] - 'a']; now = c[now][s[i] - '0']; for (int t = now; t && ~val[t]; t = fail[t])ans += val[t], val[t] = -1; } return ans; } } AC;
char s[30100]; bool vis[NUM];
booldfs(int cur){ for (int i = 0; i < CHAR_NUM; ++i) { int x = AC.c[cur][i]; if (!AC.val[x]) { bool flag = false; int t = x; while (t) { if (AC.val[t]) { flag = true; break; } t = AC.fail[t]; } if (flag) continue; if (vis[x]) returntrue; vis[x] = true; if (dfs(x)) { returntrue; } vis[x] = false; } } returnfalse; }
voidsolve(){ int n; cin >> n; for (int i = 0; i < n; ++i) { cin >> s; AC.insert(s); } AC.build(); vis[0] = true; bool flag = dfs(0); if (flag) { cout << "TAK" << endl; } else { cout << "NIE" << endl; } }