#include <bits/stdc++.h>
struct in_t {
  static const int SZ = 1 << 20;
  char buf[SZ], *s, *t;
  inline in_t() {}
  inline in_t(const char *path) { freopen(path, "r", stdin); }
  inline char gc() {
    if (s == t) t = (s = buf) + fread(buf, 1, SZ, stdin);
    return s == t ? ' ' : *s++;
  }
  template <typename T>
  void readI(T &x) {
    x = 0;
    bool f = 0;
    char c = gc();
    for (; c < '0'; c = gc())
      if (c == '-') f = 1;
    for (; c >= '0'; c = gc()) x = x * 10 + (c & 15);
    if (f) x = -x;
  }
  in_t &operator>>(int &x) { return readI(x), *this; };
} in;
const int N = 1e6 + 61;
struct rec {
  int *p, v;
};
std::stack<rec> st;
void set(int &x, int y) { st.push((rec){&x, x}), x = y; }
int n, _p[N], d[N];
int f(int x) { return x[_p] ? f(x[_p]) : x; }
void mg(int x, int y) {
  if ((x = f(x)) != (y = f(y))) {
    if (x[d] > y[d]) std::swap(x, y);
    set(x[_p], y), set(y[d], y[d] + (x[d] == y[d]));
  }
}
int u[N], v[N], ql, qr, a1, a2;
std::vector<int> opr[N << 2], ans;
void ins(int x, int l, int r, int y) {
  if (ql <= l && r <= qr) return x[opr].push_back(y);
  if (ql <= (l + r) / 2) ins((x << 1), l, (l + r) / 2, y);
  if ((l + r) / 2 < qr) ins(((x << 1) | 1), (l + r) / 2 + 1, r, y);
}
void dfs(int x, int l, int r) {
  int sz = st.size();
  for (int i = 0; i < x[opr].size(); i++) {
    int p = u[x[opr][i]], q = v[x[opr][i]];
    if (f(p) == f(q)) goto end;
    mg(p, q + n), mg(q, p + n);
  }
  if (l == r)
    a1++, ans.push_back(l);
  else
    dfs((x << 1), l, (l + r) / 2), dfs(((x << 1) | 1), (l + r) / 2 + 1, r);
end:
  for (; st.size() > sz; st.pop()) *st.top().p = st.top().v;
}
int m, x, y;
int main() {
  in >> n >> m;
  if (!m) return fputs("ctrnmsl", stderr), puts("0"), 0;
  for (int i = 1; i <= m; i++) {
    in >> u[i] >> v[i];
    if (1 < i) ql = 1, qr = i - 1, ins(1, 1, m, i);
    if (i < m) ql = i + 1, qr = m, ins(1, 1, m, i);
  }
  dfs(1, 1, m);
  printf("%d\n", a1);
  for (int i : ans) printf("%d ", i);
  puts("");
}
