Problem:
Articulation Points

Find articulation points of a given undirected graph G(V, E).

A vertex in an undirected graph is an articulation point (or cut vertex) iff removing it disconnects the graph.

Input

|V| |E|
s0 t0
s1 t1
:
s|E|-1 t|E|-1

, where |V| is the number of vertices and |E| is the number of edges in the graph. The graph vertices are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target verticess of i-th edge (undirected).

Output

A list of articulation points of the graph G ordered by name.

Constraints

1 ≤ |V| ≤ 100,000

0 ≤ |E| ≤ 100,000

The graph is connected

There are no parallel edges

There are no self-loops

Sample Input 1

4 4
0 1
0 2
1 2
2 3

Sample Output 1

2

Sample Input 2

5 4
0 1
1 2
2 3
3 4

Sample Output 2

1
2
3

Solution in Python3 (judge verdict: Accepted)

from sys import setrecursionlimit

setrecursionlimit(1000000)


def art_points(n, m, G):
    def dfs(cur, prev):
        nonlocal t
        prenum[cur] = lowest[cur] = t
        t += 1
        visited[cur] = True

        for ne in G[cur]:
            if not visited[ne]:
                parent[ne] = cur
                dfs(ne, cur)
                lowest[cur] = min(lowest[cur], lowest[ne])
            elif ne != prev:
                lowest[cur] = min(lowest[cur], prenum[ne])

    t = 1
    prenum = [0] * n
    parent = [0] * n
    lowest = [0] * n
    visited = [False] * n
    dfs(0, -1)

    ap = set()
    np = 0
    for i, p in zip(range(1, n), parent[1:]):
        if p == 0:
            np += 1
        elif prenum[p] <= lowest[i]:
            ap.add(p)
    if np > 1:
        ap.add(0)
    return ap


def main():
    n, m = [int(x) for x in input().split()]
    G = [[] for _ in range(n)]
    for _ in range(m):
        s, t = [int(x) for x in input().split()]
        G[s].append(t)
        G[t].append(s)
    for p in sorted(art_points(n, m, G)):
        print(p)


main()