Problem:
Bridges

Find bridges of an undirected graph G(V, E).

A bridge (also known as a cut-edge) is an edge whose deletion increase the number of connected components.

Input

|V| |E|
s0 t0
s1 t1
:
s|E|-1 t|E|-1

, where |V| is the number of nodes and |E| is the number of edges in the graph. The graph nodes are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target nodes of i-th edge (undirected).

Output

A list of bridges of the graph ordered by name. For each bridge, names of its end-ponints, source and target (source < target), should be printed separated by a space. The sources should be printed ascending order, then the target should also be printed ascending order for the same source.

Constraints

1 ≤ |V| ≤ 100,000

0 ≤ |E| ≤ 100,000

The graph is connected

There are no parallel edges

There are no self-loops

Sample Input 1

4 4
0 1
0 2
1 2
2 3

Sample Output 1

2 3

Sample Input 2

5 4
0 1
1 2
2 3
3 4

Sample Output 2

0 1
1 2
2 3
3 4

Solution in JavaScript (judge verdict: Wrong Answer)

var log = console.log;
if (typeof process != "undefined") {
	var input = "";
	process.stdin.resume();
	process.stdin.setEncoding('utf8');
	process.stdin.on('data', function (chunk) {
		input += chunk;
	});
	process.stdin.on('end', function () {
		var lines = input.split("\n");
		main(lines);
	});
}


function main(lines){
	if(lines.pop() != ""){
		lines.push();
	}
	lines = lines.map(function(line){
		return line.split(" ").map(function(e){
			return Number(e);
		});
	});
	var top_line = lines.shift();
	var V = top_line[0];
	var E = top_line[1];
	var real_edge = [];
	var virt_edge = [];
	var mark = [];
	var status = [];
	var ord = [];
	var lowlink = [];
	var bridges = [];
	for(var i = 0; i < V ; i++){
		real_edge[i] = [];
		mark[i] = false;
		//ord?????????
		//lowlink??????(dfs????????????????§????){0,}??¨(?????????){0,1}??§?????????ord???????°????
		//?????????????????????????????§???????°???????ord
		ord[i] = 0;
		lowlink[i] = V;
		bridges[i] = [];
	}
	lines.forEach(function(edge){
		var a = edge[0];
		var b = edge[1];
		real_edge[a].push(b);
		real_edge[b].push(a);
	});
	var no = 0;
	var prev = 0;
	function dfs(now_point,prev){
		//now_point????????¨???????????????
		//now_ord????????¨???????????????
		//mark????¨???????????????????
		var np = now_point;
		var mk = mark;
		var targets = real_edge[np];
		mk[np] = true;
		ord[np] = no;
		lowlink[np] = no;
		no++;
		targets.forEach(function(target){
			if(target == prev){
				//??´???????????????????????????????????§
				return;
			}
			if(mk[target]){
				//?????????
				//lowlink?????´??°
				//????°????????????????
				lowlink[np] = Math.min(lowlink[np],target);
			}else{
				//???????????£????????¨?????????
				//??¢?´¢?????????
				dfs(target,np);
				//?????\????????????lowlink?????????
				//???????????????????±????lowlink???????°???????lowlink????????¨??????
				lowlink[np] = Math.min(lowlink[np],lowlink[target]);
			}
		});
	}
	dfs(0,V);
	lines.forEach(function(edge){
		var u = edge[0];
		var v = edge[1];
		if(ord[u] > ord[v]){
			var k = u;
			u = v;
			v = k;
		}
		if(ord[u] < lowlink[v]){
			//????????????
			var min = Math.min(u,v);
			var max = Math.max(u,v);
			bridges[min].push(max);
		}
	});
	bridges = bridges.map(function(e){
		return e.sort();
	});
	for(var s = 0 ; s < V ; s++){
		var len = bridges[s].length;
		for(var td = 0 ; td < len ;td++){
			var t = bridges[s][td];
			log(s+" "+t);
		}
	}
}