← Home
package main

import (
	"io"
	"os"
	"strconv"
)

type Edge struct {
	u, v int
}

type Frame struct {
	v, parent, parentEdge, idx int
	entered                    bool
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	pos := 0
	nextInt := func() int {
		for pos < len(data) && (data[pos] < '0' || data[pos] > '9') {
			pos++
		}
		val := 0
		for pos < len(data) && data[pos] >= '0' && data[pos] <= '9' {
			val = val*10 + int(data[pos]-'0')
			pos++
		}
		return val
	}

	n := nextInt()
	m := nextInt()

	edges := make([]Edge, m+1)
	adj := make([][]int, n+1)
	for i := 1; i <= m; i++ {
		u := nextInt()
		v := nextInt()
		edges[i] = Edge{u, v}
		adj[u] = append(adj[u], i)
		adj[v] = append(adj[v], i)
	}

	disc := make([]int, n+1)
	low := make([]int, n+1)
	ans := make([]bool, m+1)

	edgeStack := make([]int, 0, m)
	stack := make([]Frame, 0, n)

	deg := make([]int, n+1)
	seen := make([]int, n+1)
	compBuf := make([]int, 0)
	touched := make([]int, 0)

	timer := 0
	compID := 0

	for s := 1; s <= n; s++ {
		if disc[s] != 0 {
			continue
		}
		stack = append(stack, Frame{v: s})

		for len(stack) > 0 {
			top := &stack[len(stack)-1]
			v := top.v

			if !top.entered {
				timer++
				disc[v] = timer
				low[v] = timer
				top.entered = true
			}

			if top.idx < len(adj[v]) {
				eid := adj[v][top.idx]
				top.idx++

				var to int
				if edges[eid].u == v {
					to = edges[eid].v
				} else {
					to = edges[eid].u
				}

				if eid == top.parentEdge {
					continue
				}

				if disc[to] == 0 {
					edgeStack = append(edgeStack, eid)
					stack = append(stack, Frame{v: to, parent: v, parentEdge: eid})
				} else if disc[to] < disc[v] {
					edgeStack = append(edgeStack, eid)
					if disc[to] < low[v] {
						low[v] = disc[to]
					}
				}
				continue
			}

			f := stack[len(stack)-1]
			stack = stack[:len(stack)-1]
			v = f.v

			if f.parent != 0 {
				p := f.parent
				if low[v] < low[p] {
					low[p] = low[v]
				}
				if low[v] >= disc[p] {
					compBuf = compBuf[:0]
					for {
						eid := edgeStack[len(edgeStack)-1]
						edgeStack = edgeStack[:len(edgeStack)-1]
						compBuf = append(compBuf, eid)
						if eid == f.parentEdge {
							break
						}
					}

					if len(compBuf) >= 3 {
						compID++
						touched = touched[:0]
						ok := true

						for _, eid := range compBuf {
							u := edges[eid].u
							w := edges[eid].v

							if seen[u] != compID {
								seen[u] = compID
								deg[u] = 0
								touched = append(touched, u)
							}
							if seen[w] != compID {
								seen[w] = compID
								deg[w] = 0
								touched = append(touched, w)
							}

							deg[u]++
							deg[w]++
						}

						for _, x := range touched {
							if deg[x] != 2 {
								ok = false
								break
							}
						}

						if ok {
							for _, eid := range compBuf {
								ans[eid] = true
							}
						}
					}
				}
			}
		}
	}

	res := make([]int, 0)
	for i := 1; i <= m; i++ {
		if ans[i] {
			res = append(res, i)
		}
	}

	out := make([]byte, 0, 32+len(res)*8)
	out = strconv.AppendInt(out, int64(len(res)), 10)
	out = append(out, '\n')
	for i, eid := range res {
		if i > 0 {
			out = append(out, ' ')
		}
		out = strconv.AppendInt(out, int64(eid), 10)
	}
	out = append(out, '\n')
	os.Stdout.Write(out)
}