2 0
 100000 0
 8 9
1 2
2 3
3 4
4 1
5 6
6 7
7 8
8 5
6 8
 2 1
1 2
 11 9
5 9
8 5
11 3
11 1
3 4
7 11
3 1
11 2
7 2
 7 9
7 3
7 4
1 2
2 3
3 1
3 4
4 5
5 6
6 4
 7 5
5 4
7 3
7 1
6 7
3 1
 7 8
1 2
2 3
3 4
4 1
3 5
5 6
6 7
7 3
 6 9
1 2
2 3
1 4
4 2
5 2
5 3
4 5
6 4
6 5
 7 9
1 2
2 4
4 3
3 1
2 3
4 5
5 6
6 7
7 4
 1 0
 6 7
1 2
2 3
3 1
3 4
4 5
5 6
6 4
 4 5
1 2
2 3
3 4
4 1
1 3
 100000 3
99998 99999
99999 100000
100000 99998

0

 0

 4
1 2 3 4 
 0

 6
3 4 6 7 8 9 
 9
1 2 3 4 5 6 7 8 9 
 3
2 3 5 
 8
1 2 3 4 5 6 7 8 
 0

 4
6 7 8 9 
 0

 6
1 2 3 5 6 7 
 0

 3
1 2 3 

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
map<pair<int, int>, int> M;
int root;
int root_children;
set<int> adj[N];
vector<int> toRemove[N];
int dfs_num[N], dfs_low[N], is_arti[N];
vector<int> T;
void dfs(int v, int p, int &k) {
  T.push_back(v);
  dfs_num[v] = dfs_low[v] = ++k;
  if (p == root) root_children++;
  for (auto it : adj[v]) {
    if (it == p) continue;
    if (dfs_num[it] == 0) {
      dfs(it, v, k);
      if (dfs_low[it] >= dfs_num[v]) is_arti[v] = 1;
      if (dfs_low[it] > dfs_num[v]) {
        toRemove[v].push_back(it);
        toRemove[it].push_back(v);
      }
      dfs_low[v] = min(dfs_low[v], dfs_low[it]);
    } else {
      dfs_low[v] = min(dfs_low[v], dfs_num[it]);
    }
  }
}
int U[N], V[N], disc[N], low[N], comp[N];
vector<int> g[N];
int tym;
bool is_bridge[N];
int adj2(int src, int edgeid) { return U[edgeid] ^ V[edgeid] ^ src; }
void tarjan(int src, int par_edge) {
  ++tym;
  disc[src] = low[src] = tym;
  for (int i = 0; i < (int)g[src].size(); ++i) {
    int edgeid = g[src][i];
    int to = adj2(src, edgeid);
    if (edgeid != par_edge) {
      if (!disc[to]) {
        tarjan(to, edgeid);
        low[src] = min(low[src], low[to]);
        if (low[to] > disc[src]) is_bridge[edgeid] = 1;
      } else {
        low[src] = min(low[src], disc[to]);
      }
    }
  }
}
bool urgent = 0;
int ec = 0;
pair<int, int> vis[N], vedge[N];
map<pair<int, int>, int> VF, EF;
void arti_dfs(int v, int p, int k) {
  for (auto it : adj[v]) {
    if (it == p) continue;
    int eid = M[make_pair(v, it)];
    if (vedge[eid].first) {
      vedge[eid].second = k;
      EF[vedge[eid]]++;
    } else
      vedge[eid].first = k;
    if (is_arti[it]) {
      if (it == k) continue;
      if (it < k and not urgent) continue;
      int x = k, y = it;
      ec++;
      U[ec] = x, V[ec] = y;
      g[x].push_back(ec);
      g[y].push_back(ec);
      is_bridge[ec] = 0;
      continue;
    }
    if (vis[it].first != k and vis[it].second != k) {
      if (vis[it].first)
        vis[it].second = k;
      else
        vis[it].first = k;
      arti_dfs(it, v, k);
    }
  }
}
map<pair<int, int>, int> ok;
vector<int> ans;
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int a, b;
    cin >> a >> b;
    adj[a].insert(b), adj[b].insert(a);
    M[make_pair(a, b)] = M[make_pair(b, a)] = i;
  }
  int k = 0;
  for (int i = 1; i <= n; i++) {
    if (dfs_num[i] == 0) {
      T.clear();
      root = i, root_children = 0;
      dfs(i, 0, k);
      is_arti[i] = (root_children > 1);
      for (auto v : T) {
        for (auto it : toRemove[v]) {
          adj[v].erase(it);
        }
      }
      ec = 0;
      for (auto it : T) {
        if (is_arti[it]) {
          arti_dfs(it, 0, it);
        }
      }
      urgent = 1;
      for (auto it : T) {
        if (not is_arti[it] and not vis[it].second) {
          is_arti[it] = 1;
          arti_dfs(it, 0, it);
        }
      }
      urgent = 0;
      for (auto it : T) {
        if (is_arti[it] and not disc[it]) {
          tarjan(it, 0);
        }
      }
      for (auto it : T) {
        if (vis[it].second) VF[vis[it]]++;
      }
      for (auto it : VF) {
        if (it.second + 2 == EF[it.first]) {
          ok[it.first] = 1;
        }
      }
    }
  }
  for (int i = 1; i <= m; i++) {
    if (ok[vedge[i]]) ans.push_back(i);
  }
  cout << ans.size() << "\n";
  for (auto it : ans) {
    cout << it << " ";
  }
  cout << "\n";
  return 0;
}
