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 C++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
const int maxN = 1e5+5;
const int inf = 1001*1000*1000;
#define pb push_back
#define mp make_pair
vector<int> obj[maxN];
vector<pair<int,int>> bre;
int n,e,mark[maxN],fa[maxN],dp[maxN],hig[maxN];
pair<int,int> jof;
void dfs(int u)
{
	mark[u] =1;
	dp[u]=inf;
	for(int v:obj[u])
	{
		if(!mark[v])
		{
			hig[v]=hig[u]+1;
			mark[v]=1;
			fa[v]=u;
			dfs(v);
			dp[u]=min(dp[u],dp[v]);
		}
		else if(v!=fa[u]&&hig[v]<hig[u])
		{
			dp[u]=min(dp[u],hig[v]);
		}
	}
	if(dp[u]>=hig[u]&&u!=fa[u])
	{
		jof = mp(min(u,fa[u]),max(u,fa[u]));
		bre.pb(jof);
	}
}
int main()
{
	cin>>n>>e;
	int u,v;
	for(int i=0;i<e;i++)
	{
		cin>>u>>v;
		obj[u].pb(v);
		obj[v].pb(u);
	}
	dfs(0);
	sort(bre.begin(),bre.end());
	for(int i=0;i<bre.size();i++)
	{
		cout<<bre[i].first<<" "<<bre[i].second<<endl;
	}
}