#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class FindBridge {
public:
    explicit FindBridge(const vector<vector<int>>& g) : ord(g.size(), -1), pre(g.size(), -1) {
        int curOrder = 0;
        search_(g, 0, -1, curOrder);
        auto reorder = [](vector<pair<int, int>>& v){
            for(auto& p : v){
                if(p.first > p.second) swap(p.first, p.second);
            }
            sort(v.begin(), v.end());
        };
        reorder(bridge);
        reorder(edge);
    }
private:
    void search_(const vector<vector<int>>& g, int pos, int prev, int& curOrder){
        ord[pos] = pre[pos] = curOrder;
        ++curOrder;
        for(auto& e : g[pos]){
            if(e == prev) continue;
            if(ord[e] == -1) search_(g, e, pos, curOrder);
            if(ord[pos] < pre[e]){
                bridge.emplace_back(pos, e);
            } else {
                edge.emplace_back(pos, e);
            }
            pre[pos] = min(pre[pos], pre[e]);
        }
    }
public:
    const vector<pair<int, int>> getBridge() const { return bridge; }
    const vector<pair<int, int>> getEdge() const { return edge; }
private:
    vector<int> ord;
    vector<int> pre;
    vector<pair<int, int>> bridge;
    vector<pair<int, int>> edge;
};

int main(){
    int n, m;
    while(cin >> n >> m){
        vector<vector<int>> g(n);
        for(int i=0;i<m;i++){
            int a, b; cin >> a >> b;
            g[a].push_back(b);
            g[b].push_back(a);
        }
        FindBridge b(g);
        for(auto& e : b.getBridge()){
            cout << e.first << " " << e.second << endl;
        }
    }
}

### Prompt

Develop a solution in cpp to the problem described below:

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 <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class FindBridge {
public:
    explicit FindBridge(const vector<vector<int>>& g) : ord(g.size(), -1), pre(g.size(), -1) {
        int curOrder = 0;
        search_(g, 0, -1, curOrder);
        auto reorder = [](vector<pair<int, int>>& v){
            for(auto& p : v){
                if(p.first > p.second) swap(p.first, p.second);
            }
            sort(v.begin(), v.end());
        };
        reorder(bridge);
        reorder(edge);
    }
private:
    void search_(const vector<vector<int>>& g, int pos, int prev, int& curOrder){
        ord[pos] = pre[pos] = curOrder;
        ++curOrder;
        for(auto& e : g[pos]){
            if(e == prev) continue;
            if(ord[e] == -1) search_(g, e, pos, curOrder);
            if(ord[pos] < pre[e]){
                bridge.emplace_back(pos, e);
            } else {
                edge.emplace_back(pos, e);
            }
            pre[pos] = min(pre[pos], pre[e]);
        }
    }
public:
    const vector<pair<int, int>> getBridge() const { return bridge; }
    const vector<pair<int, int>> getEdge() const { return edge; }
private:
    vector<int> ord;
    vector<int> pre;
    vector<pair<int, int>> bridge;
    vector<pair<int, int>> edge;
};

int main(){
    int n, m;
    while(cin >> n >> m){
        vector<vector<int>> g(n);
        for(int i=0;i<m;i++){
            int a, b; cin >> a >> b;
            g[a].push_back(b);
            g[b].push_back(a);
        }
        FindBridge b(g);
        for(auto& e : b.getBridge()){
            cout << e.first << " " << e.second << endl;
        }
    }
}

```