int timer = 1;
void dfs(int node, int parent, vector<int> &vis, vector<int> adj[], int tin[],
int low[], vector<pair<int, int>> &bridges) {
vis[node] = 1;
tin[node] = low[node] = timer++;
for (auto it : adj[node]) {
if (it == parent) continue;
if (!vis[it]) {
dfs(it, node, vis, adj, tin, low, bridges);
low[node] = min(low[it], low[node]);
if (low[it] > tin[node]) bridges.push_back({it, node});
} else
low[node] = min(low[node], low[it]);
}
}
vector<pair<int, int>> findBridges(int n, vector<pair<int, int>> &edges) {
vector<int> adj[n];
for (auto [u, v] : edges) {
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<int> vis(n);
int tin[n], low[n];
vector<pair<int, int>> bridges;
dfs(0, -1, vis, adj, tin, low, bridges);
return bridges;
}