#include <bits/stdc++.h>   #pragma GCC optimize( Ofast )   #pragma GCC target( avx,avx2,fma )   using namespace std;   typedef int ll;   const ll MAX = 1e3;   const ll mod = 1e4;   const ll inf = 1e9;   struct FlowEdge {     int v, u;     int cap, flow = 0;     FlowEdge(int v, int u, int cap) : v(v), u(u), cap(cap) {}   };   struct Dinic {     const int flow_inf = 1e9;     vector<FlowEdge> edges;     vector<vector<int>> adj;     int n, m = 0;     int s, t;     vector<int> level, ptr;     queue<int> q;     Dinic(int n, int s, int t) : n(n), s(s), t(t) {       adj.resize(n);       level.resize(n);       ptr.resize(n);     }     void add_edge(int v, int u, int cap) {       edges.emplace_back(v, u, cap);       edges.emplace_back(u, v, 0);       adj[v].push_back(m);       adj[u].push_back(m + 1);       m += 2;     }     bool bfs() {       while (!q.empty()) {         int v = q.front();         q.pop();         for (int id : adj[v]) {           if (edges[id].cap - edges[id].flow < 1) continue;           if (level[edges[id].u] != -1) continue;           level[edges[id].u] = level[v] + 1;           q.push(edges[id].u);         }       }       return level[t] != -1;     }     int dfs(int v, int pushed) {       if (pushed == 0) return 0;       if (v == t) return pushed;       for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) {         int id = adj[v][cid];         int u = edges[id].u;         if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)           continue;         int tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));         if (tr == 0) continue;         edges[id].flow += tr;         edges[id ^ 1].flow -= tr;         return tr;       }       return 0;     }     int flow() {       int f = 0;       while (true) {         fill(level.begin(), level.end(), -1);         level[s] = 0;         q.push(s);         if (!bfs()) break;         fill(ptr.begin(), ptr.end(), 0);         while (int pushed = dfs(s, flow_inf)) {           f += pushed;         }       }       return f;     }   };   int c[MAX], ans[MAX];   vector<ll> adj[MAX];   int main() {     ios_base::sync_with_stdio(false);     cin.tie(NULL);     int tc, n, m, k, s, t, u, v;     cin >> tc;     while (tc--) {       cin >> n >> m >> k;       s = 0, t = n + m + 1;       Dinic dinic(n + m + 2, s, t);       for (ll i = 1; i < (ll)m + 1; i++) {         cin >> u >> v;         c[u]++, c[v]++;         dinic.add_edge(n + i, t, 1);         dinic.add_edge(u, n + i, 1);         dinic.add_edge(v, n + i, 1);       }       int to = 0;       for (ll i = 1; i < (ll)n + 1; i++)         if (c[i] > k) dinic.add_edge(s, i, 2 * (c[i] - k)), to += 2 * (c[i] - k);       if (dinic.flow() == to) {         for (FlowEdge it : dinic.edges) {           if (1 <= it.v && it.v <= n && n + 1 <= it.u && it.u <= n + m &&               it.flow == 1) {             adj[it.v].push_back(it.u - n);           }         }         ll col = 1;         for (ll i = 1; i < (ll)n + 1; i++) {           for (ll j = 0; j < (ll)adj[i].size(); j += 2)             ans[adj[i][j]] = ans[adj[i][j + 1]] = col++;         }         for (ll i = 1; i < (ll)m + 1; i++)           if (ans[i] == 0) ans[i] = col++;       }       for (ll i = 1; i < (ll)m + 1; i++) cout << ans[i] <<    , ans[i] = 0;       cout << endl;       for (ll i = 1; i < (ll)n + 1; i++) adj[i].clear(), c[i] = 0;     }     return 0;   }