class Solution {

public List<List<Integer>> findBridges(int n, List<List<Integer>> edges) {

Map<Integer, Set<Integer>> graph = new HashMap<>();

for (int i = 0; i < n; i++) graph.put(i, new HashSet<>());

for (List<Integer> edge : edges) {

graph.get(edge.get(0)).add(edge.get(1));

graph.get(edge.get(1)).add(edge.get(0));

}

List<List<Integer>> res = new ArrayList<>();

boolean[] visited = new boolean[n];

int[] lowlink = new int[n];

int[] id = new int[n];

for (int i = 0; i < n; i++) {

if (!visited[i]) {

dfs(i, -1, 0, graph, id, lowlink, visited, res);

}

}

return res;

}

private void dfs(int v, int parent, int i, Map<Integer, Set<Integer>> graph, int[] id, int[] lowlink, boolean[] visited, List<List<Integer>> res) {

lowlink[v] = i;

id[v] = i;

visited[v] = true;

for (int adj : graph.get(v)) {

if (adj != parent) {

if (!visited[adj]) {

dfs(adj, v, i + 1, graph, id, lowlink, visited, res);

lowlink[v] = Math.min(lowlink[v], lowlink[adj]);

if (id[v] < lowlink[adj]) {

res.add(Arrays.asList(v, adj));

}

} else {

lowlink[v] = Math.min(lowlink[v], id[adj]);

}

}

}

}

}