#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
#define N 1010
int n,m;
int link[N],fa[N];
int base[N];//属于哪朵花
int q[N],inq[N];
int g[N][N];
int inflower[N];
int vis[N];
int head,tail;
struct node
{
int u,v;
}edge[N];
void contract(int x,int y)
{
memset(vis,0,sizeof(vis));
memset(inflower,0,sizeof(inflower));
#define pre fa[link[i]]
int lca,i;//lca公共祖先
for(i=x;i;i=pre)
{
i=base[i];
vis[i]=1;
}//找x走过的路
for(i=y;i;i=pre)
{
i=base[i];
if(vis[i])
{
lca=i;
break;
}
}//找y走过的路,若和X重叠则该点为公共祖先
for(i=x;base[i]!=lca;i=pre)
{
if(base[pre]!=lca)
fa[pre]=link[i];//对于bfs树种父边是匹配的点,那么久往下走
inflower[base[i]]=1;
inflower[base[link[i]]]=1;//将两点入花
}
for(i=y;base[i]!=lca;i=pre)
{
if(base[pre]!=lca)
fa[pre]=link[i];
inflower[base[i]]=1;
inflower[base[link[i]]]=1;
}
#undef pre
if(base[x]!=lca)
fa[x]=y;
if(base[y]!=lca)
fa[y]=x;
for(i=1;i<=n;i++)
{
if(inflower[base[i]])
{
base[i]=lca;
if(!inq[i])
{
q[tail++]=i;
inq[i]=1;
}
}
}
}
bool bfs(int u)
{
int i,j,v,f;
for(i=0;i<=n;i++)
{
fa[i]=-1;
base[i]=i;
inq[i]=0;
}
head=0,tail=1;//q.clear();
q[0]=u;
inq[u]=1;
while(head<tail)
{
int b=q[head++];
for(v=1;v<=n;v++)
{
if( g[b][v]==0 || base[b]==base[v] || link[b]==v )//当不是可连接的边,花的祖先是一样的时候,或者已经连接了的边都TMD没有意义
continue;
if( b == v || (link[v]!=-1 && fa[link[v]]!=-1))
contract(b,v);
else if(fa[v]==-1)
{
fa[v]=b;
if(link[v]!=-1)
{
q[tail++]=link[v];
inq[link[v]]=1;
}
else
{
int x,y;
while(v!=-1)
{
y=fa[v];
x=link[y];
link[y]=v;
link[v]=y;
v=x;
}
return true;
}
}
}
}
return false;
}
int maxmatch()
{
int sum=0;
memset(link,-1,sizeof(link));
for(int i=1;i<=n;i++)
{
if(link[i]==-1&&bfs(i))
sum++;
}
return sum;
}
int main()
{
//freopen("e://in.txt","r",stdin);
//freopen("e://out.txt","w",stdout);
int i,j,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(g,0,sizeof(g));
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
g[u][v] = g[v][u] =1;
edge[i].u = u;
edge[i].v = v;
}
int max=maxmatch();
vector<int>ans;
ans.clear();
for(i=1;i<=m;i++)
{
int x=edge[i].u;
int y=edge[i].v;
memset(g,0,sizeof(g));
for(j=1;j<=m;j++)
{
if(j==i)
continue;
int a=edge[j].u;
int b=edge[j].v;
if(x==a || x==b || y==a || y==b)
continue;
g[a][b]=g[b][a]=1;
}
int smax = maxmatch();
if(smax != max-1)
ans.push_back(i);
}
int sz=ans.size();
printf("%d\n",sz);
if(sz)
printf("%d",ans[0]);
for(i=1;i<sz;i++)
printf(" %d",ans[i]);
printf("\n");
}
return 0;
}
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
#define N 1010
int n,m;
int link[N],fa[N];
int base[N];//属于哪朵花
int q[N],inq[N];
int g[N][N];
int inflower[N];
int vis[N];
int head,tail;
struct node
{
int u,v;
}edge[N];
void contract(int x,int y)
{
memset(vis,0,sizeof(vis));
memset(inflower,0,sizeof(inflower));
#define pre fa[link[i]]
int lca,i;//lca公共祖先
for(i=x;i;i=pre)
{
i=base[i];
vis[i]=1;
}//找x走过的路
for(i=y;i;i=pre)
{
i=base[i];
if(vis[i])
{
lca=i;
break;
}
}//找y走过的路,若和X重叠则该点为公共祖先
for(i=x;base[i]!=lca;i=pre)
{
if(base[pre]!=lca)
fa[pre]=link[i];//对于bfs树种父边是匹配的点,那么久往下走
inflower[base[i]]=1;
inflower[base[link[i]]]=1;//将两点入花
}
for(i=y;base[i]!=lca;i=pre)
{
if(base[pre]!=lca)
fa[pre]=link[i];
inflower[base[i]]=1;
inflower[base[link[i]]]=1;
}
#undef pre
if(base[x]!=lca)
fa[x]=y;
if(base[y]!=lca)
fa[y]=x;
for(i=1;i<=n;i++)
{
if(inflower[base[i]])
{
base[i]=lca;
if(!inq[i])
{
q[tail++]=i;
inq[i]=1;
}
}
}
}
bool bfs(int u)
{
int i,j,v,f;
for(i=0;i<=n;i++)
{
fa[i]=-1;
base[i]=i;
inq[i]=0;
}
head=0,tail=1;//q.clear();
q[0]=u;
inq[u]=1;
while(head<tail)
{
int b=q[head++];
for(v=1;v<=n;v++)
{
if( g[b][v]==0 || base[b]==base[v] || link[b]==v )//当不是可连接的边,花的祖先是一样的时候,或者已经连接了的边都TMD没有意义
continue;
if( b == v || (link[v]!=-1 && fa[link[v]]!=-1))
contract(b,v);
else if(fa[v]==-1)
{
fa[v]=b;
if(link[v]!=-1)
{
q[tail++]=link[v];
inq[link[v]]=1;
}
else
{
int x,y;
while(v!=-1)
{
y=fa[v];
x=link[y];
link[y]=v;
link[v]=y;
v=x;
}
return true;
}
}
}
}
return false;
}
int maxmatch()
{
int sum=0;
memset(link,-1,sizeof(link));
for(int i=1;i<=n;i++)
{
if(link[i]==-1&&bfs(i))
sum++;
}
return sum;
}
int main()
{
//freopen("e://in.txt","r",stdin);
//freopen("e://out.txt","w",stdout);
int i,j,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(g,0,sizeof(g));
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
g[u][v] = g[v][u] =1;
edge[i].u = u;
edge[i].v = v;
}
int max=maxmatch();
vector<int>ans;
ans.clear();
for(i=1;i<=m;i++)
{
int x=edge[i].u;
int y=edge[i].v;
memset(g,0,sizeof(g));
for(j=1;j<=m;j++)
{
if(j==i)
continue;
int a=edge[j].u;
int b=edge[j].v;
if(x==a || x==b || y==a || y==b)
continue;
g[a][b]=g[b][a]=1;
}
int smax = maxmatch();
if(smax != max-1)
ans.push_back(i);
}
int sz=ans.size();
printf("%d\n",sz);
if(sz)
printf("%d",ans[0]);
for(i=1;i<sz;i++)
printf(" %d",ans[i]);
printf("\n");
}
return 0;
}