Buggy python submission (verdict: Time Limit Exceeded):
def is_contain_cycle(g, v):
    visited = set()
    for i in range(v):
        if i in visited:
            continue
        route = [None]
        dfs_stack = [(i, None)]            
        while dfs_stack:
            u, prev = dfs_stack.pop()
            while route[-1] != prev:
                route.pop()
                
            visited |= {u}
            if u in route:
                return True
            dfs_stack.extend((v, u) for v in g[u])
            
            route.append(u)
    return False

from sys import stdin
from collections import defaultdict
readline = stdin.readline


v, e = map(int, readline().split())
g = defaultdict(set)
for i in range(e):
    s, t = map(int, readline().split())
    g[s] |= {t}
print(1 if is_contain_cycle(g, v) else 0)

Fixed submission:
def is_contain_cycle(g, v):
    visited = set()
    for i in range(v):
        if i in visited:
            continue
        #route = Stack([None])
        route = [None]
        dfs_stack = [(i, None)]
        while dfs_stack:
            u, prev = dfs_stack.pop()
            while route[-1] != prev:
                route.pop()
            if u in route:
                return True
            if u in visited:
                continue
            visited |= {u}
            dfs_stack.extend((v, u) for v in g[u])
            route.append(u)
    return False

from sys import stdin
from collections import defaultdict


readline = stdin.readline

v, e = map(int, readline().split())
g = defaultdict(set)
for i in range(e):
    s, t = map(int, readline().split())
    g[s] |= {t}
print(1 if is_contain_cycle(g, v) else 0)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import UserList
class Stack(UserList):
    def __init__(self, *args):
        UserList.__init__(self, *args)
        self.contains = set()
    def __contains__(self, x):
        return x in self.contains
    def __and__(self, x):
        return self.contains & x
    def push(self, x):
        if x in self.contains:
            return
        self.data.append(x)
        self.contains |= {x}
    def pop(self):
        x = self.data.pop()
        self.contains -= {x}
        return x

def is_contain_cycle(g, v):
    visited = set()
    for i in range(v):
        if i in visited:
            continue
        route = Stack([None])
        dfs_stack = [(i, None)]            
        while dfs_stack:
            u, prev = dfs_stack.pop()
            while route[-1] != prev:
                route.pop()
                
            visited |= {u}
            if u in route:
                return True
            dfs_stack.extend((v, u) for v in g[u])
            
            route.push(u)
    return False

from sys import stdin
from collections import defaultdict
readline = stdin.readline

v, e = map(int, readline().split())
g = defaultdict(set)
for i in range(e):
    s, t = map(int, readline().split())
    g[s] |= {t}
print(1 if is_contain_cycle(g, v) else 0)

Fixed submission:
def is_contain_cycle(g, v):
    visited = set()
    for i in range(v):
        if i in visited:
            continue
        #route = Stack([None])
        route = [None]
        dfs_stack = [(i, None)]
        while dfs_stack:
            u, prev = dfs_stack.pop()
            while route[-1] != prev:
                route.pop()
            if u in route:
                return True
            if u in visited:
                continue
            visited |= {u}
            dfs_stack.extend((v, u) for v in g[u])
            route.append(u)
    return False

from sys import stdin
from collections import defaultdict


readline = stdin.readline

v, e = map(int, readline().split())
g = defaultdict(set)
for i in range(e):
    s, t = map(int, readline().split())
    g[s] |= {t}
print(1 if is_contain_cycle(g, v) else 0)