#include<cstdio>
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
const int MAX_N=1e5+10;
vector<int>adj[MAX_N];
pair<int,int>ans[MAX_N];
long long int from[MAX_N],to[MAX_N],dp[MAX_N],depth[MAX_N],rt;
bool vis[MAX_N];
void dfs(int v,int de,int p)
{
    depth[v]=de;
    vis[v]=1;
    for(int e:adj[v])
    {
        int u=from[e] xor to[e] xor v;
        if(e==p)
        {
            continue;
        }
        if(vis[u])
        {
            dp[v]=min(dp[v],depth[u]);
        }
        else
        {
            dfs(u,de+1,e);
            dp[v]=min(dp[u],dp[v]);
        }
    }
    if(dp[v]>=de&&p!=-1)
    {
        ans[rt]={min(from[p],to[p]),max(from[p],to[p])};
        rt++;
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(long long int i=0;i<=100000;i++)
    {
        dp[i]=999999;
    }
    for(int i=1;i<=m;i++)
    {
        cin>>from[i]>>to[i];
        from[i];
        to[i];
        adj[from[i]].push_back(i);
        adj[to[i]].push_back(i);
    }
    dfs(0,0,-1);
    sort(ans,ans+rt);
    for(int i=0;i<rt;i++)
    {
        cout<<ans[i].first<<" "<<ans[i].second<<endl;
    }
}
### Prompt

Please formulate a Cpp solution to the following problem:

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.

Constraints

* 1 ≤ |V| ≤ 100,000
* 0 ≤ |E| ≤ 100,000
* The graph is connected
* There are no parallel edges
* There are no self-loops

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.

Examples

Input

4 4
0 1
0 2
1 2
2 3


Output

2 3


Input

5 4
0 1
1 2
2 3
3 4


Output

0 1
1 2
2 3
3 4

### Response

```cpp
#include<cstdio>
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
const int MAX_N=1e5+10;
vector<int>adj[MAX_N];
pair<int,int>ans[MAX_N];
long long int from[MAX_N],to[MAX_N],dp[MAX_N],depth[MAX_N],rt;
bool vis[MAX_N];
void dfs(int v,int de,int p)
{
    depth[v]=de;
    vis[v]=1;
    for(int e:adj[v])
    {
        int u=from[e] xor to[e] xor v;
        if(e==p)
        {
            continue;
        }
        if(vis[u])
        {
            dp[v]=min(dp[v],depth[u]);
        }
        else
        {
            dfs(u,de+1,e);
            dp[v]=min(dp[u],dp[v]);
        }
    }
    if(dp[v]>=de&&p!=-1)
    {
        ans[rt]={min(from[p],to[p]),max(from[p],to[p])};
        rt++;
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(long long int i=0;i<=100000;i++)
    {
        dp[i]=999999;
    }
    for(int i=1;i<=m;i++)
    {
        cin>>from[i]>>to[i];
        from[i];
        to[i];
        adj[from[i]].push_back(i);
        adj[to[i]].push_back(i);
    }
    dfs(0,0,-1);
    sort(ans,ans+rt);
    for(int i=0;i<rt;i++)
    {
        cout<<ans[i].first<<" "<<ans[i].second<<endl;
    }
}
```