#include #include #include using namespace std; /*struct GRAPH { vector > s; void ClearEdges() { for (auto& i : s) i.resize(0); } void Init(int n) { ClearEdges(); s.resize(n+1); } void AddDi(int u, int v) { s[u].push_back(v); } };*/ #define MAX1 55 #define MAX2 55 //O(VE) int pair1[MAX1][MAX2];//pair1[0] is invalid. pair1[i][j] == k means that k(in the second group) can be distributed to i(in the first group) int len1[MAX1]; int match2[MAX2];//match2[i] == j means that i(in the second group) is distributed to the j(in the first group) bool vis2[MAX2]; //n1 is the size of the first group void Init(int n1, int n2) { memset(len1, 0, (n1+1) * sizeof(int)); memset(match2, 0, (n2+1) * sizeof(int)); } void AddPair(int u, int v) { pair1[u][len1[u]++] = v; } //If succeed return 1,else return 0 bool dfs_hungary(int x) { for(int i = 0; i < len1[x]; i++) { int right = pair1[x][i]; if(!vis2[right]) { vis2[right] = 1; if(match2[right] == 0 || dfs_hungary(match2[right])) { match2[right] = x; return 1; } } } return 0; } int hungary(int n1, int n2) { int tot = 0; for(int i = n1-1; i >= 0; --i) { //If i=n1;i;--i, then the final pairs' lexicographical order will be the least memset(vis2, 0, (n2+1) * sizeof(bool)); if(dfs_hungary(i)) ++tot; } return tot; } #define MAXN 111 int main() { int T; static char s1[MAXN], s2[MAXN]; static int now[MAXN]; scanf("%d", &T); while (T--) { int m, n; scanf("%d%d", &m, &n); Init(n, n); scanf("%s%s", s1, s2); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (s1[i] == s2[j]) { AddPair(i, j); } } } for (int i = 1; i < m; ++i) { scanf("%s%s", s1, s2); for (int i = 0; i < n; ++i) { int nowl = 0; for (int k = 0; k < len1[i]; ++k) { int& j = pair1[i][k]; if (s2[j] == s1[i]) { now[nowl++] = j; } } memcpy(pair1[i], now, nowl * sizeof(int)); len1[i] = nowl; } } int ans = hungary(n, n); if (ans < n) { puts("-1"); } else { for (int i = 0; i < n; ++i) { now[match2[i]] = i; } for (int i = 0; i < n; ++i) { printf("%d%c", now[i] + 1, i == n-1 ? '\n' : ' '); } } } return 0; }