Problem:


Score : 600 points

Problem Statement

Given is a directed graph G with N vertices and M edges.

The vertices are numbered 1 to N, and the i-th edge is directed from Vertex A_i to Vertex B_i.

It is guaranteed that the graph contains no self-loops or multiple edges.

Determine whether there exists an induced subgraph (see Notes) of G such that the in-degree and out-degree of every vertex are both 1. If the answer is yes, show one such subgraph.

Here the null graph is not considered as a subgraph.

Notes

For a directed graph G = (V, E), we call a directed graph G' = (V', E') satisfying the following conditions an induced subgraph of G:

V' is a (non-empty) subset of V.

E' is the set of all the edges in E that have both endpoints in V'.

Constraints

1 \leq N \leq 1000

0 \leq M \leq 2000

1 \leq A_i,B_i \leq N

A_i \neq B_i

All pairs (A_i, B_i) are distinct.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
A_2 B_2
:
A_M B_M

Output

If there is no induced subgraph of G that satisfies the condition, print -1.
Otherwise, print an induced subgraph of G that satisfies the condition, in the following format:

K
v_1
v_2
:
v_K

This represents the induced subgraph of G with K vertices whose vertex set is \{v_1, v_2, \ldots, v_K\}. (The order of v_1, v_2, \ldots, v_K does not matter.)
If there are multiple subgraphs of G that satisfy the condition, printing any of them is accepted.

Sample Input 1

4 5
1 2
2 3
2 4
4 1
4 3

Sample Output 1

3
1
2
4

The induced subgraph of G whose vertex set is \{1, 2, 4\} has the edge set \{(1, 2), (2, 4), (4, 1)\}. The in-degree and out-degree of every vertex in this graph are both 1.

Sample Input 2

4 5
1 2
2 3
2 4
1 4
4 3

Sample Output 2

-1

There is no induced subgraph of G that satisfies the condition.

Sample Input 3

6 9
1 2
2 3
3 4
4 5
5 6
5 1
5 2
6 1
6 2

Sample Output 3

4
2
3
4
5



Sample input:
4 5
1 2
2 3
2 4
4 1
4 3


Sample output:
3
1
2
4

Submission status: Time Limit Exceeded

Solution code:
import sys; input = sys.stdin.buffer.readline
from collections import defaultdict
import queue
con = 10 ** 9 + 7; INF = float("inf")

def getlist():
	return list(map(int, input().split()))

class Graph(object):
	def __init__(self):
		self.graph = defaultdict(list)

	def __len__(self):
		return len(self.graph)

	def add_edge(self, a, b):
		self.graph[a].append(b)

def BFS(G, N, s, g, ans):
	Q = queue.Queue()
	Q.put(s)
	dist = [INF] * N
	dist[s] = 0
	prev = [None] * N
	jud = "No"
	while not Q.empty():
		v = Q.get()
		for i in G.graph[v]:
			if dist[i] == INF:
				dist[i] = dist[v] + 1
				prev[i] = v
				Q.put(i)
				if i == g:
					jud = "Yes"
					break
		if jud == "Yes":
			break

	if ans > dist[g]:
		state = g
		path = [g]
		while True:
			state = prev[state]
			path.append(state)
			if state == s:
				break
		return dist[g], path[::-1]
	else:
		return INF, []

#処理内容
def main():
	N, M = getlist()
	G = Graph()
	edgefrom = []
	edgeto = []
	for i in range(M):
		a, b = getlist()
		a -= 1; b -= 1
		edgefrom.append(a)
		edgeto.append(b)
		G.add_edge(a, b)

	ans = 100000
	path = None
	for i in range(M):
		predis, prepath = BFS(G, N, edgeto[i], edgefrom[i], ans)
		if predis != INF:
			ans = predis
			path = prepath

	if ans == 100000:
		print(-1)
	else:
		print(ans + 1)
		for i in path:
			print(i + 1)

if __name__ == '__main__':
	main()

Submission status: Time Limit Exceeded

Solution code:
import sys; input = sys.stdin.buffer.readline
from collections import defaultdict
import queue
INF = float("inf")

class Graph(object):
	def __init__(self):
		self.graph = defaultdict(list)

	def __len__(self):
		return len(self.graph)

	def add_edge(self, a, b):
		self.graph[a].append(b)

	def get_nodes(self):
		return self.graph.keys()

class BFS(object):
	def __init__(self, graph, s, N):
		self.g = graph.graph
		self.Q = queue.Queue()
		self.Q.put(s)
		self.visit = ["No"] * N
		self.visit[s] = "Yes"
		self.judge = "Yes"
		self.prev = [None] * N
		self.path = []
		while not self.Q.empty():
			v = self.Q.get()
			for i in self.g[v]:
				if self.visit[i] == "No":
					self.Q.put(i)
					self.visit[i] = "Yes"
					self.prev[i] = v
				else:
					if i == s:
						self.judge = "No"
						#閉路path構築
						while True:
							self.path.append(v)
							v = self.prev[v]
							if v == None:
								break
		
			if self.judge == "No":
				break
		# print(self.path)

	def cycle(self):
		if self.judge == "No":
			return len(self.path), self.path
		else:
			return INF, []

def getlist():
	return list(map(int, input().split()))

#処理内容
def main():
	N, M = getlist()
	G = Graph()
	for i in range(M):
		A, B = getlist()
		A -= 1; B -= 1
		G.add_edge(A, B)

	cycle_dist = INF
	cycle_path = None
	for i in range(N):
		BF = BFS(G, i, N)
		dist_var, dist_path = BF.cycle()
		if dist_var < cycle_dist:
			cycle_dist = dist_var
			cycle_path = dist_path

	if cycle_dist == INF:
		print(-1)
	else:
		print(cycle_dist)
		for i in range(cycle_dist):
			print(cycle_path[cycle_dist - 1 - i] + 1)


if __name__ == '__main__':
	main()

Submission status: Time Limit Exceeded

Solution code:
import sys; input = sys.stdin.buffer.readline
from collections import defaultdict
import queue
INF = float("inf")

class Graph(object):
	def __init__(self):
		self.graph = defaultdict(list)

	def __len__(self):
		return len(self.graph)

	def add_edge(self, a, b):
		self.graph[a].append(b)

	def get_nodes(self):
		return self.graph.keys()

class BFS(object):
	def __init__(self, graph, s, N):
		self.g = graph.graph
		self.Q = queue.Queue()
		self.Q.put(s)
		self.visit = ["No"] * N
		self.visit[s] = "Yes"
		self.judge = "Yes"
		self.prev = [None] * N
		self.path = []
		while not self.Q.empty():
			v = self.Q.get()
			for i in self.g[v]:
				if self.visit[i] == "No":
					self.Q.put(i)
					self.visit[i] = "Yes"
					self.prev[i] = v
				else:
					if i == s:
						self.judge = "No"
						#閉路path構築
						while True:
							self.path.append(v)
							v = self.prev[v]
							if v == None:
								break
		
			if self.judge == "No":
				break
		# print(self.path)

	def cycle(self):
		if self.judge == "No":
			return len(self.path), list(reversed(self.path))
		else:
			return INF, []

def getlist():
	return list(map(int, input().split()))

#処理内容
def main():
	N, M = getlist()
	G = Graph()
	for i in range(M):
		A, B = getlist()
		A -= 1; B -= 1
		G.add_edge(A, B)

	cycle_dist = INF
	cycle_path = None
	for i in range(N):
		BF = BFS(G, i, N)
		dist_var, dist_path = BF.cycle()
		if dist_var < cycle_dist:
			cycle_dist = dist_var
			cycle_path = dist_path

	if cycle_dist == INF:
		print(-1)
	else:
		print(cycle_dist)
		for i in cycle_path:
			print(i + 1)


if __name__ == '__main__':
	main()

Submission status: Time Limit Exceeded

Solution code:
import sys; input = sys.stdin.buffer.readline
from collections import defaultdict
import queue
INF = float("inf")

class Graph(object):
	def __init__(self):
		self.graph = defaultdict(list)

	def __len__(self):
		return len(self.graph)

	def add_edge(self, a, b):
		self.graph[a].append(b)

	def get_nodes(self):
		return self.graph.keys()

class BFS(object):
	def __init__(self, graph, s, N):
		self.g = graph.graph
		self.Q = queue.Queue()
		self.Q.put(s)
		self.visit = ["No"] * N
		self.visit[s] = "Yes"
		self.judge = "Yes"
		self.prev = [None] * N
		self.path = []
		while not self.Q.empty():
			v = self.Q.get()
			for i in self.g[v]:
				if self.visit[i] == "No":
					self.Q.put(i)
					self.visit[i] = "Yes"
					self.prev[i] = v
				else:
					if i == s:
						self.judge = "No"
						#閉路path構築
						while True:
							self.path.append(v)
							v = self.prev[v]
							if v == None:
								break
		
			if self.judge == "No":
				break
		# print(self.path)

	def cycle(self):
		if self.judge == "No":
			return list(reversed(self.path))
		else:
			return []

def getlist():
	return list(map(int, input().split()))

#処理内容
def main():
	N, M = getlist()
	G = Graph()
	for i in range(M):
		A, B = getlist()
		A -= 1; B -= 1
		G.add_edge(A, B)

	cycle_dist = INF
	cycle_path = None
	for i in range(N):
		BF = BFS(G, i, N)
		dist_path = BF.cycle()
		dist_var = len(dist_path)
		if dist_path != []:
			if dist_var < cycle_dist:
				cycle_dist = dist_var
				cycle_path = dist_path

	if cycle_dist == INF:
		print(-1)
	else:
		print(cycle_dist)
		for i in cycle_path:
			print(i + 1)


if __name__ == '__main__':
	main()

Submission status: Time Limit Exceeded

Solution code:
import queue

n,m = map(int, input().split())

edge = [[] for i in range(n)]

for i in range(m):
    a,b = map(int, input().split())
    a-=1
    b-=1
    edge[a].append(b)

a = [-1,10**10]

for s in range(n):
    q = queue.Queue()
    q.put((s,1))
    visited = [0]*n
    visited[s] = 1
    # 自分に到達した時、flag 0に。
    flag = 1
    while (not q.empty()) and flag:
        p,d = q.get()
        for t in edge[p]:
            if t == s:
                if a[1]>d:
                    a = [s,d]
                flag = 0
                break
            elif visited[t]==0:
                q.put((t,d+1))
                visited[t]=1

# 閉路ない時
if a[0]==-1:
    print(-1)
    exit()

# 閉路ある時、最小閉路を含む頂点から、経路を求めなおす。
s = a[0]
q = queue.Queue()
q.put((s,[s]))
visited = [0]*n
visited[s] = 1
# 自分に到達した時、flag 0に。
flag = 1
ans = []
while (not q.empty()) and flag:
    p,r = q.get()
    for t in edge[p]:
        if t == s:
            ans = r
            flag = 0
            break
        elif visited[t]==0:
            q.put((t,r+[t]))
            visited[t]=1

print(len(ans))
for i in range(len(ans)):
    print(ans[i]+1)

Submission status: Time Limit Exceeded

Solution code:
import queue

n,m = map(int, input().split())

edge = [[] for i in range(n)]

for i in range(m):
    a,b = map(int, input().split())
    a-=1
    b-=1
    edge[a].append(b)

a = [-1,10**10,[]]

for s in range(n):
    q = queue.Queue()
    q.put((s,1,[s]))
    visited = [0]*n
    visited[s] = 1
    flag = 1
    while (not q.empty()) and flag:
        p,d,r = q.get()
        for t in edge[p]:
            if t == s:
                if a[1]>d:
                    a = [s,d,r]
                flag = 0
                break
            elif visited[t]==0:
                q.put((t,d+1,r+[t]))
                visited[t]=1

if a[0]==-1:
    print(-1)
else:
    print(a[1])
    for i in range(len(a[2])):
        print(a[2][i]+1)

Submission status: Time Limit Exceeded

Solution code:
import sys
sys.setrecursionlimit(10**7)
import copy
def myhash(v):
    r = 0
    for i in v:
        r += pow(2, i)
    return r
def myhash2(r, N):
    vv = set()
    for i, v in enumerate(format(r, '0'+str(N)+'b')):
        if v == '1':
            vv.add(N-i-1)
    return vv
def main():
    N, M  = map(int, input().split())
    l = [[] for _ in range(N)]
    r = []
    for _ in range(M):
        a, b = map(int, input().split())
        l[a-1].append(b-1)
    a = []
    def cyclic(n, l, r):
        ans = []
        r += pow(2, n)
        v = myhash2(r, N)
        for i in  l[n]:
            if i in v:
                a.append(r)
                return
                #return True, v
        for i in l[n]:
            cyclic(i, l, r)
        return
    for i in range(N):
        r = 0
        cyclic(i, l, r)
    if a:
        m = 100000
        rr = None
        for i in a:
            x = len(myhash2(i, N))
            if m > x:
                m = x
                rr = i
        print(m)
        for i in myhash2(rr, N):
            print(i+1)
    else:
        print(-1)
    return -1
main()

Submission status: Time Limit Exceeded

Solution code:
import sys
sys.setrecursionlimit(10**7)
import copy
def myhash(v):
    r = 0
    for i in v:
        r += pow(2, i)
    return r
def myhash2(r, N):
    vv = set()
    for i, v in enumerate(format(r, '0'+str(N)+'b')):
        if v == '1':
            vv.add(N-i-1)
    return vv
def main():
    N, M  = map(int, input().split())
    l = [[] for _ in range(N)]
    r = []
    for _ in range(M):
        a, b = map(int, input().split())
        l[a-1].append(b-1)
    a = set()
    def cyclic(n, l, r):
        ans = []
        r += pow(2, n)
        v = myhash2(r, N)
        for i in  l[n]:
            if i in v:
                a.add(r)
                return
                #return True, v
        for i in l[n]:
            cyclic(i, l, r)
        return
    for i in range(N):
        r = 0
        cyclic(i, l, r)
    if a:
        m = 100000
        rr = None
        for i in a:
            x = len(myhash2(i, N))
            if m > x:
                m = x
                rr = i
        print(m)
        for i in myhash2(rr, N):
            print(i+1)
    else:
        print(-1)
    return -1
main()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**5)

N, M = map(int, input().split())
G = [[] for _ in range(N+1)]
for _ in range(M):
    A, B = map(int, input().split())
    G[A].append(B)

def dfs(v, o):
    for c in G[v]:
        if c == o:
            return [v]
    for c in G[v]:
        ret = dfs(c, o)
        if ret:
            return [v] + ret

for v in range(1, N+1):
    cur = dfs(v, v)
    if cur:
        break
else:
    print(-1)
    exit()

while True:
    cur_set = set(cur)
    unused = None
    for i in range(len(cur)):
        u, v = cur[i], cur[(i+1) % len(cur)]
        for c in G[u]:
            if c == v:
                continue
            elif c in cur_set:
                unused = (i, cur.index(c))
                break

    if not unused:
        break
    else:
        t, s = unused
        nxt = []
        i = s
        while i != t:
            nxt.append(cur[i])
            i = (i + 1) % len(cur)
        nxt.append(cur[t])
        cur = nxt

print(len(cur))
print(*cur, sep='\n')

Submission status: Time Limit Exceeded

Solution code:
from collections import defaultdict
import sys
input = sys.stdin.readline

N, M = map(int, input().split())
G = [[] for _ in range(N+1)]
for _ in range(M):
    A, B = map(int, input().split())
    G[A].append(B)

def dfs(v, o):
    if memo[v]:
        return memo[v]

    if len(parents[v]) > 1:
        memo[v] = []
        return []
    for c in G[v]:
        parents[c].add(v)

    ancestors.add(v)
    for c in G[v]:
        if c in ancestors - {o}:
            ancestors.remove(v)
            memo[v] = []
            return []

    ret = []
    if any(c == o for c in G[v]):
        ret = [v]
    else:
        for c in G[v]:
            ret = dfs(c, o)
            if ret:
                ret.append(v)
                break

    ancestors.remove(v)
    for c in G[v]:
        parents[c].remove(v)
    memo[v] = ret
    return ret

for v in range(1, N+1):
    ancestors = set()
    parents = defaultdict(set)
    memo = [None] * (N+1)
    cand = dfs(v, v)
    if cand:
        print(len(cand))
        print(*cand, sep='\n')
        break
else:
    print(-1)

Submission status: Time Limit Exceeded

Solution code:
from collections import defaultdict
import sys
input = sys.stdin.readline

N, M = map(int, input().split())
G = [[] for _ in range(N+1)]
for _ in range(M):
    A, B = map(int, input().split())
    G[A].append(B)

def dfs(v, o):
    if len(parents[v]) > 1:
        return []
    for c in G[v]:
        parents[c].add(v)

    ancestors.add(v)
    for c in G[v]:
        if c in ancestors - {o}:
            ancestors.remove(v)
            return []

    ret = []
    if any(c == o for c in G[v]):
        ret = [v]
    else:
        for c in G[v]:
            ret = dfs(c, o)
            if ret:
                ret.append(v)
                break

    ancestors.remove(v)
    for c in G[v]:
        parents[c].remove(v)
    return ret

for v in range(1, N+1):
    ancestors = set()
    parents = defaultdict(set)
    cand = dfs(v, v)
    if cand:
        print(len(cand))
        print(*cand, sep='\n')
        break
else:
    print(-1)

Submission status: Time Limit Exceeded

Solution code:
from collections import defaultdict
import sys
input = sys.stdin.readline

N, M = map(int, input().split())
G = [[] for _ in range(N+1)]
for _ in range(M):
    A, B = map(int, input().split())
    G[A].append(B)

def dfs(v, o):
    if len(parents[v]) > 1:
        return []

    ancestors.add(v)

    # check c -> ancestor
    for c in G[v]:
        if c in ancestors - {o}:
            ancestors.remove(v)
            return []

    # add to parents
    for c in G[v]:
        parents[c].add(v)

    # check each child
    ret = []
    if any(c == o for c in G[v]):
        ret = [v]
    else:
        for c in G[v]:
            a = dfs(c, o)
            if a:
                ret = [v] + a
                break

    ancestors.remove(v)
    for c in G[v]:
        parents[c].remove(v)
    return ret

for v in range(1, N+1):
    ancestors = set()
    parents = defaultdict(set)
    cand = dfs(v, v)
    if cand:
        print(len(cand))
        print(*cand, sep='\n')
        break
else:
    print(-1)

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

N, M = map(int, input().split())
G = [[] for _ in range(N+1)]
for _ in range(M):
    A, B = map(int, input().split())
    G[A].append(B)

def dfs(v, o):
    ret = []
    ancestors.add(v)
    for c in G[v]:
        if c == o:
            ancestors.remove(v)
            return [[v]]
        elif c in ancestors:
            ancestors.remove(v)
            return []
        else:
            for a in dfs(c, o):
                ret.append([v] + a)
    ancestors.remove(v)
    return ret

for v in range(1, N+1):
    ancestors = set()
    for cand in dfs(v, v):
        cand = set(cand)
        for v in cand:
            cnt = 0
            for c in G[v]:
                if c in cand:
                    cnt += 1
            if cnt >= 2:
                break
        else:
            print(len(cand))
            print(*cand, sep='\n')
            exit()
print(-1)

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

N, M = map(int, input().split())
G = [[] for _ in range(N+1)]
for _ in range(M):
    A, B = map(int, input().split())
    G[A].append(B)

def dfs(v, o):
    ret = []
    ancestors.add(v)
    for c in G[v]:
        if c == o:
            ret.append([v])
        elif c in ancestors:
            continue
        else:
            for a in dfs(c, o):
                ret.append([v] + a)
    ancestors.remove(v)
    return ret

for v in range(1, N+1):
    ancestors = set()
    for cand in dfs(v, v):
        cand = set(cand)
        for v in cand:
            cnt = 0
            for c in G[v]:
                if c in cand:
                    cnt += 1
            if cnt >= 2:
                break
        else:
            print(len(cand))
            print(*cand, sep='\n')
            exit()
print(-1)

Submission status: Time Limit Exceeded

Solution code:
N,M = map(int,input().split())
AB = [tuple(map(int,input().split())) for i in range(M)]
es = [[] for i in range(N)]
for a,b in AB:
    a,b = a-1,b-1
    es[a].append(b)

from collections import deque
mindist = N
opt = None
for g,tos in enumerate(es):
    for s in tos:
        q = deque([(s,0)])
        prev = [-1]*N
        while q:
            v,d = q.popleft()
            for to in es[v]:
                if to==g: break
                if prev[to] >= 0: continue
                prev[to] = v
                q.append((to,d+1))
            else:
                continue
            break
        else:
            continue
        if d+1 >= mindist: continue
        mindist = d+1
        opt = [g,v]
        while prev[opt[-1]] >= 0:
            opt.append(prev[opt[-1]])
if opt:
    ans = [o+1 for o in opt]
    print(len(ans))
    print(*ans, sep='\n')
else:
    print(-1)

Submission status: Time Limit Exceeded

Solution code:
def dijkstra_back(s,t,n,w,cost):
    #sからtへの最短経路の経路復元
    prev = [s] * n #最短経路の直前の頂点
    d = [float("inf")] * n
    used = [False] * n
    d[s] = 0

    while True:
        v = -1
        for i in range(n):
            if (not used[i]) and (v == -1):
               v = i
            elif (not used[i]) and d[i] < d[v]:
                v = i
        if v == -1:
               break
        used[v] = True

        for i in range(n):
            if d[i] > d[v] + cost[v][i]:
                d[i] = d[v] + cost[v][i]
                prev[i] = v

    path = [t]
    while prev[t] != s:
        path.append(prev[t])
        prev[t] = prev[prev[t]]
    path.append(s)
    path = path[::-1]
    return path



N,M=map(int,input().split())
fr={i:set([]) for i in range(1,N+1)}
to={i:set([]) for i in range(1,N+1)}
for i in range(0,M):
    a,b=map(int,input().split())
    fr[b].add(a)
    to[a].add(b)

delete=set([])
flag=1
while flag==1:
    flag=0
    for i in range(1,N+1):
        if (not i in delete) and (delete>=fr[i] or delete>=to[i]):
            delete.add(i)
            flag=1

node=[i for i in range(1,N+1)]
save=set(node)-delete
if save:
    hen=[]
    for i in save:
        fr[i]=fr[i]&save
        to[i]=to[i]&save

    for i in save:
        for j in fr[i]:
            hen.append((j,i))

    save=list(save)

    cost=[[float('inf') for i in range(0,N+1)] for i in range(0,N+1)]
    for i in range(0,len(hen)):
        a,b=hen[i]
        cost[a][b]=1

    ansc=10**10
    ans=[]
    for i in range(len(save)):
        for j in fr[save[i]]:
            test=dijkstra_back(save[i],j,N+1,len(hen),cost)
            if len(test)<ansc:
                ansc=len(test)
                ans=test

    print(ansc)
    for i in range(0,ansc):
        print(ans[i])

else:
    print(-1)

Submission status: Time Limit Exceeded

Solution code:
def examA():
    class Dijkstra(object):
        """
        construct: O(ElogV)
        """
        def __init__(self, edges, start=0):
            """
            :param list of list of list of int edges:
            :param int start=0:
            """
            self.__dist = [inf] * len(edges)
            self.__dist[start] = 0
            self.__calculate(edges, start)

        @property
        def dist(self):
            return self.__dist

        def __calculate(self, edges, start):
            Q = [(0, start)]  # (dist,vertex)
            while (Q):
                dist, v = heapq.heappop(Q)
                if self.dist[v] < dist: continue  # 候補として挙がったd,vだが、他に短いのがある
                for u, cost in edges[v]:
                    if self.dist[u] > self.dist[v] + cost:
                        self.__dist[u] = self.dist[v] + cost
                        heapq.heappush(Q, (self.dist[u], u))
    N, L = LI()
    V, D = LI()
    X = [LI()for _ in range(N)]
    X.append([0,V,D])
    X.append([L,0,0])
    X.sort()
    V = [[]for _ in range(N+2)]
    for i in range(N+1):
        x1, v1, d1 = X[i]
        r = x1 + d1
        for j in range(i+1,N+2):
            x2, v2, d2 = X[j]
            if r<x2:
                break
            cost = (x2-x1)/v1
            V[i].append((j,cost))

    dij = Dijkstra(V, 0)
    ans = dij.dist[-1]
    if ans>=inf:
        print("impossible")
        return
    print('{:.18f}'.format(ans))
    return

def examB():
    N, K = LI()
    H = 11; W = 7
    S = [[0]*(W+1) for _ in range(H+3)]
    for h in range(H+2):
        for w in range(W):
            S[h+1][w+1] = (S[h][w+1] + S[h+1][w] - S[h][w] + (7*h+w+1))
    #print(S)
    base = 0
    for h in range(H):
        for w in range(W-2):
            cur = S[h+3][w+3] - S[h+3][w] - S[h][w+3] + S[h][w]
            if cur%11==K:
                base += 1
                #print(h,w)
    ans = base * ((N-2)//11)
    #print(ans)
    rest = (N-2)%11
    for h in range(rest):
        for w in range(W-2):
            cur = S[h+3][w+3] - S[h+3][w] - S[h][w+3] + S[h][w]
            if cur%11==K:
                ans += 1
                #print(h,w)
    print(ans)
    return

def examC():
    N, K = LI()
    A = LI()
    loop = 2**N
    ans = inf
    for i in range(loop):
        cnt = 0
        need = 0
        highest = 0
        for j in range(N):
            if i&(1<<j)==0:
                if highest<A[j]:
                    need = inf
                    break
                continue
            cnt += 1
            if highest>=A[j]:
                need += (highest+1-A[j])
                highest = highest + 1
            else:
                highest = A[j]
        if cnt>=K and need<ans:
            ans = need
        #print(need)
    print(ans)
    return

def examD():
    # 参考 https://qiita.com/maskot1977/items/e1819b7a1053eb9f7d61
    def cycle(neighbor, start, ring_size, node):
        visited = set()
        stack = []
        stack.append(start)
        path = [{} for _ in range(node)]
        path[start] = {start}
        visited.add(start)
        while (stack):
            last = stack.pop()
            curr_path = path[last]
            if len(curr_path) > ring_size:
                continue
            for nei in neighbor[last]:
                if nei in curr_path:
                    if start == nei:
                        return curr_path
                    else:
                        return cycle(neighbor,nei,ring_size-1,node)
                if nei in visited:
                    continue
                visited.add(nei)
                path[nei] = curr_path | {nei}
                stack.append(nei)
        return -1,visited
    N, M = LI()
    V = [[]for _ in range(N)]
    for _ in range(M):
        a,b = LI()
        a -= 1; b -= 1
        V[a].append(b)
    #print(V)
    loop = -1
    visited = [False]*N
    for i in range(N):
        if visited[i]:
            continue
        loop = cycle(V,i,N,N)
        if type(loop) is set:
            break
        for v in loop[1]:
            visited[v] = True
    if type(loop) is not set:
        print(-1)
        return
    while(True):
        visited = [False] * N
        next = -1
        for k in loop:
            next = cycle(V,k,len(loop)-1,N)
            if type(next) is set:
                break
            for v in next[1]:
                visited[v] = True
        if type(next) is not set:
            break
        loop = next

    ans = loop
    print(len(ans))
    for v in ans:
        print(v+1)
    return

import sys,bisect,itertools,heapq,math,random
from copy import copy,deepcopy
from heapq import heappop,heappush,heapify
from collections import Counter,defaultdict,deque
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))
def LSI(): return list(map(str,sys.stdin.readline().split()))
def LS(): return sys.stdin.readline().split()
def SI(): return sys.stdin.readline().strip()
global mod,mod2,inf,alphabet,_ep
mod = 10**9 + 7
mod2 = 998244353
inf = 10**18
_ep = 10**(-12)
alphabet = [chr(ord('a') + i) for i in range(26)]

sys.setrecursionlimit(10**6)

if __name__ == '__main__':
    examD()

Submission status: Time Limit Exceeded

Solution code:
def examA():
    class Dijkstra(object):
        """
        construct: O(ElogV)
        """
        def __init__(self, edges, start=0):
            """
            :param list of list of list of int edges:
            :param int start=0:
            """
            self.__dist = [inf] * len(edges)
            self.__dist[start] = 0
            self.__calculate(edges, start)

        @property
        def dist(self):
            return self.__dist

        def __calculate(self, edges, start):
            Q = [(0, start)]  # (dist,vertex)
            while (Q):
                dist, v = heapq.heappop(Q)
                if self.dist[v] < dist: continue  # 候補として挙がったd,vだが、他に短いのがある
                for u, cost in edges[v]:
                    if self.dist[u] > self.dist[v] + cost:
                        self.__dist[u] = self.dist[v] + cost
                        heapq.heappush(Q, (self.dist[u], u))
    N, L = LI()
    V, D = LI()
    X = [LI()for _ in range(N)]
    X.append([0,V,D])
    X.append([L,0,0])
    X.sort()
    V = [[]for _ in range(N+2)]
    for i in range(N+1):
        x1, v1, d1 = X[i]
        r = x1 + d1
        for j in range(i+1,N+2):
            x2, v2, d2 = X[j]
            if r<x2:
                break
            cost = (x2-x1)/v1
            V[i].append((j,cost))

    dij = Dijkstra(V, 0)
    ans = dij.dist[-1]
    if ans>=inf:
        print("impossible")
        return
    print('{:.18f}'.format(ans))
    return

def examB():
    N, K = LI()
    H = 11; W = 7
    S = [[0]*(W+1) for _ in range(H+3)]
    for h in range(H+2):
        for w in range(W):
            S[h+1][w+1] = (S[h][w+1] + S[h+1][w] - S[h][w] + (7*h+w+1))
    #print(S)
    base = 0
    for h in range(H):
        for w in range(W-2):
            cur = S[h+3][w+3] - S[h+3][w] - S[h][w+3] + S[h][w]
            if cur%11==K:
                base += 1
                #print(h,w)
    ans = base * ((N-2)//11)
    #print(ans)
    rest = (N-2)%11
    for h in range(rest):
        for w in range(W-2):
            cur = S[h+3][w+3] - S[h+3][w] - S[h][w+3] + S[h][w]
            if cur%11==K:
                ans += 1
                #print(h,w)
    print(ans)
    return

def examC():
    N, K = LI()
    A = LI()
    loop = 2**N
    ans = inf
    for i in range(loop):
        cnt = 0
        need = 0
        highest = 0
        for j in range(N):
            if i&(1<<j)==0:
                if highest<A[j]:
                    need = inf
                    break
                continue
            cnt += 1
            if highest>=A[j]:
                need += (highest+1-A[j])
                highest = highest + 1
            else:
                highest = A[j]
        if cnt>=K and need<ans:
            ans = need
        #print(need)
    print(ans)
    return

def examD():
    # 参考 https://qiita.com/maskot1977/items/e1819b7a1053eb9f7d61
    def cycle(neighbor, start, ring_size, node):
        visited = [{} for _ in range(node)]
        stack = []
        stack.append(start)
        visited[start] = {start}
        while (stack):
            last = stack.pop()
            curr_path = visited[last]
            if len(curr_path) > ring_size:
                continue
            for nei in neighbor[last]:
                if nei in visited[last]:
                    if start == nei:
                        return visited[last]
                    else:
                        return cycle(neighbor,nei,ring_size-1,node)
                if visited[nei]:
                    continue
                visited[nei] = visited[last] | {nei}
                stack.append(nei)
        return -1
    N, M = LI()
    V = [[]for _ in range(N)]
    for _ in range(M):
        a,b = LI()
        a -= 1; b -= 1
        V[a].append(b)
    #print(V)
    loop = -1
    for i in range(N):
        loop = cycle(V,i,N,N)
        if loop!=-1:
            break
    if loop==-1:
        print(-1)
        return
    while(True):
        next = -1
        for k in loop:
            next = cycle(V,k,len(loop)-1,N)
            if next != -1:
                break
        if next==-1:
            break
        loop = next

    ans = loop
    print(len(ans))
    for v in ans:
        print(v+1)
    return

import sys,bisect,itertools,heapq,math,random
from copy import copy,deepcopy
from heapq import heappop,heappush,heapify
from collections import Counter,defaultdict,deque
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))
def LSI(): return list(map(str,sys.stdin.readline().split()))
def LS(): return sys.stdin.readline().split()
def SI(): return sys.stdin.readline().strip()
global mod,mod2,inf,alphabet,_ep
mod = 10**9 + 7
mod2 = 998244353
inf = 10**18
_ep = 10**(-12)
alphabet = [chr(ord('a') + i) for i in range(26)]

sys.setrecursionlimit(10**6)

if __name__ == '__main__':
    examD()