<p>There are <code>n</code> servers numbered from <code>0</code> to <code>n - 1</code> connected by undirected server-to-server <code>connections</code> forming a network where <code>connections[i] = [a<sub>i</sub>, b<sub>i</sub>]</code> represents a connection between servers <code>a<sub>i</sub></code> and <code>b<sub>i</sub></code>. Any server can reach other servers directly or indirectly through the network.</p>

<p>A <em>critical connection</em> is a connection that, if removed, will make some servers unable to reach some other server.</p>

<p>Return all critical connections in the network in any order.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2019/09/03/1537_ex1_2.png" style="width: 198px; height: 248px;" />
<pre>
<strong>Input:</strong> n = 4, connections = [[0,1],[1,2],[2,0],[1,3]]
<strong>Output:</strong> [[1,3]]
<strong>Explanation:</strong> [[3,1]] is also accepted.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> n = 2, connections = [[0,1]]
<strong>Output:</strong> [[0,1]]
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li>
	<li><code>n - 1 &lt;= connections.length &lt;= 10<sup>5</sup></code></li>
	<li><code>0 &lt;= a<sub>i</sub>, b<sub>i</sub> &lt;= n - 1</code></li>
	<li><code>a<sub>i</sub> != b<sub>i</sub></code></li>
	<li>There are no repeated connections.</li>
</ul>

class Solution:
    def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:
        # Build the graph
        graph = [[] for _ in range(n)]
        for u, v in connections:
            graph[u].append(v)
            graph[v].append(u)

        # Initialize the rank array and set the initial rank to 0
        rank = [None for _ in range(n)]
        self.current_rank = 0

        # Initialize the result list
        critical_connections = []

        # DFS to find cycles and critical connections
        def dfs(node, parent):
            # If the rank of the current node is already set, return it
            if rank[node] is not None:
                return rank[node]

            # Set the rank of the current node to the current rank and increment the rank
            rank[node] = self.current_rank
            self.current_rank += 1

            # Initialize the minimum rank that the node can reach
            min_rank = rank[node]

            # Explore all adjacent nodes
            for neighbor in graph[node]:
                # Skip the parent to avoid going back
                if neighbor == parent:
                    continue

                # Get the rank of the neighbor using DFS
                neighbor_rank = dfs(neighbor, node)

                # Update the minimum rank
                min_rank = min(min_rank, neighbor_rank)

            # If the minimum rank is still the same as the current node's rank,
            # it means that removing the edge to the parent will disconnect the graph
            if min_rank == rank[node] and parent is not None:
                critical_connections.append([node, parent] if node < parent else [parent, node])

            return min_rank

        # Start DFS from node 0
        dfs(0, None)

        return critical_connections

# Example usage:
# sol = Solution()
# print(sol.criticalConnections(4, [[0,1],[1,2],[2,0],[1,3]]))  # Output: [[1,3]]
# print(sol.criticalConnections(2, [[0,1]]))  # Output: [[0,1]]
68126