#include<bits/stdc++.h> using namespace std; typedef long long int uli; struct edge{int v,i;}; const int mxv=66; const int mxe=mxv*mxv; int n,m; vector<edge>g[mxv]; int us[mxe],vs[mxe],col[mxe]; bool vis[mxv],vise[mxe]; vector<edge>tree[2][mxv]; int par[2][mxv],ear[2][mxv]; int ti[2][mxv],to[2][mxv],T=0; bool connector[mxe]; vector<int>bip[mxe]; vector<int>lyr[mxv]; vector<edge>eul[mxv]; list<edge>lst; //find eulerian path void epath(int u,list<edge>::iterator it){ while(!eul[u].empty()){ edge to=eul[u].back(); eul[u].pop_back(); if(vise[to.i])continue; it=lst.insert(it,to); auto nit=it; nit++; vise[to.i]=true; epath(to.v,nit); } } void dfs(int u,int c){ vis[u]=true; for(auto e:g[u])if(!vis[e.v] && col[e.i]==-1){ col[e.i]=c; dfs(e.v,c); } } void root(int u,int pu,int c,int l=0){ lyr[l].push_back(u); ti[c][u]=T++; par[c][u]=pu; for(auto e:tree[c][u])if(e.v!=pu){ ear[c][e.v]=e.i; root(e.v,u,c,l+1); } to[c][u]=T++; } bool child(int v,int u,int c){ return ti[c][u]<=ti[c][v] && ti[c][v]<=to[c][u]; } int lca(int u,int v,int c){ while(!child(v,u,c) && u!=par[c][u]){ u=par[c][u]; } if(!child(v,u,c))return -1; return u; } void trees(){ for(int it=0;it<2;it++)for(int i=0;i<n;i++){ tree[it][i].clear(); par[it][i]=ear[it][i]=-1; } for(int i=0;i<m;i++){ int c=col[i]; if(c!=-1){ int u=us[i],v=vs[i]; tree[c][u].push_back({v,i}); tree[c][v].push_back({u,i}); } } T=0; for(int i=0;i<n;i++)if(par[1][i]==-1)root(i,i,1); T=0; for(int i=0;i<n;i++)lyr[i].clear(); root(0,0,0); memset(connector,false,sizeof connector); for(int i=0;i<m;i++)if(col[i]==0)if(lca(us[i],vs[i],1)==-1)connector[i]=true; } int d[mxe]; int pbfs[mxe]; void addEdge(int e,int c){ int u=us[e],v=vs[e]; int w=lca(u,v,c^1); if(w==-1)return; for(int x:{u,v}){ int y=x; while(y!=w){ int f=ear[c^1][y]; bip[e].push_back(f); y=par[c^1][y]; d[e]=d[f]=-1; pbfs[e]=pbfs[f]=-1; } } } int bfs(int u){ d[u]=0; queue<int>q; q.push(u); pbfs[u]=u; int idx=-1; while(!q.empty()){ u=q.front(); q.pop(); if(connector[u]) if(idx==-1 || d[u]<d[idx]) idx=u; for(int v:bip[u])if(d[v]==-1){ d[v]=1+d[u]; pbfs[v]=u; q.push(v); } } return idx; } int p[mxv]; int gp(int u){ return (u==p[u]?u:p[u]=gp(p[u])); } int main(){ int t; scanf("%d",&t); for(int tt=1;tt<=t;tt++){ T=0; scanf("%d %d",&n,&m); for(int i=0;i<n;i++)g[i].clear(); for(int i=0;i<m;i++){ int u,v; scanf("%d %d",&u,&v); --u,--v; g[u].push_back({v,i}); g[v].push_back({u,i}); us[i]=u,vs[i]=v,col[i]=-1; } memset(vis,false,sizeof vis); dfs(0,0); memset(vis,false,sizeof vis); for(int i=0;i<n;i++)if(!vis[i])dfs(i,1); for(int e=0;e<m;e++)if(col[e]==-1){ trees(); for(int i=0;i<m;i++){ bip[i].clear(); vise[i]=false; } for(int i=0;i<m;i++)if(col[i]!=-1){ addEdge(i,col[i]); } addEdge(e,0); addEdge(e,1); int x=bfs(e); if(x!=-1){ while(pbfs[x]!=e){ col[x]^=1; x=pbfs[x]; } col[x]^=1; col[e]=(col[x]^1); } } trees(); for(int it=0;it<2;it++){//check two connected spanning trees iota(p,p+n,0); for(int i=0;i<m;i++)if(col[i]==it)p[gp(us[i])]=gp(vs[i]); for(int i=0;i<n;i++)assert(gp(i)==gp(0)); } for(int i=0;i<n;i++)eul[i].clear(); for(int u=0;u<n;u++)for(auto e:tree[1][u]){ eul[u].push_back({e.v,e.i});//adding green edges } for(int l=n;l>0;l--){ for(int u:lyr[l]){ if(eul[u].size()%2==1){ int pu=par[0][u]; int eu=ear[0][u]; eul[u].push_back({pu,eu}); eul[pu].push_back({u,eu}); } } } memset(vise,false,sizeof vise); lst.clear(); epath(0,lst.begin()); assert((int)lst.size()<=m); printf("%d",(int)lst.size()); for(auto e:lst)printf(" %d",e.i+1); puts(""); } return 0; }