C# solution (Tarjan's algorithm)
Reference: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm\n\npublic class Solution {\n    \n    private int time = 0;\n    \n 
Reference: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm\n```\npublic class Solution {\n    \n    private int time = 0;\n    \n    public IList<IList<int>> CriticalConnections(int n, IList<IList<int>> connections) {\n        \n        IList<IList<int>> bridge = new List<IList<int>>();\n        \n        // build the graph\n        Dictionary<int, List<int>> graph = new Dictionary<int, List<int>>();\n        foreach(var connection in connections)\n        {\n            int node1 = connection[0];\n            int node2 = connection[1];\n            \n            if(!graph.ContainsKey(node1))\n                graph[node1] = new List<int>();\n            if(!graph.ContainsKey(node2))\n                graph[node2] = new List<int>();\n            \n            graph[node1].Add(node2);\n            graph[node2].Add(node1);\n        }\n                \n        int[] disc = new int[n]; // node id generated by DFS search\n        int[] low = new int[n];  // smallest node id that current node can be reached from\n        Array.Fill(disc, -1);    // -1 denotes the node is not visted\n        \n        // traverse the graph\n        for(int i = 0; i < n; i++)\n        {\n            if(disc[i] == -1)\n                DFS(i, i, disc, low, graph, bridge);\n        }\n        \n        return bridge;\n    }\n    \n    private void DFS(int u, int parent, int[] disc, int[] low, Dictionary<int, List<int>> graph, IList<IList<int>> bridge)\n    {\n        disc[u] = time;\n        low[u] = time;\n        time++;\n        \n        for(int i = 0; i < graph[u].Count; i++)\n        {\n            int v = graph[u][i];\n            \n            if(v == parent)\n                continue;\n            if(disc[v] == -1)\n            {\n                // node v is not visited, keep DFS traverse\n                DFS(v, u, disc, low, graph, bridge);\n                \n                // update the low-link value for u\n                low[u] = Math.Min(low[u], low[v]);\n                \n                if(low[v] > disc[u])\n                    bridge.Add(new List<int>{u, v});\n            }\n            else   \n            {\n                // if v is already visited, then u-v is a back-edge in the DFS tree.\n                // low stores the min node id from the subtree of u, so use disv[v] here.\n                low[u] = Math.Min(low[u], disc[v]);\n            }\n        }\n    }\n}\n```
[]