#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define FOR(i,k,n) for (int (i)=(k); (i)<(n); ++(i))
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define all(v) begin(v), end(v)
#define debug(x) cerr<< #x <<": "<<x<<endl
#define debug2(x,y) cerr<< #x <<": "<< x <<", "<< #y <<": "<< y <<endl

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<i_i, int> p_i;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
template<class T> using vv=vector<vector< T > >;
typedef deque<int> di;
typedef deque<deque<int> > ddi;

vvi edge;
vi prenum;
vi lowest;
vi parent;
int timer;

void dfs(int u, int prev) {
  prenum[u] = timer;
  lowest[u] = timer;
  timer += 1;

  for (auto v : edge[u]) {
    if (prenum[v] < 0) {
      parent[v] = u;
      dfs(v, u);
      lowest[u] = min(lowest[u], lowest[v]);
    } else if (v != prev) {
      lowest[u] = min(lowest[u], prenum[v]);
    }
  }
}

int main() {
  int v, e;
  cin >> v >> e;
  edge.resize(v);
  prenum.resize(v, -1);
  lowest.resize(v);
  parent.resize(v);
  rep (i, e) {
    int s, t;
    cin >> s >> t;
    edge[s].pb(t);
    edge[t].pb(s);
  }
  timer = 0;
  dfs(0, -1);

  set<vi> ans;
  FOR(i, 1, v) {
    if (prenum[parent[i]] < lowest[i]) {
      int mi = min(parent[i], i);
      int ma = max(parent[i], i);
      ans.insert({mi, ma});
    }
  }
  for (auto e : ans) {
    printf("%d %d\n", e[0], e[1]);
  }

  return 0;
}
### Prompt

Generate 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 <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define FOR(i,k,n) for (int (i)=(k); (i)<(n); ++(i))
#define rep(i,n) FOR(i,0,n)
#define pb push_back
#define all(v) begin(v), end(v)
#define debug(x) cerr<< #x <<": "<<x<<endl
#define debug2(x,y) cerr<< #x <<": "<< x <<", "<< #y <<": "<< y <<endl

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<i_i, int> p_i;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
template<class T> using vv=vector<vector< T > >;
typedef deque<int> di;
typedef deque<deque<int> > ddi;

vvi edge;
vi prenum;
vi lowest;
vi parent;
int timer;

void dfs(int u, int prev) {
  prenum[u] = timer;
  lowest[u] = timer;
  timer += 1;

  for (auto v : edge[u]) {
    if (prenum[v] < 0) {
      parent[v] = u;
      dfs(v, u);
      lowest[u] = min(lowest[u], lowest[v]);
    } else if (v != prev) {
      lowest[u] = min(lowest[u], prenum[v]);
    }
  }
}

int main() {
  int v, e;
  cin >> v >> e;
  edge.resize(v);
  prenum.resize(v, -1);
  lowest.resize(v);
  parent.resize(v);
  rep (i, e) {
    int s, t;
    cin >> s >> t;
    edge[s].pb(t);
    edge[t].pb(s);
  }
  timer = 0;
  dfs(0, -1);

  set<vi> ans;
  FOR(i, 1, v) {
    if (prenum[parent[i]] < lowest[i]) {
      int mi = min(parent[i], i);
      int ma = max(parent[i], i);
      ans.insert({mi, ma});
    }
  }
  for (auto e : ans) {
    printf("%d %d\n", e[0], e[1]);
  }

  return 0;
}
```