#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
using namespace std;
inline char nc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline int GetInt() {
  char ch = nc();
  int sum = 0;
  while (!(ch >= '0' && ch <= '9')) ch = nc();
  while (ch >= '0' && ch <= '9') sum = sum * 10 + ch - 48, ch = nc();
  return sum;
}
static char buf[100000];
char* p = buf;
inline void pc(char a) {
  if (p == buf + 100000) fwrite(buf, 1, 100000, stdout), p = buf;
  *p = a;
  ++p;
  return;
}
inline void Putint(int x) {
  if (!x) return;
  Putint(x / 10);
  pc(x % 10 + '0');
  return;
}
inline void PutInt(int x) {
  if (!x)
    putchar('0');
  else
    Putint(x);
}
struct Node {
  int to, next, id;
} e[2000005];
int s[1000005], t[1000005], dep[1000005], h[1000005], cnt = 0, sum = 0;
inline void Addedge(int x, int y, int id) {
  e[++cnt] = (Node){y, h[x], id};
  h[x] = cnt;
  return;
}
bool vis[1000005], tree[1000005];
stack<int> si, sx, s1, s2, sv;
inline void dfs1(int x) {
  int i, v, y;
CALL1:
  vis[x] = true;
  for (i = h[x]; i; i = e[i].next) {
    y = e[i].to;
    v = e[i].id;
    if (vis[y]) continue;
    dep[y] = dep[x] + 1;
    tree[v] = true;
    si.push(i);
    sx.push(x);
    x = y;
    goto CALL1;
  RET1:;
  }
  if (si.empty()) return;
  i = si.top();
  si.pop();
  x = sx.top();
  sx.pop();
  goto RET1;
}
vector<int> ans;
inline void dfs2(int x) {
  int i, v, y, sum1, sum2;
  pair<int, int> tmp;
CALL2:
  sum1 = 0, sum2 = 0;
  vis[x] = true;
  for (i = h[x]; i; i = e[i].next) {
    y = e[i].to;
    v = e[i].id;
    if (!tree[v] || vis[y]) continue;
    si.push(i);
    sx.push(x);
    s1.push(sum1);
    s2.push(sum2);
    sv.push(v);
    x = y;
    goto CALL2;
  RET2:
    if (tmp.first == sum && !tmp.second) ans.push_back(v);
    sum1 += tmp.first;
    sum2 += tmp.second;
  }
  tmp = make_pair(sum1 + s[x], sum2 + t[x]);
  if (si.empty()) return;
  i = si.top();
  si.pop();
  x = sx.top();
  sx.pop();
  sum1 = s1.top();
  s1.pop();
  sum2 = s2.top();
  s2.pop();
  v = sv.top();
  sv.pop();
  goto RET2;
}
struct node {
  int x, y;
} a[1000005];
int main(void) {
  int i, j, x, y, n = GetInt(), m = GetInt();
  for (i = 1; i <= m; ++i) {
    a[i].x = GetInt();
    a[i].y = GetInt();
    Addedge(a[i].x, a[i].y, i);
    Addedge(a[i].y, a[i].x, i);
  }
  for (i = 1; i <= n; ++i)
    if (!vis[i]) dfs1(i);
  for (i = 1; i <= m; ++i) {
    x = a[i].x;
    y = a[i].y;
    if (tree[i]) continue;
    if (dep[x] > dep[y]) swap(x, y);
    if ((dep[y] - dep[x]) & 1) {
      ++t[y];
      --t[x];
    } else {
      ++sum;
      ++s[y];
      --s[x];
    }
  }
  if (sum == 1) {
    for (i = 1; i <= m; ++i) {
      x = a[i].x;
      y = a[i].y;
      if (tree[i]) continue;
      if ((dep[y] - dep[x]) % 2 == 0) ans.push_back(i);
    }
  }
  if (!sum) {
    PutInt(m);
    pc('\n');
    for (i = 1; i <= m; ++i) PutInt(i), pc(' ');
    fwrite(buf, 1, (p - buf), stdout);
    return 0;
  }
  memset(vis, 0, sizeof(vis));
  for (i = 1; i <= n; ++i)
    if (!vis[i]) dfs2(i);
  sort(ans.begin(), ans.end());
  PutInt(ans.size());
  pc('\n');
  for (i = 0; i < ans.size(); ++i) PutInt(ans[i]), pc(' ');
  pc('\n');
  fwrite(buf, 1, (p - buf), stdout);
  return 0;
}
