#include <bits/stdc++.h>
using namespace std;
class Graph {
 public:
  struct edge {
    edge()
        : u(-1),
          v(-1),
          w(0),
          index(-1),
          deleted(false),
          bi_edge(false),
          ctx(0) {}
    edge(int _u, int _v, int _w, int _index, int _bi_edge, int _ctx)
        : u(_u),
          v(_v),
          w(_w),
          index(_index),
          deleted(false),
          bi_edge(_bi_edge),
          ctx(_ctx) {}
    int u;
    int v;
    int w;
    int index;
    bool deleted;
    bool bi_edge;
    int ctx;
    bool existed() { return !deleted; }
    int to(int _u) {
      if (!bi_edge) {
        return v;
      } else {
        return _u == u ? v : u;
      }
    }
  };
  Graph(int _n, bool _need_unique_edge = false)
      : n(_n),
        need_unique_edge(_need_unique_edge),
        need_count_edge(false),
        support_circle_edge(false) {
    g.resize(n);
    for (int i = 0; i < n; i++) {
      g[i].reserve(5);
    }
    edges.reserve(n * 2);
    edge_count.resize(n);
  }
  void SetUseRepeatEdge(bool use) {
    if (use) {
      need_count_edge = true;
      need_unique_edge = false;
    } else {
      need_count_edge = false;
      need_unique_edge = true;
    }
  }
  void SetSupportCircleEdge(bool support) { support_circle_edge = support; }
  bool CheckNeedAdd(int u, int v) {
    assert(u < n);
    assert(v < n);
    if (!support_circle_edge) {
      if (u == v) {
        return false;
      }
    }
    if (need_unique_edge) {
      if (edge_count[u][v] > 0) {
        return false;
      }
    }
    return true;
  }
  void AddEdge(int u, int v, int w = 0, int ctx = 0) {
    int edge_index = (int)edges.size();
    edges.push_back(edge(u, v, w, edge_index, false, ctx));
    if (!CheckNeedAdd(u, v)) {
      return;
    }
    if (need_unique_edge || need_count_edge) {
      edge_count[u][v]++;
    }
    g[u].push_back(edge_index);
  }
  void AddBiEdge(int u, int v, int w = 0, int ctx = 0) {
    int edge_index = (int)edges.size();
    edges.push_back(edge(u, v, w, edge_index, true, ctx));
    if (!CheckNeedAdd(u, v)) {
      return;
    }
    if (need_unique_edge || need_count_edge) {
      edge_count[u][v]++;
      if (u != v) {
        edge_count[v][u]++;
      }
    }
    g[u].push_back(edge_index);
    if (u != v) {
      g[v].push_back(edge_index);
    }
  }
  void SetEdgeDeleted(int edge_index, bool deleted) {
    if (edge_index >= (int)edges.size()) {
      return;
    }
    auto& e = edges[edge_index];
    if (e.deleted != deleted) {
      e.deleted = deleted;
      if (need_count_edge) {
        int delta = deleted ? -1 : 1;
        edge_count[e.u][e.v] += delta;
        if (e.bi_edge && e.u != e.v) {
          edge_count[e.v][e.u] += delta;
        }
      }
    }
  }
  void RandEdge() {
    for (auto& es : g) {
      random_shuffle(es.begin(), es.end());
    }
  }

 public:
  int Tarjan_VBCC(vector<int>& cut_vertices, vector<int>& edge_component);

 public:
  int n;
  vector<vector<int>> g;
  vector<edge> edges;
  vector<map<int, int>> edge_count;
  bool need_unique_edge;
  bool need_count_edge;
  bool support_circle_edge;
};
int Graph ::Tarjan_VBCC(vector<int>& cut_vertices,
                        vector<int>& edge_component) {
  edge_component.resize(edges.size(), -1);
  vector<int> dfn(n, 0);
  vector<int> low(n, 0);
  vector<bool> visited(n, false);
  stack<int> s;
  function<void(int, int)> dfs;
  int visit_index = 0;
  int component_index = 0;
  dfs = [&](int u, int parent) {
    dfn[u] = low[u] = visit_index++;
    visited[u] = true;
    int found_cp_count = 0;
    for (auto ei : g[u]) {
      auto& e = edges[ei];
      if (!e.existed()) continue;
      int v = e.to(u);
      if (!visited[v]) {
        s.push(e.index);
        dfs(v, u);
        low[u] = min(low[u], low[v]);
        if (low[v] >= dfn[u]) {
          found_cp_count++;
          while (!s.empty()) {
            auto edge_index = s.top();
            s.pop();
            edge_component[edge_index] = component_index;
            if (edge_index == e.index) {
              break;
            }
          }
          component_index++;
        }
      } else if (v != parent) {
        if (dfn[v] < dfn[u]) {
          s.push(e.index);
        }
        low[u] = min(low[u], dfn[v]);
      }
    }
    if ((parent != -1 && found_cp_count > 0) || found_cp_count > 1) {
      cut_vertices.push_back(u);
    }
  };
  for (int u = 0; u < n; u++) {
    if (!visited[u]) {
      dfs(u, -1);
    }
  }
  return component_index;
}
void Solve() {
  int n, m;
  cin >> n >> m;
  Graph g(n);
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    g.AddBiEdge(u - 1, v - 1);
  }
  vector<int> cut_vertices;
  vector<int> edge_component;
  int component_count = g.Tarjan_VBCC(cut_vertices, edge_component);
  vector<set<int>> component_vertex_count(component_count);
  vector<int> component_edge_count(component_count);
  for (int ei = 0; ei < m; ei++) {
    component_edge_count[edge_component[ei]]++;
    auto& e = g.edges[ei];
    component_vertex_count[edge_component[ei]].insert(e.u);
    component_vertex_count[edge_component[ei]].insert(e.v);
  }
  vector<int> ans;
  for (int ei = 0; ei < m; ei++) {
    auto cp = edge_component[ei];
    if (component_vertex_count[cp].size() == component_edge_count[cp]) {
      ans.push_back(ei + 1);
    }
  }
  printf("%d\n", (int)ans.size());
  for (auto v1 : ans) printf("%d ", (int)v1);
  ;
}
int main(int argc, char** argv) {
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int t = 1;
  while (t--) {
    Solve();
  }
  return 0;
}
