#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const long long LINF = 2e16;
const int INF = 2e9;
const int magic = 348;
const double eps = 1e-10;
const double pi = 3.14159265;
inline int getint() {
  char ch;
  int res;
  bool f;
  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';
  return f ? res : -res;
}
int n, e;
pair<int, int> edge[10048];
vector<pair<int, int> > v[10048];
int ansnum;
vector<int> ans;
struct Edge {
  int first, second;
  int ind;
};
vector<Edge> tedge, ntgedge, ntbedge;
int fa[10048], fa_ind[10048];
bool visited[10048];
int num[10048];
vector<int> vv[10048];
int tot;
int dep[10048], depth[10048], sz[10048], son[10048], ffa[10048];
int tpos[10048], ind = 0, top[10048];
int anc[10048][21];
void dfs(int cur) {
  visited[cur] = true;
  if (!fa[cur]) num[fa_ind[cur]] = ++tot;
  int i, j, to;
  for (i = 0; i < int(v[cur].size()); i++) {
    to = v[cur][i].first;
    if (!visited[to]) {
      fa[to] = cur;
      fa_ind[to] = v[cur][i].second;
      tedge.push_back(Edge{cur, to, v[cur][i].second});
      num[v[cur][i].second] = ++tot;
      anc[to][0] = cur;
      dep[to] = dep[cur] + 1;
      for (j = 1; j <= 20; j++) anc[to][j] = anc[anc[to][j - 1]][j - 1];
      dfs(to);
      vv[num[fa_ind[cur]]].push_back(num[v[cur][i].second]);
    } else {
      if (to != fa[cur] && dep[cur] > dep[to]) {
        if (!((dep[cur] - dep[to]) & 1))
          ntbedge.push_back(Edge{to, cur, v[cur][i].second});
        else
          ntgedge.push_back(Edge{to, cur, v[cur][i].second});
      }
    }
  }
}
void dfs1(int cur, int father) {
  ffa[cur] = father;
  sz[cur] = 1;
  son[cur] = 0;
  int i, to, max_size = -1;
  for (i = 0; i < int(vv[cur].size()); i++) {
    to = vv[cur][i];
    depth[to] = depth[cur] + 1;
    dfs1(to, cur);
    sz[cur] += sz[to];
    if (sz[to] > max_size) {
      max_size = sz[to];
      son[cur] = to;
    }
  }
}
void dfs2(int cur, int tp) {
  top[cur] = tp;
  tpos[cur] = ++ind;
  if (son[cur]) dfs2(son[cur], tp);
  int i;
  for (i = 0; i < int(vv[cur].size()); i++)
    if (vv[cur][i] != son[cur]) dfs2(vv[cur][i], vv[cur][i]);
}
struct node {
  int left, right;
  int cnt;
} tree_good[40048], tree_bad[40048];
void build_good(int cur, int left, int right) {
  tree_good[cur].left = left;
  tree_good[cur].right = right;
  tree_good[cur].cnt = 0;
  if (left != right) {
    int mid = (left + right) >> 1;
    build_good(cur << 1, left, mid);
    build_good(cur << 1 | 1, mid + 1, right);
  }
}
void build_bad(int cur, int left, int right) {
  tree_bad[cur].left = left;
  tree_bad[cur].right = right;
  tree_bad[cur].cnt = 0;
  if (left != right) {
    int mid = (left + right) >> 1;
    build_bad(cur << 1, left, mid);
    build_bad(cur << 1 | 1, mid + 1, right);
  }
}
void update_good(int cur, int left, int right) {
  if (left <= tree_good[cur].left && tree_good[cur].right <= right) {
    tree_good[cur].cnt++;
    return;
  }
  int mid = (tree_good[cur].left + tree_good[cur].right) >> 1;
  if (left <= mid) update_good(cur << 1, left, right);
  if (mid + 1 <= right) update_good(cur << 1 | 1, left, right);
}
void update_bad(int cur, int left, int right) {
  if (left <= tree_bad[cur].left && tree_bad[cur].right <= right) {
    tree_bad[cur].cnt++;
    return;
  }
  int mid = (tree_bad[cur].left + tree_bad[cur].right) >> 1;
  if (left <= mid) update_bad(cur << 1, left, right);
  if (mid + 1 <= right) update_bad(cur << 1 | 1, left, right);
}
int query_good(int cur, int pos) {
  if (tree_good[cur].left == tree_good[cur].right) return tree_good[cur].cnt;
  int mid = (tree_good[cur].left + tree_good[cur].right) >> 1;
  if (pos <= mid)
    return query_good(cur << 1, pos) + tree_good[cur].cnt;
  else
    return query_good(cur << 1 | 1, pos) + tree_good[cur].cnt;
}
int query_bad(int cur, int pos) {
  if (tree_bad[cur].left == tree_bad[cur].right) return tree_bad[cur].cnt;
  int mid = (tree_bad[cur].left + tree_bad[cur].right) >> 1;
  if (pos <= mid)
    return query_bad(cur << 1, pos) + tree_bad[cur].cnt;
  else
    return query_bad(cur << 1 | 1, pos) + tree_bad[cur].cnt;
}
void doit_good(int u, int v) {
  int tp1 = top[u], tp2 = top[v];
  while (tp1 != tp2) {
    if (depth[tp1] < depth[tp2]) {
      swap(u, v);
      swap(tp1, tp2);
    }
    update_good(1, tpos[tp1], tpos[u]);
    u = ffa[tp1];
    tp1 = top[u];
  }
  if (depth[u] < depth[v]) swap(u, v);
  update_good(1, tpos[v], tpos[u]);
}
void doit_bad(int u, int v) {
  int tp1 = top[u], tp2 = top[v];
  while (tp1 != tp2) {
    if (depth[tp1] < depth[tp2]) {
      swap(u, v);
      swap(tp1, tp2);
    }
    update_bad(1, tpos[tp1], tpos[u]);
    u = ffa[tp1];
    tp1 = top[u];
  }
  if (depth[u] < depth[v]) swap(u, v);
  update_bad(1, tpos[v], tpos[u]);
}
int lca(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  int i;
  for (i = 20; i >= 0; i--)
    if (dep[anc[u][i]] >= dep[v]) u = anc[u][i];
  if (u == v) return u;
  for (i = 20; i >= 0; i--)
    if (anc[u][i] != anc[v][i]) {
      u = anc[u][i];
      v = anc[v][i];
    }
  return anc[u][0];
}
int getbelow(int u, int v) {
  int i;
  for (i = 20; i >= 0; i--)
    if (dep[anc[u][i]] > dep[v]) u = anc[u][i];
  return u;
}
pair<int, int> query_node(int u, int v) {
  int LCA = lca(u, v);
  if (LCA != u && LCA != v) return make_pair(num[fa_ind[u]], num[fa_ind[v]]);
  if (dep[u] < dep[v]) swap(u, v);
  int tmp = getbelow(u, v);
  return make_pair(num[fa_ind[u]], num[fa_ind[tmp]]);
}
int main() {
  int i, j, cur, first, second;
  int wei;
  n = getint();
  e = getint();
  for (i = 1; i <= e; i++) {
    first = getint();
    second = getint();
    if (i == 1) wei = first;
    edge[i] = make_pair(first, second);
    v[first].push_back(make_pair(second, i));
    v[second].push_back(make_pair(first, i));
  }
  memset(visited, false, sizeof(visited));
  int all_cnt = 0;
  ansnum = 0;
  for (cur = 1; cur <= n; cur++) {
    if (!visited[cur]) {
      for (j = 1; j <= tot; j++) vv[j].clear();
      tot = 0;
      fa[cur] = fa_ind[cur] = 0;
      dep[cur] = 1;
      tedge.clear();
      ntgedge.clear();
      ntbedge.clear();
      dfs(cur);
      depth[cur] = 1;
      dfs1(1, 0);
      ind = 0;
      dfs2(1, 1);
      if (!int(ntbedge.size())) continue;
      all_cnt++;
      if (int(ntbedge.size()) == 1) {
        ansnum++;
        ans.push_back(ntbedge[0].ind);
      }
      build_good(1, 1, ind);
      build_bad(1, 1, ind);
      for (i = 0; i < int(ntgedge.size()); i++) {
        pair<int, int> res = query_node(ntgedge[i].first, ntgedge[i].second);
        doit_good(res.first, res.second);
      }
      for (i = 0; i < int(ntbedge.size()); i++) {
        pair<int, int> res = query_node(ntbedge[i].first, ntbedge[i].second);
        doit_bad(res.first, res.second);
      }
      for (i = 0; i < int(tedge.size()); i++) {
        if (dep[tedge[i].first] > dep[tedge[i].second])
          swap(tedge[i].first, tedge[i].second);
        if (query_good(1, tpos[num[fa_ind[tedge[i].second]]]) == 0 &&
            query_bad(1, tpos[num[fa_ind[tedge[i].second]]]) ==
                int(ntbedge.size())) {
          ansnum++;
          ans.push_back(tedge[i].ind);
        }
      }
    }
  }
  if (all_cnt == 0) {
    printf("%d\n", e);
    for (i = 1; i <= e; i++) printf("%d ", i);
    printf("\n");
    return 0;
  }
  if (all_cnt > 1) {
    printf("0\n");
    return 0;
  }
  printf("%d\n", ansnum);
  sort(ans.begin(), ans.end());
  for (i = 0; i < int(ans.size()); i++) printf("%d ", ans[i]);
  printf("\n");
  return 0;
}
