/*
zoj 2588 求割边
Tarjan算法。第一次写tarjan,完全学习别人写的。
注意点:
1.必须变成有向图存储,对于一条无向边,从一个方向访问过,则另一个方向不能访问。
2.因为两点之间可能有多条边,重边必定不是割边,需标记。
3.临界表存储。
*/
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#define N 10005
#define M 1000005
using namespace std;
int DFN[N],LOW[N],head[M],bridge[M],nbridge,k,num;
struct way
{
int next,id,v,tag;
}w[M];
void inint()
{
int i;
k=1; nbridge=0; num=1;
memset( head,0,sizeof(head) );
memset( DFN,0,sizeof(DFN) );
memset( LOW,0,sizeof(LOW) );
memset( bridge,0,sizeof(bridge) );
}
void addedge( int a,int b,int id )
{
int i;
for( i=head[a];i;i=w[i].next )
if( w[i].v==b ) break;
if(i)
{
w[i].tag=1;
return;
}
w[k].next=head[a];
w[k].id=id;
w[k].tag=0;
w[k].v=b;
head[a]=k; k++;
}
void tarjan( int sta,int father )
{
int i,v;
DFN[sta]=LOW[sta]=++num;
for( i=head[sta];i;i=w[i].next )
{
v=w[i].v;
if( !DFN[v] )
{
tarjan( v,sta );
LOW[sta]=min( LOW[sta],LOW[v] );
if( DFN[sta]<LOW[v] && !w[i].tag )
bridge[nbridge++]=w[i].id;
}
else if( v!=father ) LOW[sta]=min( LOW[sta],DFN[v] );
}
}
int main()
{
int T,m,n,i;
int a,b;
scanf( "%d",&T );
while( T-- )
{
inint();
scanf( "%d%d",&n,&m );
for( i=0;i<m;i++ )
{
scanf( "%d%d",&a,&b );
addedge( a,b,i+1 );
addedge( b,a,i+1 );
}
tarjan( 1,-1 );
printf("%d\n",nbridge);
if(nbridge)
{
sort( bridge,bridge+nbridge );
for(i=0;i<nbridge-1;i++)
printf("%d ",bridge[i]);
printf("%d\n",bridge[nbridge-1]);
}
if(T) printf("\n");
}
return 0;
}