#include <bits/stdc++.h>
using namespace std;
const int max_n = 1e4 + 5;
int n, m;
struct Edge_Tree {
  int to, next, id;
} edge[max_n * 2];
int head[max_n], fth[max_n], fth_id[max_n], dep[max_n];
int djs[max_n];
int Find(int x) {
  if (x == djs[x]) return x;
  return djs[x] = Find(djs[x]);
}
int vis[max_n];
void dfs1(int p) {
  vis[p] = true;
  for (int i = head[p]; i; i = edge[i].next) {
    if (vis[edge[i].to]) continue;
    fth[edge[i].to] = p;
    dep[edge[i].to] = dep[p] + 1;
    fth_id[edge[i].to] = edge[i].id;
    dfs1(edge[i].to);
  }
}
struct Query_LCA {
  int to, id;
};
vector<Query_LCA> query_lca[max_n];
struct Edge_Fail {
  int x, y, z, id;
  bool type;
} edge_fail[max_n];
int cnt = 0;
void Tarjan(int p) {
  vis[p] = 1;
  for (int i = head[p]; i; i = edge[i].next) {
    if (vis[edge[i].to]) continue;
    Tarjan(edge[i].to);
    djs[edge[i].to] = p;
  }
  for (auto it : query_lca[p])
    if (vis[it.to] == 2) edge_fail[it.id].z = Find(it.to);
  vis[p] = 2;
}
int d[max_n];
bool ans[max_n];
int flag = 0;
void dfs2(int p) {
  vis[p] = true;
  for (int i = head[p]; i; i = edge[i].next) {
    if (vis[edge[i].to]) continue;
    dfs2(edge[i].to);
    d[p] += d[edge[i].to];
  }
}
signed main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) djs[i] = i;
  for (int i = 1, tot = 1; i <= m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    if (Find(u) == Find(v))
      edge_fail[++cnt] = {u, v, 0, i, false};
    else {
      edge[++tot] = {v, head[u], i}, head[u] = tot;
      edge[++tot] = {u, head[v], i}, head[v] = tot;
      djs[Find(u)] = Find(v);
    }
  }
  for (int i = 1; i <= n; i++) vis[i] = false;
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs1(i);
  for (int i = 1; i <= cnt; i++) {
    query_lca[edge_fail[i].x].push_back({edge_fail[i].y, i});
    query_lca[edge_fail[i].y].push_back({edge_fail[i].x, i});
  }
  for (int i = 1; i <= n; i++) djs[i] = i;
  for (int i = 1; i <= n; i++) vis[i] = false;
  for (int i = 1; i <= n; i++)
    if (!vis[i]) Tarjan(i);
  for (int i = 1; i <= cnt; i++) {
    int x = edge_fail[i].x, y = edge_fail[i].y, z = edge_fail[i].z;
    if ((dep[x] + dep[y] - 2 * dep[z]) % 2 == 0) edge_fail[i].type = true;
  }
  int uni = 0;
  for (int i = 1; i <= cnt; i++)
    if (edge_fail[i].type) flag++, uni = edge_fail[i].id;
  if (flag == 0)
    for (int i = 1; i <= m; i++) ans[i] = true;
  if (flag == 1) ans[uni] = true;
  for (int i = 1; i <= cnt; i++) {
    if (edge_fail[i].type)
      d[edge_fail[i].x]++, d[edge_fail[i].y]++, d[edge_fail[i].z] -= 2;
    else
      d[edge_fail[i].x]--, d[edge_fail[i].y]--, d[edge_fail[i].z] += 2;
  }
  for (int i = 1; i <= n; i++) vis[i] = false;
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs2(i);
  for (int i = 1; i <= n; i++)
    if (d[i] == flag) ans[fth_id[i]] = true;
  int num = 0;
  for (int i = 1; i <= m; i++)
    if (ans[i]) num++;
  printf("%d\n", num);
  for (int i = 1; i <= m; i++)
    if (ans[i]) printf("%d ", i);
  return 0;
}
