#include #include #include #include //#include #include using namespace std; int n, k; string v[20]; unordered_map mapa; bool check(vector & v) { int res = 0; for(int i = 0; i < n; i++) { string word = ""; for(int j = 0; j < n; j++) { word += v[i][j]; } if(mapa[word]) { res++; } if(res >= 2 * n) { return true; } word = ""; for(int j = n - 1; j >= 0; j--) { word += v[i][j]; } if(mapa[word]) { res++; } if(res >= 2 * n) { return true; } word = ""; for(int j = 0; j < n; j++) { word += v[j][i]; } if(mapa[word]) { res++; } if(res >= 2 * n) { return true; } word = ""; for(int j = n - 1; j >= 0; j--) { word += v[j][i]; } if(mapa[word]) { res++; } if(res >= 2 * n) { return true; } } return false; } int main() { ios_base::sync_with_stdio(false); cin >> n >> k; unordered_map mapa; map, bool> crossword_visited; for(int i = 0; i < k; i++) { cin >> v[i]; mapa[v[i]] = true; } string tmp = ""; for(int i = 0; i < n; i++) { tmp += "."; } vector c(n, tmp); queue> q; q.push(c); queue> q_visited; vector visited(k, false); q_visited.push(visited); int res = 0; while(!q.empty()) { c = q.front(); q.pop(); visited = q_visited.front(); q_visited.pop(); for(int i = 0; i < n; i++) { for(int j= 0; j < n; j++) { cout << c[i][j]; } cout << endl; } cout << endl; if(check(c)) { res++; continue; } for(int a = 0; a < k; a++) { if(!visited[a]) { for(int i = 0; i < n; i++) { bool ok = true; for(int j = 0; j < n; j++) { if(v[a][j] != c[i][j] and c[i][j] != '.') { ok = false; break; } } if(ok) { vector t = c; for(int j = 0; j < n; j++) { t[i][j] = v[a][j]; } if(!crossword_visited[t]) { q.push(t); visited[a] = true; q_visited.push(visited); visited[a] = false; crossword_visited[t] = true; } } ok = true; for(int j = n - 1; j >= 0; j--) { if(v[a][j] != c[i][j] and c[i][j] != '.') { ok = false; break; } } if(ok) { vector t = c; for(int j = n - 1; j >= 0; j--) { t[i][j] = v[a][j]; } if(!crossword_visited[t]) { q.push(t); visited[a] = true; q_visited.push(visited); visited[a] = false; crossword_visited[t] = true; } } ok = true; for(int j = 0; j < n; j++) { if(v[a][j] != c[j][i] and c[j][i] != '.') { ok = false; break; } } if(ok) { vector t = c; for(int j = 0; j < n; j++) { t[j][i] = v[a][j]; } if(!crossword_visited[t]) { q.push(t); visited[a] = true; q_visited.push(visited); visited[a] = false; crossword_visited[t] = true; } } ok = true; for(int j = n - 1; j>= 0; j--) { if(v[a][j] != c[j][i] and c[j][i] != '.') { ok = false; break; } } if(ok) { vector t = c; for(int j = n - 1; j >= 0; j--) { t[j][i] = v[a][j]; } if(!crossword_visited[t]) { q.push(t); visited[a] = true; q_visited.push(visited); visited[a] = false; crossword_visited[t] = true; } } } } } } cout << res << endl; return 0; }