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



Sample input:
4 4
0 1
0 2
1 2
2 3


Sample output:
2

Submission status: Runtime Error

Solution code:
from sys import stdin
import sys
n, m = map(int, stdin.readline().split())
edges = [set() for _ in range(n)]
for _ in [0] * m:
    s, t = map(int, stdin.readline().split())
    edges[s].add(t)
    edges[t].add(s)
prenum = [None] * n
parent = [None] * n
lowest = [None] * n
counter = 0
def dfs(cur, prev):
    global counter
    prenum[cur] = lowest[cur] = counter
    counter += 1
    for edge in edges[cur]:
        if prenum[edge] is not None:
            if edge != prev:
                lowest[cur] = min(lowest[cur], prenum[edge])
            continue
        parent[edge] = cur
        dfs(edge, cur)
        lowest[cur] = min(lowest[cur], lowest[edge])
dfs(0, 1)
ap = [False] * n
r = 0
for _ in filter(lambda x: x == 0, parent):
    r += 1
    if r > 1:
        ap[0] = True
        break
for i in range(1, n):
    p = parent[i]
    if p and prenum[p] <= lowest[i]:
        ap[p] = True
for i, e in enumerate(ap):
    if e: print(i)

Submission status: Runtime Error

Solution code:
from sys import stdin
n, m = map(int, stdin.readline().split())
edges = [set() for _ in range(n)]
for _ in [0] * m:
    s, t = map(int, stdin.readline().split())
    edges[s].add(t)
    edges[t].add(s)
prenum = [None] * n
parent = [None] * n
lowest = [None] * n
counter = 0
def dfs(cur, prev):
    global counter
    prenum[cur] = lowest[cur] = counter
    counter += 1
    for edge in edges[cur]:
        if prenum[edge] is not None:
            if edge != prev:
                lowest[cur] = min(lowest[cur], prenum[edge])
            continue
        parent[edge] = cur
        dfs(edge, cur)
        lowest[cur] = min(lowest[cur], lowest[edge])
dfs(0, 1)
ap = [False] * n
r = 0
for _ in filter(lambda x: x == 0, parent):
    r += 1
    if r > 1:
        ap[0] = True
        break
for i in range(1, n):
    p = parent[i]
    if p and prenum[p] <= lowest[i]:
        ap[p] = True
for i, e in enumerate(ap):
    if e: print(i)

Submission status: Runtime Error

Solution code:
import sys
def dfs(v, tm):
    dts[v] = est[v] = tm + 1
    child = 0

    for i in adj[v]:
        if est[i] == float('inf'):
            child += 1
            parents[i] = v
            dfs(i, tm + 1)
            est[v] = min(est[v], est[i])

            if parents[v] is None and child > 1: aps[v] = True
            if parents[v] is not None and est[i] >= dts[v]: aps[v] = True

        elif parents[v] != i:
            est[v] = min(est[v], dts[i])


nv, ne = map(int, input().split(' '))
adj = [[] for _ in range(nv)]
est = [float('inf')] * nv
parents = [None] * nv
aps = [False] * nv
dts = [0] * nv

for _ in range(ne):
    s, t = map(int, input().split(' '))
    adj[s].append(t)
    adj[t].append(s)

dfs(0, 0)

for i in range(nv):
    if aps[i]:
        print(i)

Submission status: Runtime Error

Solution code:
prenum = {}
lowest = {}
parent = {}
visited = set()

def dfs(G, u, t):
  prenum[u] = t
  lowest[u] = t
  visited.add(u)
  for v in G[u]:
    if v not in visited:
      dfs(G, v, t+1)
      lowest[u] = min(lowest[u], lowest[v])
      parent[v] = u
    else:
      lowest[u] = min(lowest[u], prenum[v])

def solve(G):
  dfs(G, 0, 0)
  ret = set()
  np = 0
  for i in G:
    if i not in parent:
      continue
    p = parent[i]
    if p == 0:
      np += 1
      continue
    if prenum[p] <= lowest[i]:
      ret.add(p)
  if np > 1:
    ret.add(0)
  return ret

n,m = list(map(int, input().split(' ')))
G = {}
for i in range(n):
  G[i] = set()

for i in range(m):
  s,t = list(map(int, input().split(' ')))
  G[s].add(t)
  G[t].add(s)

ret = solve(G)
for r in sorted(ret):
  print(r)

Submission status: Runtime Error

Solution code:
def get_articulation_points(G, N, start=0):
    v_min = [0]*N; order = [None]*N
    result = []; count = 0
    def dfs(v, prev):
        nonlocal count
        r_min = order[v] = count
        fcnt = 0; p_art = 0
        count += 1
        for w in G[v]:
            if w == prev:
                continue
            if order[w] is None:
                ret = dfs(w, v)
                p_art |= (ret == w)
                r_min = min(r_min, ret)
                fcnt += 1
            else:
                r_min = min(r_min, order[w])
        if (prev == -1 and fcnt > 1) or (prev != -1 and p_art):
            result.append(v)
        return r_min
    dfs(start, -1)
    return result

n, m = map(int, input().split())
G = [[] for i in range(n)]
for i in range(m):
    s, t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)
[*map(print,sorted(get_articulation_points(G, n)))]

Submission status: Runtime Error

Solution code:

def get_articulation_points(G, N, start=0):
    v_min = [0]*N; order = [None]*N
    result = []; count = 0
    def dfs(v, prev):
        nonlocal count
        r_min = order[v] = count
        fcnt = 0; p_art = 0
        count += 1
        for w in G[v]:
            if w == prev:
                continue
            if order[w] is None:
                ret = dfs(w, v)
                p_art |= (order[v] <= ret)
                r_min = min(r_min, ret)
                fcnt += 1
            else:
                r_min = min(r_min, order[w])
        p_art |= (r_min == order[v] and len(G[v]) > 1)
        if (prev == -1 and fcnt > 1) or (prev != -1 and p_art):
            result.append(v)
        return r_min
    dfs(start, -1)
    return result

n, m = map(int, input().split())
G = [[] for i in range(n)]
for i in range(m):
    s, t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)
*_,=map(print,sorted(get_articulation_points(G, n)))

Submission status: Runtime Error

Solution code:
from collections import defaultdict

def seq():
    a = 1
    while True:
        yield a
        a += 1

def dfs(here, went, connect, discovery, low, answer, seq):
    went |= {here}
    discovery[here] = low[here] = next(seq)
    child = 0
    for con in connect[here]:
        if con not in went:
            parent[con] = here
            child += 1
            dfs(con, went, connect, discovery, low, answer, seq)
            low[here] = min(low[here], low[i])
            if parent[here] is None and child >= 2:
                answer.append(here)
            elif parent[here] is not None and discovery[here] <= low[con]:
                answer.append(here)
        elif parent[here] != parent[con]:
            low[here] = min(low[here], discovery[con])

vertices, edges = (int(n) for n in input().split(" "))
connect = defaultdict(list)
for _ in range(edges):
    v1, v2 = (int(n) for n in input().split(" "))
    connect[v1].append(v2)
    connect[v2].append(v1)
answer = []
new_seq = seq()
went = set()
discovery = [None for n in range(vertices)]
low = [None for n in range(vertices)]
parent = [None for n in range(vertices)]
dfs(0, went, connect, discovery, low, answer, new_seq)
for a in sorted(answer):
    print(a)

Submission status: Runtime Error

Solution code:
from collections import defaultdict

def seq():
    a = 1
    while True:
        yield a
        a += 1

def dfs(here, went, connect, discovery, low, answer, seq):
    went |= {here}
    discovery[here] = low[here] = next(seq)
    child = 0
    for con in connect[here]:
        if con not in went:
            parent[con] = here
            child += 1
            dfs(con, went, connect, discovery, low, answer, seq)
            low[here] = min(low[here], low[con])
            if parent[here] is None and child >= 2:
                answer[here] = 1
            elif parent[here] is not None and discovery[here] <= low[con]:
                answer[here] = 1
        elif parent[here] != con:
            low[here] = min(low[here], discovery[con])

vertices, edges = (int(n) for n in input().split(" "))
connect = defaultdict(list)
for _ in range(edges):
    v1, v2 = (int(n) for n in input().split(" "))
    connect[v1].append(v2)
    connect[v2].append(v1)
answer = [0 for n in range(vertices)]
new_seq = seq()
went = set()
discovery = [0 for n in range(vertices)]
low = [float("inf") for n in range(vertices)]
parent = [None for n in range(vertices)]
dfs(0, went, connect, discovery, low, answer, new_seq)
for i,n in enumerate(answer):
    if n:
        print(i)

Submission status: Runtime Error

Solution code:
from collections import defaultdict
V, E = map(int, input().split())
G = defaultdict(list)
T = defaultdict(list)
for i in range(E):
    s,t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)

prenum = [float('inf')] * V
lowest = [float('inf')] * V
parent = [None] * V
visited = [False] * V

def dfs(g,s,c=0,p=None):    
    visited[s] = True
    prenum[s] = c
    lowest[s] = c
    c+=1    
    for v in g[s]:
        if not visited[v]:
            parent[v] = s
            T[v].append(s)
            T[s].append(v)
            dfs(g,v,c,s)
            lowest[s] = min( lowest[s], lowest[v] )
        elif v != p:
            lowest[s] = min( lowest[s], prenum[v] )

dfs(G,0)
k = []
if len(T[0]) > 1: k.append(0)
for u in range(V):
    p = parent[u]
    if p is None or p == 0: continue
    if prenum[p] <= lowest[u]: k.append(p)
for i in sorted(set(k)):
    print(i)

Submission status: Runtime Error

Solution code:
from collections import defaultdict
import sys
sys.setrecursionlimit(2*sys.getrecursionlimit())
V, E = map(int, input().split())
G = defaultdict(list)
T = defaultdict(list)
for i in range(E):
    s,t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)

prenum = [float('inf')] * V
lowest = [float('inf')] * V
parent = [None] * V
visited = [False] * V

def dfs(g,s,c=0,p=None):    
    visited[s] = True
    prenum[s] = c
    lowest[s] = c
    c+=1    
    for v in g[s]:
        if not visited[v]:
            parent[v] = s
            T[v].append(s)
            T[s].append(v)
            dfs(g,v,c,s)
            lowest[s] = min( lowest[s], lowest[v] )
        elif v != p:
            lowest[s] = min( lowest[s], prenum[v] )

dfs(G,0)
k = []
if len(T[0]) > 1: k.append(0)
for u in range(V):
    p = parent[u]
    if p is None or p == 0: continue
    if prenum[p] <= lowest[u]: k.append(p)
for i in sorted(set(k)):
    print(i)

Submission status: Runtime Error

Solution code:
from collections import defaultdict
import sys
sys.setrecursionlimit(3*sys.getrecursionlimit())
V, E = map(int, input().split())
G = defaultdict(list)
T = defaultdict(list)
for i in range(E):
    s,t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)

prenum = [float('inf')] * V
lowest = [float('inf')] * V
parent = [None] * V
visited = [False] * V

def dfs(g,s,c=0,p=None):    
    visited[s] = True
    prenum[s] = c
    lowest[s] = c
    c+=1    
    for v in g[s]:
        if not visited[v]:
            parent[v] = s
            T[v].append(s)
            T[s].append(v)
            dfs(g,v,c,s)
            lowest[s] = min( lowest[s], lowest[v] )
        elif v != p:
            lowest[s] = min( lowest[s], prenum[v] )

dfs(G,0)
k = []
if len(T[0]) > 1: k.append(0)
for u in range(V):
    p = parent[u]
    if p is None or p == 0: continue
    if prenum[p] <= lowest[u]: k.append(p)
for i in sorted(set(k)):
    print(i)

Submission status: Runtime Error

Solution code:
from collections import defaultdict
import sys
sys.setrecursionlimit(5*sys.getrecursionlimit())
V, E = map(int, input().split())
G = defaultdict(list)
T = defaultdict(list)
for i in range(E):
    s,t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)

prenum = [float('inf')] * V
lowest = [float('inf')] * V
parent = [None] * V
visited = [False] * V

def dfs(g,s,c=0,p=None):    
    visited[s] = True
    prenum[s] = c
    lowest[s] = c
    c+=1    
    for v in g[s]:
        if not visited[v]:
            parent[v] = s
            T[v].append(s)
            T[s].append(v)
            dfs(g,v,c,s)
            lowest[s] = min( lowest[s], lowest[v] )
        elif v != p:
            lowest[s] = min( lowest[s], prenum[v] )

dfs(G,0)
k = []
if len(T[0]) > 1: k.append(0)
for u in range(V):
    p = parent[u]
    if p is None or p == 0: continue
    if prenum[p] <= lowest[u]: k.append(p)
for i in sorted(set(k)):
    print(i)

Submission status: Runtime Error

Solution code:
# -*- coding: utf-8 -*-


if __name__ == '__main__':

    n, m = [int(s) for s in input().split()]
    E = [set() for _ in range(n)]
    for _ in range(m):
        s, t = [int(s) for s in input().split(" ")]
        E[s].add(t)
        E[t].add(s)

    def dfs(current, prev):
        global timer
        prenum[current] = timer
        lowest[current] = prenum[current]
        timer += 1

        visited[current] = 1

        for v in E[current]:
            if visited[v] == 0:
                parent[v] = current
                dfs(v, current)
                lowest[current] = min(lowest[current], lowest[v])
            elif v != prev:  # current -> v is back-edge
                lowest[current] = min(lowest[current], prenum[v])

    prenum = [None] * n
    parent = [None] * n
    lowest = [float("inf")] * n
    timer = 1
    visited = [0] * n

    dfs(0, -1)

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

    if np > 1:
        ap.append(0)

    ap = list(set(ap))
    ap.sort()
    if ap:
        print("\n".join(map(str, ap)))

Submission status: WA: Presentation Error

Solution code:
from collections import deque


def dfs(current, prev):
    global time
    # node currentを訪問した直後の処理
    ord[current] = time
    low[current] = time
    time += 1
    color[current] = BLACK

    for next in G[current]:
        if color[next] == WHITE:
            # node currentからnode nextへ訪問する直前の処理
            parent[next] = current
            dfs(next, current)

            # node nextの探索が終了した直後の処理
            low[current] = min(low[current], low[next])
        elif next != prev:
            # edge current --> next がback-edgeの場合の処理
            low[current] = min(low[current], ord[next])


def art_points():
    global time
    time = 1
    dfs(0, -1)  # 0をrootとしてlowの計算
    np = 0
    for i in range(1, n):
        p = parent[i]
        if p == 0:
            np += 1
        elif ord[p] <= low[i]:
            ap.append(p)
    if np > 1:
        ap.append(0)


G = {}
v, n = map(int, input().split())
for i in range(0, v):
    G[i] = []
for i in range(n):
    s, t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)
WHITE = 0
BLACK = 2

color = [WHITE] * (v)
parent = [0] * (v)
ord = [0] * (v)
low = [0] * (v)
parent = [0] * (v)
ap = []
art_points()
print(*ap, sep='\n')

Submission status: WA: Presentation Error

Solution code:
n, m = map(int, input().split())

edges = [set() for _ in range(n)]

for _ in range(m):
    s, t = map(int, input().split())
    edges[s].add(t)
    edges[t].add(s)

prenum = [None] * n
parent = [None] * n
lowest = [None] * n
counter = 0


def dfs(cur, prev):
    global counter
    prenum[cur] = lowest[cur] = counter
    counter += 1
    for edge in edges[cur]:
        if prenum[edge] is not None:
            if edge != prev:
                lowest[cur] = min(lowest[cur], prenum[edge])
            continue
        parent[edge] = cur
        dfs(edge, cur)
        lowest[cur] = min(lowest[cur], lowest[edge])


dfs(0, 1)
ap = [False] * n
r = 0
for _ in filter(lambda x: x == 0, parent):
    r += 1
    if r > 1:
        ap[0] = True
        break

for i in range(1, n):
    p = parent[i]
    if p and prenum[p] <= lowest[i]:
        ap[p] = True

print('\n'.join(str(i) for i, e in enumerate(ap) if e) + '\n')

Submission status: WA: Presentation Error

Solution code:
# Acceptance of input

import sys

f_i = sys.stdin

V, E = map(int, f_i.readline().split())

adj_sets = [set() for i in range(V)]

for l_i in f_i:
    s, t = map(int, l_i.split())
    adj_sets[s].add(t)
    adj_sets[t].add(s)


# dfs traverse

prenum = [0] * V
parent = [0] * V
lowest = [V] * V

import collections

path = collections.deque()
path.append(0)

cnt = 0

while path:
    u = path[-1]
    adj_v = adj_sets[u].copy()
    v_candidate = adj_v.difference(path)
    if v_candidate:
        v = v_candidate.pop()
        cnt += 1
        prenum[v] = cnt
        parent[v] = u
        path.append(v)
        adj_sets[u].remove(v)
        adj_sets[v].remove(u)
    else:
        l = min(prenum[u], lowest[u])
        for v in adj_v:
            l = min(l, prenum[v])
            adj_sets[u].remove(v)
            adj_sets[v].remove(u)
        lowest[u] = l
        lowest[parent[u]] = l
        path.pop()


# output

ans = set()

if parent.count(0) >= 3:
    ans.add(0)

for u in range(2, V):
    p = parent[u]
    if prenum[p] <= lowest[u]:
        ans.add(p)

ans = list(ans)
ans.sort()

print(*ans, sep = '\n')

Submission status: WA: Presentation Error

Solution code:
# Acceptance of input

import sys

f_i = sys.stdin

V, E = map(int, f_i.readline().split())

adj_sets = [set() for i in range(V)]

for l_i in f_i:
    s, t = map(int, l_i.split())
    adj_sets[s].add(t)
    adj_sets[t].add(s)


# dfs traverse

prenum = [0] * V
parent = [0] * V
lowest = [V] * V

import collections

path = collections.deque()
path.append(0)

cnt = 0

while path:
    u = path[-1]
    adj_v = adj_sets[u].copy()
    v_candidate = adj_v.difference(path)
    if v_candidate:
        v = v_candidate.pop()
        cnt += 1
        prenum[v] = cnt
        parent[v] = u
        path.append(v)
        adj_sets[u].remove(v)
        adj_sets[v].remove(u)
    else:
        l = min(prenum[u], lowest[u])
        for v in adj_v:
            l = min(l, prenum[v])
            adj_sets[u].remove(v)
            adj_sets[v].remove(u)
        lowest[u] = l
        lowest[parent[u]] = l
        path.pop()


# output

ans = set()

if parent.count(0) >= 3:
    ans.add(0)

for u in range(2, V):
    p = parent[u]
    if prenum[p] <= lowest[u]:
        ans.add(p)

ans = list(ans)
ans.sort()

print(*ans, sep = '\n', end = '')

Submission status: WA: Presentation Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

from sys import stdin

UNVISITED, VISITED_IN_STACK, POPPED_OUT = 0, 1, 2


def generate_adj_matrix(_v_info):
    for v_detail in _v_info:
        v_from, v_to = map(int, v_detail)
        init_adj_table[v_from].append(v_to)
        # undirected graph
        init_adj_table[v_to].append(v_from)
    return init_adj_table


def graph_dfs(current, prev):
    global timer
    pre_v[current] = lowest_v[current] = timer
    timer += 1

    color[current] = VISITED_IN_STACK

    for adj in adj_table[current]:
        if color[adj] is UNVISITED:
            parent_v[adj] = current

            graph_dfs(adj, current)

            lowest_v[current] = min(lowest_v[current], lowest_v[adj])
        elif adj is not prev:
            lowest_v[current] = min(lowest_v[current], pre_v[adj])

    return None


def art_points():
    graph_dfs(0, -1)

    v_count = 0
    for j in range(1, vertices):
        parent = parent_v[j]
        if parent == init_vertex_index:
            v_count += 1
        elif pre_v[parent] <= lowest_v[j]:
            ans.append(parent)

    if v_count > 1:
        ans.append(init_vertex_index)

    return ans


if __name__ == '__main__':
    _input = stdin.readlines()
    vertices, edges = map(int, _input[0].split())
    v_info = map(lambda x: x.split(), _input[1:])
    pre_v, parent_v, lowest_v = ([-1] * vertices for _ in range(3))

    timer = 1
    # root
    init_vertex_index = 0

    ans = []
    v_stack = []
    color = [UNVISITED] * vertices

    init_adj_table = tuple([] for _ in range(vertices))
    adj_table = generate_adj_matrix(v_info)

    # print(*sorted(art_points()), sep='\n')
    print(*ans, sep='\n')

Submission status: WA: Presentation Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

from sys import stdin

UNVISITED, VISITED_IN_STACK, POPPED_OUT = 0, 1, 2


def generate_adj_matrix(_v_info):
    for v_detail in _v_info:
        v_from, v_to = map(int, v_detail)
        init_adj_table[v_from].append(v_to)
        # undirected graph
        init_adj_table[v_to].append(v_from)
    return init_adj_table


def graph_dfs(current, prev):
    global timer
    pre_v[current] = lowest_v[current] = timer
    timer += 1

    color[current] = VISITED_IN_STACK

    for adj in adj_table[current]:
        if color[adj] is UNVISITED:
            parent_v[adj] = current

            graph_dfs(adj, current)

            lowest_v[current] = min(lowest_v[current], lowest_v[adj])
        elif adj is not prev:
            lowest_v[current] = min(lowest_v[current], pre_v[adj])

    return None


def art_points():
    graph_dfs(0, -1)

    v_count = 0
    for j in range(1, vertices):
        parent = parent_v[j]
        if parent == init_vertex_index:
            v_count += 1
        elif pre_v[parent] <= lowest_v[j]:
            ans.append(parent)

    if v_count > 1:
        ans.append(init_vertex_index)

    return ans


if __name__ == '__main__':
    _input = stdin.readlines()
    vertices, edges = map(int, _input[0].split())
    v_info = map(lambda x: x.split(), _input[1:])
    pre_v, parent_v, lowest_v = ([-1] * vertices for _ in range(3))

    timer = 1
    # root
    init_vertex_index = 0

    ans = []
    v_stack = []
    color = [UNVISITED] * vertices

    init_adj_table = tuple([] for _ in range(vertices))
    adj_table = generate_adj_matrix(v_info)

    print(*sorted(art_points()), sep='\n')

Submission status: WA: Presentation Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

from sys import stdin

UNVISITED, VISITED_IN_STACK, POPPED_OUT = 0, 1, 2


def generate_adj_matrix(_v_info):
    for v_detail in _v_info:
        v_from, v_to = map(int, v_detail)
        init_adj_table[v_from].append(v_to)
        # undirected graph
        init_adj_table[v_to].append(v_from)
    return init_adj_table


def graph_dfs(current, prev):
    global timer
    pre_v[current] = lowest_v[current] = timer
    timer += 1

    color[current] = VISITED_IN_STACK

    for adj in adj_table[current]:
        if color[adj] is UNVISITED:
            parent_v[adj] = current

            graph_dfs(adj, current)

            lowest_v[current] = min(lowest_v[current], lowest_v[adj])
        elif adj is not prev:
            lowest_v[current] = min(lowest_v[current], pre_v[adj])

    return None


def art_points():
    graph_dfs(0, -1)

    v_count = 0
    for j in range(1, vertices):
        parent = parent_v[j]
        if parent == init_vertex_index:
            v_count += 1
        elif pre_v[parent] <= lowest_v[j]:
            ans.append(parent)

    if v_count > 1:
        ans.append(init_vertex_index)

    return ans


if __name__ == '__main__':
    _input = stdin.readlines()
    vertices, edges = map(int, _input[0].split())
    v_info = map(lambda x: x.split(), _input[1:])
    pre_v, parent_v, lowest_v = ([-1] * vertices for _ in range(3))

    timer = 1
    # root
    init_vertex_index = 0

    ans = []
    v_stack = []
    color = [UNVISITED] * vertices

    init_adj_table = tuple([] for _ in range(vertices))
    adj_table = generate_adj_matrix(v_info)

    if ans:
        pass
    else:
        # print(*sorted(art_points()), sep='\n')
        print(*art_points(), sep='\n')

Submission status: WA: Presentation Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

import sys

sys.setrecursionlimit(int(1e6))


def generate_adj_table(_v_info):
    for v_detail in _v_info:
        source, target = map(int, v_detail)
        init_adj_table[source].append(target)
        init_adj_table[target].append(source)
    return init_adj_table


def Tarjan(current, parents, visited, disc, low):
    global timer
    current_children_count = 0
    visited[current] = True
    disc[current] = low[current] = timer
    timer += 1

    for adj in adj_table[current]:
        if not visited[adj]:
            parents[adj] = current
            current_children_count += 1

            Tarjan(adj, parents, visited, disc, low)

            low[current] = min(low[current], low[adj])
            # current is root of DFS tree
            if parents[current] == -1 and current_children_count > 1:
                art_set.add(current)

            elif parents[current] != -1 and low[adj] >= disc[current]:
                art_set.add(current)

        elif adj != parents[current]:
            low[current] = min(low[current], disc[adj])

    # print(timer, parents, visited, disc, low)
    return None


def art_points():
    parents = [-1] * vertices
    visited = [False] * vertices
    disc = [float('inf')] * vertices
    low = [float('inf')] * vertices

    for v in range(vertices):
        Tarjan(v, parents, visited, disc, low)

    return art_set


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    vertices, edges = map(int, _input[0].split())
    v_info = map(lambda x: x.split(), _input[1:])
    init_adj_table = tuple([] for _ in range(vertices))
    adj_table = generate_adj_table(v_info)

    timer = 0
    art_set = set()
    print(*sorted(art_points()), sep='\n')

Submission status: WA: Presentation Error

Solution code:
from sys import stdin
n, m = map(int, stdin.readline().split())
G = [[] for _ in [0] * n]
prenum = [0] * n
parent = [0] * n
lowest = [0] * n
timer = 0
visited = [False] * n
for _ in [0] * m:
    s, t = map(int, stdin.readline().split())
    G[s].append(t)
    G[t].append(s)
def dfs(current, prev):
    global timer
    timer += 1
    prenum[current] = lowest[current] = timer
    visited[current] = True
    for i in range(len(G[current])):
        next = G[current][i]
        if not visited[next]:
            parent[next] = current
            dfs(next, current)
            lowest[current] = min(lowest[current], lowest[next])
        elif next != prev:
            lowest[current] = min(lowest[current], prenum[next])
dfs(0, -1)
ap = set()
np = 0
for i in range(1, n):
    p = parent[i]
    if p == 0: np += 1
    elif prenum[p] <= lowest[i]:
        ap.add(p)
if np > 1: print(0)
li = sorted(ap)
print(*li, sep="\n")

Submission status: WA: Presentation Error

Solution code:
from sys import stdin
n, m = map(int, stdin.readline().split())
if n < 1:
    print()
    exit()
G = [[] for _ in [0] * n]
prenum = [0] * n
parent = [0] * n
lowest = [0] * n
timer = 0
visited = [False] * n
for _ in [0] * m:
    s, t = map(int, stdin.readline().split())
    G[s].append(t)
    G[t].append(s)
def dfs(current, prev):
    global timer
    timer += 1
    prenum[current] = lowest[current] = timer
    visited[current] = True
    for i in range(len(G[current])):
        next = G[current][i]
        if not visited[next]:
            parent[next] = current
            dfs(next, current)
            lowest[current] = min(lowest[current], lowest[next])
        elif next != prev:
            lowest[current] = min(lowest[current], prenum[next])
dfs(0, -1)
ap = set()
np = 0
for i in range(1, n):
    p = parent[i]
    if p == 0: np += 1
    elif prenum[p] <= lowest[i]:
        ap.add(p)
if np > 1: print(0)
li = sorted(ap)
print(*li, sep="\n")

Submission status: WA: Presentation Error

Solution code:
from sys import stdin
n, m = map(int, stdin.readline().split())
if m < 1:
    print()
    exit()
G = [[] for _ in [0] * n]
prenum = [0] * n
parent = [0] * n
lowest = [0] * n
timer = 0
visited = [False] * n
for _ in [0] * m:
    s, t = map(int, stdin.readline().split())
    G[s].append(t)
    G[t].append(s)
def dfs(current, prev):
    global timer
    timer += 1
    prenum[current] = lowest[current] = timer
    visited[current] = True
    for i in range(len(G[current])):
        next = G[current][i]
        if not visited[next]:
            parent[next] = current
            dfs(next, current)
            lowest[current] = min(lowest[current], lowest[next])
        elif next != prev:
            lowest[current] = min(lowest[current], prenum[next])
dfs(0, -1)
ap = set()
np = 0
for i in range(1, n):
    p = parent[i]
    if p == 0: np += 1
    elif prenum[p] <= lowest[i]:
        ap.add(p)
if np > 1: print(0)
li = sorted(ap)
print(*li, sep="\n")

Submission status: WA: Presentation Error

Solution code:
from sys import stdin
n, m = map(int, stdin.readline().split())
if m < 1:
#    print()
    exit()
G = [[] for _ in [0] * n]
prenum = [0] * n
parent = [0] * n
lowest = [0] * n
timer = 0
visited = [False] * n
for _ in [0] * m:
    s, t = map(int, stdin.readline().split())
    G[s].append(t)
    G[t].append(s)
def dfs(current, prev):
    global timer
    timer += 1
    prenum[current] = lowest[current] = timer
    visited[current] = True
    for i in range(len(G[current])):
        next = G[current][i]
        if not visited[next]:
            parent[next] = current
            dfs(next, current)
            lowest[current] = min(lowest[current], lowest[next])
        elif next != prev:
            lowest[current] = min(lowest[current], prenum[next])
dfs(0, -1)
ap = set()
np = 0
for i in range(1, n):
    p = parent[i]
    if p == 0: np += 1
    elif prenum[p] <= lowest[i]:
        ap.add(p)
if np > 1: print(0)
li = sorted(ap)
print(*li, sep="\n")

Submission status: WA: Presentation Error

Solution code:
from sys import stdin
n, m = map(int, stdin.readline().split())
if m < 1:
#    print()
    exit(0)
G = [[] for _ in [0] * n]
prenum = [0] * n
parent = [0] * n
lowest = [0] * n
timer = 0
visited = [False] * n
for _ in [0] * m:
    s, t = map(int, stdin.readline().split())
    G[s].append(t)
    G[t].append(s)
def dfs(current, prev):
    global timer
    timer += 1
    prenum[current] = lowest[current] = timer
    visited[current] = True
    for i in range(len(G[current])):
        next = G[current][i]
        if not visited[next]:
            parent[next] = current
            dfs(next, current)
            lowest[current] = min(lowest[current], lowest[next])
        elif next != prev:
            lowest[current] = min(lowest[current], prenum[next])
dfs(0, -1)
ap = set()
np = 0
for i in range(1, n):
    p = parent[i]
    if p == 0: np += 1
    elif prenum[p] <= lowest[i]:
        ap.add(p)
if np > 1: print(0)
li = sorted(ap)
print(*li, sep="\n")