#include <bits/stdc++.h>
using namespace std;
const int INF = 2e9;
const long long LINF = 2e16;
const int magic = 348;
const int MOD = 1e9 + 7;
const double eps = 1e-10;
const double pi = acos(-1);
struct fastio {
  static const int S = 1e7;
  char rbuf[S + 48], wbuf[S + 48];
  int rpos, wpos, len;
  fastio() { rpos = len = wpos = 0; }
  inline char Getchar() {
    if (rpos == len) rpos = 0, len = fread(rbuf, 1, S, stdin);
    if (!len) return EOF;
    return rbuf[rpos++];
  }
  template <class T>
  inline void Get(T &first) {
    char ch;
    bool f;
    T res;
    while (!isdigit(ch = Getchar()) && ch != '-') {
    }
    if (ch == '-')
      f = false, res = 0;
    else
      f = true, res = ch - '0';
    while (isdigit(ch = Getchar())) res = res * 10 + ch - '0';
    first = (f ? res : -res);
  }
  inline void getstring(char *s) {
    char ch;
    while ((ch = Getchar()) <= 32) {
    }
    for (; ch > 32; ch = Getchar()) *s++ = ch;
    *s = '\0';
  }
  inline void flush() {
    fwrite(wbuf, 1, wpos, stdout);
    fflush(stdout);
    wpos = 0;
  }
  inline void Writechar(char ch) {
    if (wpos == S) flush();
    wbuf[wpos++] = ch;
  }
  template <class T>
  inline void Print(T first, char ch) {
    char s[20];
    int pt = 0;
    if (first == 0)
      s[++pt] = '0';
    else {
      if (first < 0) Writechar('-'), first = -first;
      while (first) s[++pt] = '0' + first % 10, first /= 10;
    }
    while (pt) Writechar(s[pt--]);
    Writechar(ch);
  }
  inline void printstring(char *s) {
    int pt = 1;
    while (s[pt] != '\0') Writechar(s[pt++]);
  }
} io;
template <typename T>
inline void check_max(T &first, T cmp) {
  first = max(first, cmp);
}
template <typename T>
inline void check_min(T &first, T cmp) {
  first = min(first, cmp);
}
template <typename T>
inline T myabs(T first) {
  return first >= 0 ? first : -first;
}
template <typename T>
inline T gcd(T first, T second) {
  return second == 0 ? first : gcd(second, first % second);
}
inline int add(int first) {
  if (first >= MOD) first -= MOD;
  return first;
}
inline int add(int first, int MO) {
  if (first >= MO) first -= MO;
  return first;
}
inline int sub(int first) {
  if (first < 0) first += MOD;
  return first;
}
inline int sub(int first, int MO) {
  if (first < 0) first += MO;
  return first;
}
inline void Add(int &first, int second) { first = add(first + second); }
inline void Add(int &first, int second, int MO) {
  first = add(first + second, MO);
}
inline void Sub(int &first, int second) { first = sub(first - second); }
inline void Sub(int &first, int second, int MO) {
  first = sub(first - second, MO);
}
template <typename T>
inline int quick_pow(int first, T second) {
  int res = 1;
  while (second) {
    if (second & 1) res = 1ll * res * first % MOD;
    first = 1ll * first * first % MOD;
    second >>= 1;
  }
  return res;
}
template <typename T>
inline int quick_pow(int first, T second, int MO) {
  int res = 1;
  while (second) {
    if (second & 1) res = 1ll * res * first % MO;
    first = 1ll * first * first % MO;
    second >>= 1;
  }
  return res;
}
const int MAXN = 1e4;
int n, m;
vector<pair<int, int> > v[MAXN + 48];
bool intree[MAXN + 48], vv[MAXN + 48];
int fa[MAXN + 48], faind[MAXN + 48], son[MAXN + 48], sz[MAXN + 48],
    depth[MAXN + 48], top[MAXN + 48];
int tpos[MAXN + 48], seq[MAXN + 48], ind;
inline void dfs1(int cur, int father) {
  fa[cur] = father;
  sz[cur] = 1;
  son[cur] = 0;
  vv[cur] = true;
  for (register int i = 0; i < int(v[cur].size()); i++) {
    int second = v[cur][i].first;
    if (!intree[v[cur][i].second]) continue;
    if (second != father) {
      depth[second] = depth[cur] + 1;
      faind[second] = v[cur][i].second;
      dfs1(second, cur);
      sz[cur] += sz[second];
      if (!son[cur] || sz[son[cur]] < sz[second]) son[cur] = second;
    }
  }
}
inline void dfs2(int cur, int tp) {
  seq[++ind] = cur;
  tpos[cur] = ind;
  top[cur] = tp;
  if (son[cur]) dfs2(son[cur], tp);
  for (register int i = 0; i < int(v[cur].size()); i++) {
    int second = v[cur][i].first;
    if (!intree[v[cur][i].second]) continue;
    if (second != fa[cur] && second != son[cur]) dfs2(second, second);
  }
}
namespace SegmentTree {
int lazy[MAXN * 4];
inline void init() {
  for (register int i = 1; i <= ind * 4; i++) lazy[i] = 0;
}
inline void pushdown(int cur) {
  lazy[cur << 1] += lazy[cur];
  lazy[cur << 1 | 1] += lazy[cur];
  lazy[cur] = 0;
}
inline void modify(int cur, int left, int right, int delta, int l, int r) {
  if (left > right) return;
  if (left <= l && r <= right) {
    lazy[cur] += delta;
    return;
  }
  pushdown(cur);
  int mid = (l + r) >> 1;
  if (left <= mid) modify(cur << 1, left, right, delta, l, mid);
  if (mid + 1 <= right) modify(cur << 1 | 1, left, right, delta, mid + 1, r);
}
inline int query(int cur, int pos, int l, int r) {
  if (l == r) return lazy[cur];
  pushdown(cur);
  int mid = (l + r) >> 1;
  if (pos <= mid)
    return query(cur << 1, pos, l, mid);
  else
    return query(cur << 1 | 1, pos, mid + 1, r);
}
}  // namespace SegmentTree
inline void update(int u, int v, int delta) {
  int tp1 = top[u], tp2 = top[v];
  while (tp1 != tp2) {
    if (depth[tp1] < depth[tp2]) {
      swap(u, v);
      swap(tp1, tp2);
    }
    SegmentTree::modify(1, tpos[tp1], tpos[u], delta, 1, ind);
    u = fa[tp1];
    tp1 = top[u];
  }
  if (depth[u] < depth[v]) swap(u, v);
  SegmentTree::modify(1, tpos[v] + 1, tpos[u], delta, 1, ind);
}
int cntodd, fnum, visited[MAXN + 48], d[MAXN + 48];
vector<pair<int, int> > Odd, Even;
inline void Dfs(int cur, int father) {
  visited[cur] = 1;
  for (register int i = 0; i < int(v[cur].size()); i++) {
    int second = v[cur][i].first;
    if (!visited[second]) {
      d[second] = d[cur] + 1;
      intree[v[cur][i].second] = true;
      Dfs(second, cur);
    } else if (second != father && visited[second] == 1) {
      if ((d[cur] & 1) == (d[second] & 1)) {
        cntodd++;
        Odd.push_back(make_pair(cur, second));
        if (cntodd == 1) fnum = v[cur][i].second;
      } else
        Even.push_back(make_pair(cur, second));
    }
  }
  visited[cur] = 2;
}
vector<int> edge;
int main() {
  io.Get(n);
  io.Get(m);
  int first, second;
  for (register int i = 1; i <= m; i++) {
    io.Get(first);
    io.Get(second);
    v[first].push_back(make_pair(second, i));
    v[second].push_back(make_pair(first, i));
  }
  int ocnt = 0;
  for (register int i = 1; i <= n; i++)
    if (!vv[i]) {
      int tmp = cntodd;
      d[i] = 1;
      Dfs(i, -1);
      if (cntodd != tmp)
        ocnt++;
      else
        continue;
      depth[i] = 1;
      dfs1(i, -1);
      ind = 0;
      dfs2(i, i);
      for (auto item : Odd) update(item.first, item.second, 1);
      for (auto item : Even) update(item.first, item.second, -1);
    }
  if (ocnt > 1) {
    printf("0\n");
    return 0;
  }
  if (!cntodd) {
    printf("%d\n", m);
    for (register int i = 1; i <= m; i++) printf("%d ", i);
    printf("\n");
    return 0;
  }
  int Ans = 0;
  for (register int i = 2; i <= n; i++)
    if (tpos[i] && SegmentTree::query(1, tpos[i], 1, ind) == cntodd)
      Ans++, edge.push_back(faind[i]);
  if (cntodd == 1) Ans++, edge.push_back(fnum);
  printf("%d\n", Ans);
  sort(edge.begin(), edge.end());
  for (register int i = 0; i < int(edge.size()); i++) printf("%d ", edge[i]);
  printf("\n");
  io.flush();
  return 0;
}
