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 

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class BiconnectedComponet {

	public static void main(String[] args) throws NumberFormatException, IOException {
		// TODO Auto-generated method stub
		Scanner in = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		int n = in.nextInt();
		int m = in.nextInt();
		MagicComponents mc = new MagicComponents(n);
		for (int i = 0; i < m; i++) {
			int u = in.nextInt() - 1;
			int v = in.nextInt() - 1;
			mc.addEdge(u, v, i + 1);
		}
		mc.run();
		TreeSet<Integer> ans = new TreeSet<>();
		for (ArrayList<Edge> bic : mc.bccs) {
			int edges = bic.size();
			HashSet<Integer> l = new HashSet<>();
			for (Edge e : bic) {
				l.add(e.u);
				l.add(e.v);
			}
			if (l.size() == edges) {
				for (Edge e : bic) {
					ans.add(e.id2);
				}
			}
		}
		out.println(ans.size());
		for (Integer i : ans) {
			out.print(i + " ");
		}
		out.flush();
		out.close();

	}

	// # Bi-connected Components
	// Two-Connected Components
	// Articulation or cut points
	// Bridges //$
	static class Edge {
		int u, v, id, id2;

		public Edge() {

		}

		public Edge(int U, int V, int i, int ii) {
			u = U;
			v = V;
			id = i;
			id2 = ii;
		}

		@Override
		public String toString() {
			return "Edge [u=" + u + ", v=" + v + ", id=" + id + ", id2=" + id2 + "]";
		}

	}

	static class MagicComponents { // Stack Trick!
		int num, n, edges;
		int[] dfsNum, low, vis;
		ArrayList<Integer> cuts;
		ArrayList<Edge> bridges, adj[];
		ArrayList<ArrayList<Edge>> bccs;
		ArrayDeque<Edge> eStack;

		MagicComponents(int N) {
			adj = new ArrayList[n = N];
			for (int i = 0; i < n; i++)
				adj[i] = new ArrayList<>();
			edges = 0;
		}

		void addEdge(int u, int v, int i) {
			adj[u].add(new Edge(u, v, edges, i));
			adj[v].add(new Edge(v, u, edges++, i));
		}

		void run() {
			vis = new int[n];
			dfsNum = new int[n];
			low = new int[n];
			bridges = new ArrayList<>();
			cuts = new ArrayList<>();
			bccs = new ArrayList<>();
			eStack = new ArrayDeque<>();
			num = 0;

			for (int i = 0; i < n; i++) {
				if (vis[i] != 0)
					continue;
				dfs(i, -1);
			}
		}

		void dfs(int node, int par) {
			dfsNum[node] = low[node] = num++;
			vis[node] = 1;
			int nChild = 0;
			for (Edge e : adj[node]) {
				if (e.v == par)
					continue;
				if (vis[e.v] == 0) {
					++nChild;
					eStack.push(e);
					dfs(e.v, node);
					low[node] = Math.min(low[node], low[e.v]);
					if (low[e.v] >= dfsNum[node]) {
						if (dfsNum[node] > 0 || nChild > 1)
							cuts.add(node);
						if (low[e.v] > dfsNum[node]) {
							bridges.add(e);
							pop(node);
						} else
							pop(node);
					}
				} else if (vis[e.v] == 1) {
					low[node] = Math.min(low[node], dfsNum[e.v]);
					eStack.push(e);
				}
			}
			vis[node] = 2;
		}

		void pop(int u) {
			ArrayList<Edge> list = new ArrayList<>();
			for (;;) {
				Edge e = eStack.pop();
				list.add(e);
				if (e.u == u)
					break;
			}
			bccs.add(list);
		}

		// # Make sure to call run before calling this function.
		// Function returns a new graph such that all two connected
		// components are compressed into one node and all bridges
		// in the previous graph are the only edges connecting the
		// components in the new tree.
		// map is an integer array that will store the mapping
		// for each node in the old graph into the new graph. //$
		MagicComponents componentTree(int[] map) {
			boolean[] vis = new boolean[edges];
			for (Edge e : bridges)
				vis[e.id] = true;

			int numComp = 0;
			Arrays.fill(map, -1);
			for (int i = 0; i < n; ++i) {
				if (map[i] == -1) {
					ArrayDeque<Integer> q = new ArrayDeque<>();
					q.add(i);
					map[i] = numComp;
					while (!q.isEmpty()) {
						int node = q.poll();
						for (Edge e : adj[node]) {
							if (!vis[e.id] && map[e.v] == -1) {
								vis[e.id] = true;
								map[e.v] = numComp;
								q.add(e.v);
							}
						}
					}
					++numComp;
				}
			}

			MagicComponents g = new MagicComponents(numComp);
			Arrays.fill(vis, false);
			for (int i = 0; i < n; ++i) {
				for (Edge e : adj[i]) {
					if (!vis[e.id] && map[e.v] < map[e.u]) {
						vis[e.id] = true;
						g.addEdge(map[e.v], map[e.u], e.id2);
					}
				}
			}

			return g;
		}

		// # Make sure to call run before calling this function.
		// Function returns a new graph such that all biconnected
		// components are compressed into one node. Cut nodes will
		// be in multiple components, so these nodes will also have
		// their own component by themselves. Edges in the graph
		// represent components to articulation points
		// map is an integer array that will store the mapping
		// for each node in the old graph into the new graph.
		// Cut points to their special component, and every other node
		// to their specific component. //$
		MagicComponents bccTree(int[] map) {
			int[] cut = new int[n];
			Arrays.fill(cut, -1);
			int size = bccs.size();
			for (int i : cuts)
				map[i] = cut[i] = size++;
			MagicComponents g = new MagicComponents(size);
			int[] used = new int[n];
			for (int i = 0; i < bccs.size(); ++i) {
				ArrayList<Edge> list = bccs.get(i);
				for (Edge e : list) {
					for (int node : new int[] { e.u, e.v }) {
						if (used[node] != i + 1) {
							used[node] = i + 1;
							if (cut[node] != -1)
								g.addEdge(i, cut[node], e.id2);
							else
								map[node] = i;
						}
					}
				}
			}
			return g;
		}
	}

	static class Scanner {// Fast I/O
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String file) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(file));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

	}
}
