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.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;

public class F_test {
	static int N;
	static int M;
	static HashMap<String, Integer> map = new HashMap<String, Integer>();
	public static void main(String[] args) {
		JS in = new JS();
		PrintWriter out = new PrintWriter(System.out);
		N = in.nextInt();
		M = in.nextInt();
		MagicComponents MC = new MagicComponents(N);
		for(int i = 0; i < M; i++) {
			int v1 = in.nextInt()-1;
			int v2 = in.nextInt()-1;
			MC.addEdge(v1, v2);
			String s1 = v1+"#"+v2;
			String s2 = v2+"#"+v1;
			map.put(s1, i+1);
			map.put(s2, i+1);
		}
		MC.run();
		//for(int i = 0; i < N; i++) {
		//	System.out.println(i+" "+MC.low[i]);
		//} System.out.println();

		HashSet<Integer> res = new HashSet<Integer>();
		//ArrayList<Integer> nodes[] = new ArrayList[N];
		HashSet<Integer> nodes[] = new HashSet[N];
		for(int i = 0; i < N; i++) nodes[i] = new HashSet<Integer>();
		for(int i = 0; i < N; i++) nodes[MC.low[i]].add(i);
		for(int i = 0; i < N; i++) {
			int curLo = MC.low[i];
			HashSet<Integer> lows = new HashSet<Integer>();
			for(Edge e : MC.adj[i]) {
				if(MC.low[e.v] != curLo) {
					if(lows.contains(MC.low[e.v])) nodes[MC.low[e.v]].add(i);
					lows.add(MC.low[e.v]);
				}
			}
		}
		
		for(int i = 0; i < N; i++) {
			if(nodes[i].size() <= 1)continue;
			//Get all edges for the nodes
			int cnt = 0;
			for(Integer v : nodes[i]) {
				for(Edge e : MC.adj[v]) {
					if(nodes[i].contains(e.v)) cnt++;
				}
			}
			//System.out.println(nodes[i].toString()+" "+cnt);
			if(cnt/2 != nodes[i].size())continue;
			
			
			for(Integer v : nodes[i]) {
				for(Edge e : MC.adj[v]) {
					if(nodes[i].contains(e.v)) {
						String s = v+"#"+e.v;
						res.add(map.get(s));
					}
				}
			}			
		}
		ArrayList<Integer> res2 = new ArrayList<Integer>();
		for(Integer rr : res) res2.add(rr);
		Collections.sort(res2);
		out.println(res2.size());
		for(Integer ii : res2) out.print(ii+" ");
		out.close();
	}

	
	//# Bi-connected Components
	// Two-Connected Components
	// Articulation or cut points
	// Bridges //$
	static class Edge {
	  int u, v, id;
	  public Edge(int U, int V, int i) {
	    u = U; v = V; id = i;
	  }
	}
	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) {
	    adj[u].add(new Edge(u, v, edges));
	    adj[v].add(new Edge(v, u, edges++));
	  }
	  
	  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]);
	        }
	      }
	    }
	    
	    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]);
	            else map[node] = i;
	          }
	        }
	      }
	    }
	    return g;
	  }
	}
	
	
	static class JS{
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;
		
		public JS() {
			in = new BufferedInputStream(System.in, BS);
		}
		
		public JS(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}
		
		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}				
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}
		
		public int nextInt() {
			return (int)nextLong();
		}
		
		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}
		
		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}
		
		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}
		
		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}
	}
	
}
