JAVA Solution
\nclass Solution {\n    private int depth = 0;\n    public List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) {\n        //disc[i] 
```\nclass Solution {\n    private int depth = 0;\n    public List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) {\n        //disc[i] is the node\'s depth in a DFS tree\n        int[] disc = new int[n];\n        Arrays.fill(disc, -1);\n        //low[i] is the node\'s all reachable node\'s smallest depth in a DFS tree\n        int[] low = new int[n];\n        //Create the graph;\n        List<Integer>[] graph = new ArrayList[n];\n        for (int i = 0; i < n; i++) {\n            graph[i] = new ArrayList<Integer>();\n        }\n        for (List<Integer> connection : connections) {\n            int from = connection.get(0);\n            int to = connection.get(1);\n            graph[from].add(to);\n            graph[to].add(from);\n        }\n        //Create the result;\n        List<List<Integer>> result = new ArrayList<>();\n        //DFS for each node\n        for (int i = 0; i < n; i++) {\n            if(disc[i] == -1) {\n                dfs(i, disc, low, graph, result, i);\n            }\n        }\n        return result;\n    }\n    private void dfs(int u, int[] disc, int[] low, List<Integer>[] graph, List<List<Integer>> result, int parent) {\n        depth++;\n        disc[u] = depth;\n        low[u] = depth;\n        List<Integer> children = graph[u];\n        for (int v : children) {\n            if (v == parent) {\n                continue;\n            } else {\n                if (disc[v] == -1) {\n                    dfs(v, disc, low, graph, result, u);\n                    low[u] = Math.min(low[u], low[v]);\n                    if (low[v] > disc[u]) {\n                        result.add(Arrays.asList(u, v));\n                    }\n                } else {\n                    low[u] = Math.min(low[u], low[v]);\n                }\n            }\n        }\n    }\n}\n```
[]