#include using namespace std; const int MaxN = 1e6 + 16; int nextEdge[MaxN], lastEdge[MaxN]; int dpStart[2][MaxN]; int dpEnd[2][MaxN]; bool cStart[2][MaxN], cEnd[2][MaxN]; int number[MaxN]; int a[MaxN], b[MaxN]; long long ans1[MaxN], ans2[MaxN]; int all; int n, m; bool isOnCycle[MaxN]; bool used[MaxN]; vector myStack; void addEdge(int x, int y, int num) { number[all] = num; a[all] = x, b[all] = y; nextEdge[all] = lastEdge[x]; lastEdge[x] = all; ++all; } void clear() { for(int i = 0; i <= all; ++i) { nextEdge[i] = 0; a[i] = b[i] = 0; ans1[i] = ans2[i] = 0; for(int j = 0; j < 2; ++j) { dpStart[j][i] = dpEnd[j][i] = 0; cStart[j][i] = cEnd[j][i] = false; } isOnCycle[i] = false; } for(int i = 1; i <= n; ++i) used[i] = 0; all = n = m = 0; } void paintCycle() { int endPoint = b[myStack.back()]; for(int i = myStack.size() - 1; i >= 0; --i) { isOnCycle[number[myStack[i]]] = true; if(a[myStack[i]] == endPoint) break; } } void findCycles(int x, int pEdge) { used[x] = true; for(int i = lastEdge[x]; i >= 0; i = nextEdge[i]) if(number[i] != pEdge) { int to = b[i]; if(!used[to]) { myStack.push_back(i); findCycles(to, number[i]); myStack.pop_back(); } else { if(!isOnCycle[number[i]]) { myStack.push_back(i); paintCycle(); myStack.pop_back(); } } } } void calcStart0(int x) { if(cStart[0][x]) return; cStart[0][x] = true; if(isOnCycle[number[x]]) return; dpStart[0][x] = 1; for(int i = lastEdge[b[x]]; i >= 0; i = nextEdge[i]) if(number[i] != number[x]) { calcStart0(i); dpStart[0][x] += dpStart[0][i]; } } void calcEnd0(int x) { if(cEnd[0][x]) return; cEnd[0][x] = true; if(isOnCycle[number[x]]) return; dpEnd[0][x] = 1; for(int i = lastEdge[a[x]]; i >= 0; i = nextEdge[i]) if(number[i] != number[x]) { calcEnd0(i ^ 1); dpEnd[0][x] += dpEnd[0][i ^ 1]; } } void calcStart1(int x) { if(cStart[1][x]) return; cStart[1][x] = true; for(int i = lastEdge[b[x]]; i >= 0; i = nextEdge[i]) if(number[i] != number[x]) { if(isOnCycle[number[x]]) { calcStart0(i); dpStart[1][x] += dpStart[0][i]; }else { calcStart1(i); dpStart[1][x] += dpStart[1][i]; } } if(isOnCycle[number[x]]) dpStart[1][x]++; } void calcEnd1(int x) { if(cEnd[1][x]) return; cEnd[1][x] = true; for(int i = lastEdge[a[x]]; i >= 0; i = nextEdge[i]) if(number[i] != number[x]) { if(isOnCycle[number[x]]) { calcEnd0(i ^ 1); dpEnd[1][x] += dpEnd[0][i ^ 1]; }else { calcEnd1(i ^ 1); dpEnd[1][x] += dpEnd[1][i ^ 1]; } } if(isOnCycle[number[x]]) dpEnd[1][x]++; } void calcAns(int x) { if(!isOnCycle[number[x]]) { if(a[x] < b[x]) { ans1[number[x]] += dpEnd[0][x] * 1ll * dpStart[0][x]; ans1[number[x]] += dpEnd[1][x] * 1ll * dpStart[0][x]; ans1[number[x]] += dpEnd[0][x] * 1ll * dpStart[1][x]; } }else { if(a[x] < b[x]) ans1[number[x]] += dpEnd[1][x] * 1ll * dpStart[1][x]; } } void solve() { cin >> n >> m; for(int i = 0; i <= n; ++i) lastEdge[i] = -1; for(int i = 1; i <= m; ++i) { int x, y; cin >> x >> y; addEdge(x, y, i); addEdge(y, x, i); } for(int i = 1; i <= n; ++i) if(!used[i]) findCycles(i, -1); for(int i = 0; i < all; ++i) calcStart0(i), calcEnd0(i); for(int i = 0; i < all; ++i) calcStart1(i), calcEnd1(i); for(int i = 0; i < all; ++i) calcAns(i); for(int i = 1; i <= m; ++i) cout << ans1[i] + ans2[i] << '\n'; } int main() { // freopen("input.txt", "r", stdin); ios_base :: sync_with_stdio(false); cin.tie(NULL); int t; cin >> t; while(t--) { solve(); clear(); } return 0; }