#include using namespace std; const int MAXN = (int) 1e5 + 15; typedef long long LL; const int MAX = (int) 1e5; int main() { int T; scanf("%d", &T); assert(T >= 1 && T <= 10); int tc = 0; while (T--) { tc++; int n, m; scanf("%d %d", &n, &m); assert(n >= 1 && n <= MAX); assert(m >= 1 && m <= MAX); n += 1; int ok = true; vector > edges; set > edgeSet; vector > revEdges(n); for (int i = 0; i < m; i++) { int from, to; scanf("%d %d", &from, &to); assert(from >= 0 && from <= n); assert(to >= 0 && to <= n); if (from >= to) { ok = false; } if (edgeSet.find(make_pair(from, to)) != edgeSet.end()) { ok = false; } edgeSet.insert(make_pair(from, to)); edges.push_back(make_pair(from, to)); revEdges[to].push_back(from); } for (int to = 1; ok && to < n; to++) { if (revEdges[to].size() == 0) { ok = false; break; } // If the set of vertices {from}, such that there is an edge (from, to) is not a set of consecutive elements, // Then the answer is impossible. sort(revEdges[to].begin(), revEdges[to].end()); int start = revEdges[to][0]; for (int from: revEdges[to]) { if (from != start) { ok = false; break; } start++; } if (start != to) { ok = false; break; } } vector filled(n); if (ok) { for (int to = 1; to < n; to++) { int start = -1; if (revEdges[to].size()) { start = revEdges[to][0]; } if (start == 0) { int val = 0; for (int i = 1; i < to; i++) { val = max(val, filled[i]); } filled[to] = val + 1; } else { filled[to] = filled[start]; } set blocked; for (int from: revEdges[to]) { if (from != start) { blocked.insert(filled[from]); } } if (blocked.count(filled[to])) { ok = false; break; } } } if (ok) { filled[0] = 0; for (int i = 1; i < n; i++) { printf("%d ", filled[i]); } printf("\n"); // The below lines can be commented for the solution if needed. // These lines check whether the answer we provided corresponds to a valid solution. // i.e. the automata generated by them has the above edges or not. // However it doesn't check the lexicographically smallest condition of the array filled. set > actualEdgeSet; set disVals; vector > values(n + 1); for (int i = 0; i < n; i++) { values[filled[i]].push_back(i); disVals.insert(filled[i]); } for (int i = 0; i < n; i++) { for (int x: disVals) { int j = lower_bound(values[x].begin(), values[x].end(), i + 1) - values[x].begin(); if (j != values[x].size()) { actualEdgeSet.insert(make_pair(i, values[x][j])); } } } assert(edgeSet == actualEdgeSet); } else { printf("-1\n"); } } return 0; }