Problem:
社員旅行

Problem Statement

あなたの会社にはn人の社員が存在する．m個の社員(a_i,b_i)の組について，a_iはb_iの上司である．

社員xが社員yの実質的な上司であるとは，次のうち少なくとも一方が成り立つことをいう．

xがyの上司である．

yの実質的な上司である社員zが存在して，xはzの上司である．

あなたの会社で，自分自身が自分の実質的な上司であるような社員は存在しない．

あなたの会社では社員が全員参加する社員旅行が計画されている．全社員の要求により，旅館での部屋割りは「よい部屋割り」でなければならない．

ある部屋割りが「よい部屋割り」であるとは以下の両方が満たされることをいう．

各社員はどこかの部屋に割り振られる．

社員xと社員yが同じ部屋に割り振られているとき，xはyの実質的な上司でない．

幹事の社員は非常に優秀なので，「よい部屋割り」でかつ必要な部屋の数が最小になるように部屋割りを行った．しかし残念なことに予算が不足している．どうしても必要な部屋の数を減らさなければならないらしい．

そこで，人事部で働くあなたは上司-部下の関係を一つだけ解消することによって，「よい部屋割り」を得るために必要な部屋の数を減らすことにした．

さて，どの関係を解消すればよいのだろう？

Input

入力は以下の形式に従う．与えられる数は全て整数である．

n m
a_1 b_1
...
a_m b_m

Constraints

2≦n≦10^5

1≦m≦2 \times 10^5

1≦a_i<b_i≦n

i \neq jならば(a_i, b_i) \neq (a_j, b_j)

Output

次を満たすようなiを昇順に1行ずつ出力せよ．

「a_iがb_iの上司である」という関係を解消したとき，「よい部屋割り」を得るために必要な部屋の数を減らすことができる．

そのようなiが存在しない場合は-1を1行に出力せよ．

Sample Input 1

5 4
1 2
2 3
3 4
3 5

Output for the Sample Input 1

1
2

Solution in Ruby (judge verdict: Accepted)

require 'set'

class Graph
	attr_reader :nodes, :edges

	def add_node(label = nil)
		Node.new(label)
	end

	def add_edge(u, v, label = nil)
		e = Edge.new(u, v, label)
		u.outgoings << e
		v.incomings << e
		e
	end
	
	def del_edge(e)
		u, v = e.from, e.to
		u.outgoings.delete(e)
		v.incomings.delete(e)
		e
	end

	class Node
		def initialize(label)
			@label = label
			@outgoings = Set.new
			@incomings = Set.new
		end

		def to_nodes
			@outgoings.map(&:to)
		end

		def from_nodes
			@incomings.map(&:from)
		end

		def to_s
			@label
		end

		def compute_height
			if @outgoings.empty?
				@height = 0
				return 0
			end
			@height = 0 
			to_nodes.each{|v|
				h = v.height || v.compute_height
				@height = h if h > @height
			}
			@outgoings.reject!{|e| e.to.height < @height}

			@height += 1
		end

		attr_reader :height, :label
		attr_accessor :incomings, :outgoings, :height
	end

	class Edge
		def initialize(u, v, label = nil)
			@from = u	
			@to = v
			@label = label
		end
		attr_reader :from, :to, :label
	end

	def Graph::layers_from(start)
		reached = Set[*start]
		layers = [start]

		loop {
			layers << []
			layers[-2].each{|u|
				u.to_nodes.each{|v|
					next if reached.include?(v)
					reached << v
					layers[-1] << v
				}
			}	

			if layers[-1].empty?
				layers.pop
				return layers
			end
		}
	end
end

class UnionFind
	def initialize
		@obj_to_node = {}
	end

	def size(x = nil)
		x ? @obj_to_node[x].root.size : @obj_to_node.size
	end

	class Node
		def initialize(obj)
			@obj = obj
			@parent = self
			@size = 1
		end

		def root
			return self if @parent == self
			@parent = @parent.root
		end	

		attr_accessor :parent, :size
	end

	def union(x, y)
		u = (@obj_to_node[x] ||= Node.new(x)).root
		v = (@obj_to_node[y] ||= Node.new(y)).root
		return if u == v
		u.parent = v.root
		v.size += u.size
	end

	def same_group?(x, y)
		return false unless u = @obj_to_node[x]
		return false unless v = @obj_to_node[y]
		u.root == v.root
	end
end

class Heap
	def initialize
		@array = []
		@index = {}
	end
	attr_reader :index, :array

	def add(obj, key)
		@array << [obj, key]
		@index[obj] = @array.size - 1
		lift_up(@array.size - 1)
	end

	def swap(i, j)
		u = @array[i]
		v = @array[j]
		@index[u[0]] = j
		@index[v[0]] = i
		@array[i] = v
		@array[j] = u
	end

	def lift_up(i)
		return if i == 0
		j = (i - 1) / 2
		if @array[i][1] < @array[j][1]
			swap(i, j)
			lift_up(j)
		end
	end

	def del_min
		raise "heap is empty" if empty?

		min = @array[0]
		@index.delete(min[0])
		if size > 1
			@array[0] = @array.pop
			lift_down(0)
		else
			@array.pop
		end
		min
	end

	def del_min
		min = @array[0]
		if size > 1
			swap(0, @array.size-1)
			@array.pop
			lift_down(0)
		else
			@array.pop
		end
		@index.delete(min[0])
		min
	end

	def dec_key(obj, diff)
		raise "heap is empty" if empty?
		i = @index[obj]
		return unless i
		@array[i][1] -= diff
		lift_up(i)
	end

	def min_obj
		@array[0][0]
	end

	def min_key
		@array[0][1]
	end

	def lift_down(i)
		j = 2 * i + 1
		k = j + 1
		if k >= size
			return if j >= size
			if @array[i][1] > @array[j][1]
				swap(i, j)
				lift_down(j)
			end
		else
			l = (@array[j][1] < @array[k][1] ? j : k)
			if @array[i][1] > @array[l][1]
				swap(i, l)
				lift_down(l)
			end
		end
	end

	def empty?
		@array.empty?
	end

	def size
		@array.size
	end
end

g = Graph.new
uf = UnionFind.new

n, m = gets.split.map(&:to_i)

nodes = (1..n).map{|i| g.add_node(i) }
m.times{|k|
	i, j = gets.split.map(&:to_i)
	g.add_edge(nodes[i-1], nodes[j-1], k+1)
	uf.union(i, j)
}

t_sorted = []
heap = Heap.new
nodes.each{|v|
	heap.add(v, v.outgoings.size)
}

loop {
	v, _ = heap.del_min
	t_sorted << v
	break if heap.empty?
	v.from_nodes.each{|u|
		heap.dec_key(u, 1)
	}
}

t_sorted.each{|u|
	if u.outgoings.empty?
		u.height = 0
	else
		u.height = 0
		u.height = u.to_nodes.map(&:height).max
		u.outgoings.reject!{|e| e.to.height < u.height}
		u.height += 1
	end
	
}

roots = nodes.select{|v| v.incomings.empty?}

h = roots.map(&:height).max
roots.reject!{|v| v.height < h}

if roots.size != 1 && roots.any?{|v| !uf.same_group?(roots[0].label, v.label)}
	puts -1
else
	u = roots[0]
	ans = []
	Graph::layers_from(roots).each_cons(2){|l1, l2|
		if l1.size == 1 && l2.size == 1
			ans << l1[0].outgoings.to_a[0].label
		end
	}

	puts ans.empty? ? -1 : ans.sort
end