Harryxun/sft_time huggingface dataset:
### BUGGY CODE ###

from collections import deque

INF = 1000000000
h,w = map(int, input().split())
maze = [list(input()) for _ in range(h)]

def bfs(sx, sy, gx, gy):
    ds = [[1,0], [-1,0], [0,1], [0,-1]]
    visited = [[False for _ in range(h)] for _ in range(w)]
    distance = [[INF for _ in range(h)] for _ in range(w)]
    q = deque([[sx, sy]])
    distance[sx][sy] = 0

    while q:
        x, y = q.popleft()
        if visited[x][y]: continue
        visited[x][y] = True
        #print('-----', x, y)
        for dx, dy in ds:
            nx = x+dx
            ny = y+dy
            if (nx >= 0) and (nx <= w-1) and (ny >= 0) and (ny <= h-1):
                #print(nx, ny)
                if maze[ny][nx] != '#':
                    q.append([nx, ny])
                    distance[nx][ny] = min(distance[nx][ny], distance[x][y] + 1)
    return distance[gx][gy]

count = 0
for s_x in range(w):
    for s_y in range(h):
        if maze[s_y][s_x] == '.':
            for g_x in range(w):
                for g_y in range(h):
                    if (maze[g_y][g_x] == '.' and ((s_x != g_x) or (s_y != g_y))):
                        #print(s_x, s_y, g_x, g_y)
                        ans = bfs(s_x, s_y, g_x, g_y)
                        #print(ans)
                        if ans != INF and ans > count:
                            count = ans

print(count)


### FIXED CODE ###

from collections import deque

INF = 1000000000
h,w = map(int, input().split())
maze = [list(input()) for _ in range(h)]

def bfs(sx, sy):
    ds = [[1,0], [-1,0], [0,1], [0,-1]]
    distance = [[-1 for _ in range(h)] for _ in range(w)]
    q = deque([[sx, sy]])
    distance[sx][sy] = 0

    while q:
        x, y = q.popleft()
        #print('-----', x, y)
        for dx, dy in ds:
            nx, ny = x+dx, y+dy
            if (nx >= 0) and (nx <= w-1) and (ny >= 0) and (ny <= h-1):
                #print(nx, ny)
                if maze[ny][nx] != '#' and distance[nx][ny] == -1:
                    q.append([nx, ny])
                    distance[nx][ny] = distance[x][y] + 1
    return max(map(max, distance))

count = 0
for s_x in range(w):
    for s_y in range(h):
        if maze[s_y][s_x] == '.':
            count = max(count, bfs(s_x, s_y))

print(count)
### BUGGY CODE ###

n = int(input())

A = list(map(int,input().split()))
ans = 1
if 0 in A:
    print(0)
else:
    for i in A:
        ans *= i

    if ans > 10**18:
        print(-1)
    else:
        print(ans)

### FIXED CODE ###

n = int(input())

A = list(map(int,input().split()))
ans = 1
if 0 in A:
    print(0)
else:
    f = 0
    for i in A:
        ans *= i
        if ans > 10**18:
            print(-1)
            f = 1
            break
    if f == 0:
        print(ans)
### BUGGY CODE ###

n = int(input())
A = [int(i) for i in input().split()]
b = []
for i in range(n):
  b.append(A[i])
  b = b[::-1]
print(*b)
  

### FIXED CODE ###

from collections import deque
n = int(input())
A = list(map(int,input().split()))
l = deque()
for i in range(len(A)):
  if n % 2 == 0:
    if i % 2 == 0:
      l.append(A[i])
    else:
      l.appendleft(A[i])
  else:
    if i % 2 == 0:
      l.appendleft(A[i])
    else:
      l.append(A[i])
print(*l)
### BUGGY CODE ###

n = int(input())
l = [list(map(int,input().split())) for i in range(n)]
left = []



for i in range(n):
    left.append((l[i][0]-l[i][1],l[i][0]+l[i][1]))
left.sort()   
count = 1
right = 10**10
for i in range(n):
    right = min(right,left[i][1])

while True:
    right2 = 10**10
    for i in range(n):
        if left[i][0] >= right:
            
            right2 = min(right2,left[i][1])
            
            
    if right2 == 10**10:
        print(count)
        exit()
    else:
        right = right2
        count += 1


### FIXED CODE ###

n = int(input())
l = [list(map(int,input().split())) for i in range(n)]
left = []



for i in range(n):
    left.append((l[i][0]+l[i][1],l[i][0]-l[i][1]))
left.sort()   
count = 1
right = 10**10
right = left[0][0]
c = 0

while True:
    
    for i in range(c,n+1):
        if i == n:
            print(count)
            exit()
        if left[i][1] >= right:
            count += 1
            right = left[i][0]
            c = i
            
            
            
    if c == n-1:
        print(count)
        exit()
### BUGGY CODE ###

import copy
N,M = map(int, input().split())
t_table = {}
for i in range(M):
	x,y = map(int, input().split())
	if x-1 in t_table: t_table[x-1].append(y-1)
	else: t_table[x-1] = [y-1]
ans = 0
dp = [1 for _ in range(N)]
zerolist = [0 for _ in range(N)]
while True:
	pnode = copy.copy(dp)
	dp = [0 for _ in range(N)]
	for i in range(N):
		if pnode[i] == 1 and i in t_table:
			for j in t_table[i]:
				if dp[j]==0 : dp[j]= 1
	if(dp == zerolist):
	 	print(ans)
	 	break
	ans += 1


### FIXED CODE ###

import sys

sys.setrecursionlimit(10**5+10)
input = sys.stdin.readline

N,M = map(int, input().split())
lst_edge = [[] for _ in range(N)]
for _ in range(M):
	x,y = map(int, input().split())
	lst_edge[x-1].append(y-1)

dp = [-1] * N

def rec(v):
	if dp[v] != -1:
		return dp[v]
	ans = 0
	lst_nv = lst_edge[v]
	for nv in lst_nv:
		ans = max(ans, rec(nv)+1)
	dp[v] = ans
	return dp[v]

ans = 0
for v in range(N):
	ans = max(ans,rec(v))
print(ans)
### BUGGY CODE ###

from collections import defaultdict
import queue

n, x, y = map(int, input().split())

edges = [[] for _ in range(n)]
for i in range(n-1):
    edges[i].append(i+1)

for i in range(1, n):
    edges[i].append(i-1)

edges[x-1].append(y-1)
edges[y-1].append(x-1)

count = defaultdict(int)


def bfs(start):
    dist = [10**4] * n
    dist[start] = 0
    todo = queue.Queue(maxsize=10)
    for to in edges[start]:
        todo.put([1, to])

    while not todo.empty():
        d, node = todo.get()
        if d >= dist[node]:
            continue

        dist[node] = d
        for to in edges[node]:
            todo.put([d+1, to])
    return dist


for start in range(n):
    dist = bfs(start)
    for d in dist:
        count[d] += 1

for k in range(1, n):
    res = count[k] // 2
    print(res)

### FIXED CODE ###

from collections import defaultdict
from collections import deque

n, x, y = map(int, input().split())

edges = [[] for _ in range(n)]
for i in range(n-1):
    edges[i].append(i+1)

for i in range(1, n):
    edges[i].append(i-1)

edges[x-1].append(y-1)
edges[y-1].append(x-1)

count = defaultdict(int)


def bfs(start):
    dist = [10**4] * n
    dist[start] = 0
    todo = deque([])
    for to in edges[start]:
        todo.append([1, to])

    while todo:
        d, node = todo.popleft()
        if d >= dist[node]:
            continue

        dist[node] = d
        for to in edges[node]:
            todo.append([d+1, to])
    return dist


for start in range(n):
    dist = bfs(start)
    for d in dist:
        count[d] += 1

for k in range(1, n):
    res = count[k] // 2
    print(res)
### BUGGY CODE ###

N, Q = [int(nq) for nq in input().split()]
S = input()
ANS = []
for q in range(Q):
    l, r = [int(lr) for lr in input().split()]
    ans = S[l-1:r].count("AC")
    ANS.append(ans)
for q in range(Q):
    print(ANS[q])

### FIXED CODE ###

N, Q = [int(nq) for nq in input().split()]
S = input()
AC = []
for s in range(len(S)-1):
    if S[s:s+2] == "AC":
        AC.append(1)
    else:
        AC.append(0)
CS = [0]*len(AC)
CS[0] = AC[0]
for i in range(len(AC)-1):
    CS[i+1] = CS[i] + AC[i+1]
for q in range(Q):
    l, r = [int(lr) for lr in input().split()]
    if l == 1:
        print(CS[r-2])
    else:
        print(CS[r-2] - CS[l-2])
### BUGGY CODE ###

import sys
from math import ceil, floor
from collections import deque, Counter, defaultdict
from fractions import gcd
input = lambda: sys.stdin.readline().rstrip()

def eprint(s):
    sys.stderr.write('DEBUG: {}'.format(s))
    return

def main():
    s = input()
    q = int(input())
    ans = deque()
    swap = False
    for i in range(len(s)):
        ans.append(s[i])

    for i in range(q):
        #print(ans, swap)
        inp = input()
        if len(inp) == 1:
            hoge = int(inp)
            if swap:
                swap = False
            else:
                swap = True
        else:
            # print(tuple(inp))
            fi, ci = tuple(inp)[2], tuple(inp)[4]
                       
            if int(fi) == 1:
                if not swap:
                    ans.appendleft(ci)
                else:
                    ans.append(ci)
            if int(fi) == 2:
                if not swap:
                    ans.append(ci)
                else:
                    ans.appendleft(ci)
    s_ans = str()
    if swap:
        for i in range(len(ans)-1,-1, -1):
            s_ans += ans[i]
    else:
        for i in range(len(ans)):
            s_ans += ans[i]
    
    print(s_ans)
                
    return

if __name__ == '__main__':
    main()

### FIXED CODE ###

import sys
from math import ceil, floor
from collections import deque, Counter, defaultdict
from fractions import gcd
input = lambda: sys.stdin.readline().rstrip()

def eprint(s):
    sys.stderr.write('DEBUG: {}'.format(s))
    return

def main():
    s = input()
    q = int(input())
    ans = deque()
    swap = False
    for i in range(len(s)):
        ans.append(s[i])

    for i in range(q):
        #print(ans, swap)
        inp = input()
        if len(inp) == 1:
            hoge = int(inp)
            if swap:
                swap = False
            else:
                swap = True
        else:
            # print(tuple(inp))
            fi, ci = tuple(inp)[2], tuple(inp)[4]
                       
            if int(fi) == 1:
                if not swap:
                    ans.appendleft(ci)
                else:
                    ans.append(ci)
            if int(fi) == 2:
                if not swap:
                    ans.append(ci)
                else:
                    ans.appendleft(ci)
    s_ans = str()
    ans = list(ans)
    if swap:
        for i in range(len(ans)-1,-1, -1):
            s_ans += ans[i]
    else:
        for i in range(len(ans)):
            s_ans += ans[i]
    
    print(s_ans)
                
    return

if __name__ == '__main__':
    main()
### BUGGY CODE ###

k = int(input())
seven = 0
i = 0
if k % 2 == 0:
    print(-1)
else:
    while True:
        i += 1
        seven = seven * 10 + 7
        seven = seven % k
        if seven == 0:
            print(i)
            break

### FIXED CODE ###

k=int(input())


def get(k):
    ans=7
    i=1
    while True:
        if ans%k==0:
            return i
        ans=(ans*10+7)%k
        i+=1




if k%2==0 or k%5==0:
    print(-1)

else:
    print(get(k))
### BUGGY CODE ###

k=int(input())
ans=0
from fractions import gcd
for a in range(1,k+1):
    for b in range(1,k+1):
        t=gcd(a,b)
        for c in range(1,k+1):
            ans+=gcd(c,t)
print(ans)



### FIXED CODE ###

k=int(input())
ans=0
from math import gcd
for a in range(1,k+1):
    for b in range(1,k+1):
        t=gcd(a,b)
        for c in range(1,k+1):
            ans+=gcd(c,t)
print(ans)
### BUGGY CODE ###


A,B =[int(x) for x in input().split()]

def bunkai(n):
    sosu= {1}
    tmp = n
    stop_flag = n
    
    if tmp%2 == 0:
        while tmp%2==0:
            tmp //=2
        sosu.add(2)
    
    for i in range(3,n+1,2):
        if tmp%i == 0:
            while tmp%i==0:
                tmp //=i
            sosu.add(i)
            stop_flag = tmp 
            
        if i > stop_flag:
            break
#        else:
#            stop_flag = int(stop_flag/i) 
            
    if tmp!=1:
        sosu.add(tmp)
                
    if sosu==[1]:
        sosu.add(n)
    
    return sosu

def check_sosu(n,x):
    ans=0
    tmp = n
    for i in x:
        if (tmp % i) == 0:
            ans+=1
    return ans

ans = check_sosu(B,bunkai(A))

print(ans)


### FIXED CODE ###


A,B =[int(x) for x in input().split()]

def bunkai(n):
    sosu= {1}
    tmp = n
    stop_flag = n
    
    if tmp%2 == 0:
        while tmp%2==0:
            tmp //=2
        sosu.add(2)
    
    for i in range(3,n+1,2):
        if tmp%i == 0:
            while tmp%i==0:
                tmp //=i
            sosu.add(i)
            stop_flag = tmp 
            
        if i > stop_flag:
            break
        else:
            stop_flag = int(n/i)+1
            
    if tmp!=1:
        sosu.add(tmp)
                
    if sosu==[1]:
        sosu.add(n)
    
    return sosu

def check_sosu(n,x):
    ans=0
    tmp = n
    for i in x:
        if (tmp % i) == 0:
            ans+=1
    return ans

ans = check_sosu(B,bunkai(A))

print(ans)
### BUGGY CODE ###

import sys
import itertools
# import numpy as np
import time
import math

sys.setrecursionlimit(10 ** 7)

from collections import defaultdict

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

s = input()
q = int(input())
is_reversed = False
for i in range(q):
    query = input().split()
    t = int(query[0])
    if t == 1:
        is_reversed = not is_reversed
    elif t == 2:
        f = int(query[1])
        c = query[2]
        if f == 1:
            if is_reversed:
                s += c
            else:
                s = c + s
        elif f == 2:
            if is_reversed:
                s = c + s
            else:
                s += c
if is_reversed:
    print(s[::-1])
else:
    print(s)

### FIXED CODE ###

import sys
import itertools
# import numpy as np
import time
import math

sys.setrecursionlimit(10 ** 7)

from collections import defaultdict

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

s = readline().decode().strip()
q = int(readline())
is_reversed = False
qs = read().decode().split("\n")
left = []
right = [] 
for i in range(q):
    query = qs[i].split()
    t = int(query[0])
    if t == 1:
        is_reversed = not is_reversed
    elif t == 2:
        f = int(query[1])
        c = query[2]
        if f == 1:
            if is_reversed:
                right.append(c)
            else:
                left.append(c)
        elif f == 2:
            if is_reversed:
                left.append(c)
            else:
                right.append(c)

s = "".join(reversed(left)) + s + "".join(right)
if is_reversed:
    print(s[::-1])
else:
    print(s)
### BUGGY CODE ###

from collections import deque
def main():
    n = int(input())
    p = list(map(int, input().split()))
    for i in range(len(p)):
        p[i] -= 1
    
    to_outsides = [[0]*n for _ in range(n)]
    not_exist = [[False]*n for _ in range(n)]
    
    for i in range(n):
        for j in range(n):
            to_outside = [i,n-1-i,j,n-1-j]
            to_outsides[i][j] = min(to_outside)
    
    directions = [[-1,0],[1,0],[0,-1],[0,1]]

    answer = 0
    for i, person in enumerate(p):
        exited = [person//n, person%n]
        answer += to_outsides[exited[0]][exited[1]]
        not_exist[exited[0]][exited[1]] = True
        seen = []
        seen.append([exited[0],exited[1]])
        todo = deque([exited])
        renews = []
        while len(todo)>0:
            now = todo.pop()
            now_to_outside = to_outsides[now[0]][now[1]]
            renews.append(now)
            for direction in directions:
                try:
                    checking = [now[0]+direction[0],now[1]+direction[1]]
                    checking_to_outside = to_outsides[checking[0]][checking[1]]
                except:
                    continue
                if [checking[0],checking[1]] not in seen:
                    if ((not_exist[checking[0]][checking[1]] == True and checking_to_outside==now_to_outside)or\
                     checking_to_outside>now_to_outside):
                        todo.append([checking[0],checking[1]])
                        seen.append([checking[0],checking[1]])
                        
        for renew in renews:
            if to_outsides[renew[0]][renew[1]] != 0:
                to_outsides[renew[0]][renew[1]]-=1
    print(answer)
main()

### FIXED CODE ###

N = int(input())
P = list(map(int, input().split()))

dp = [[min(i, N - i - 1, j, N - j - 1) for j in range(N)] for i in range(N)]

presence = [[1 for j in range(N)] for i in range(N)]

ans = 0
for i in range(len(P)):
    P[i] -= 1
    x, y = divmod(P[i], N)
    ans += dp[x][y]
    presence[x][y] = 0

    Q = [(x, y)]
    #%%
    while Q:
        x, y = Q.pop()
        new_value = dp[x][y] + presence[x][y]
        if 1 <= x and dp[x - 1][y] > new_value:
            dp[x - 1][y] = new_value
            Q.append((x - 1, y))
        if x < N - 1 and dp[x + 1][y] > new_value:
            dp[x + 1][y] = new_value
            Q.append((x + 1, y))
        if 1 <= y and dp[x][y - 1] > new_value:
            dp[x][y - 1] = new_value
            Q.append((x, y - 1))
        if y < N - 1 and dp[x][y + 1] > new_value:
            dp[x][y + 1] = new_value
            Q.append((x, y + 1))

print(ans)
### BUGGY CODE ###

S = list(input())
ln = len(S)
next_lr = [0] * ln
for i in range(ln):
    if S[i] == "R":
        for j in range(i+1,ln):
            if S[j] == "L":
                next_lr[i] = j - i
                break
    else:
        for j in reversed(range(0,i)):
            if S[j] == "R":
                next_lr[i] = j - i
                break

result = [0] * ln
for i in range(ln):
    nx = next_lr[i]
    if nx %2 == 0:
        result[i+nx] += 1
    elif nx > 0:
        result[i+nx-1] += 1
    else:
        result[i+nx+1] += 1

print(" ".join(map(str, result)))


### FIXED CODE ###

S = list(input())
ln = len(S)
next_lr = [0] * ln
next_r = 0
next_l = 0


for i in range(ln):
    if S[i] == "R":
        next_r = i
        if i < next_l:
            next_lr[i] = next_l - i
        else:
            for j in range(i+1,ln):
                if S[j] == "L":
                    next_l = j
                    next_lr[i] = j - i
                    break
    else:
        next_lr[i] = next_r - i


result = [0] * ln
for i in range(ln):
    nx = next_lr[i]
    if nx %2 == 0:
        result[i+nx] += 1
    elif nx > 0:
        result[i+nx-1] += 1
    else:
        result[i+nx+1] += 1

print(" ".join(map(str, result)))
### BUGGY CODE ###

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

# list_n = list(map(int, input().split()))

# n = input()
# list = [input() for i in range(N)

# list = [[i for i in range(N)] for _ in range(M)]

import sys
input = sys.stdin.readline

N, K, Q = map(int, input().split())
list_A = [int(input()) for i in range(Q)]
list_P = [K] * N

for i in range(Q):
    for j in range(N):
        if list_A[i] != j+1:
            list_P[j] -= 1

for i in range(N):
    if list_P[i] <= 0:
        print("No")
    else:
        print("Yes")


### FIXED CODE ###

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

# list_n = list(map(int, input().split()))

# n = input()
# list = [input() for i in range(N)

# list = [[i for i in range(N)] for _ in range(M)]

import sys
input = sys.stdin.readline

N, K, Q = map(int, input().split())
list_P = [K-Q] * N
for i in range(Q):
    A = int(input())
    list_P[A-1] += 1

for i in range(N):
    if list_P[i] <= 0:
        print("No")
    else:
        print("Yes")
### BUGGY CODE ###

N, M = map(int, input().split())

L = []
R = []
C = [1] * N

for i in range(M):
    a, b = map(int, input().split())
    L.append(a)
    R.append(b)

for i in range(M):
    a = L[i] - 1
    b = R[i]

    if a != 0:
        C[:a] = [0] * a
    if b-1 != len(C):
        C[b:] = [0] * (len(C) - b)

print(sum(C))


### FIXED CODE ###

N, M = map(int, input().split())

L = []
R = []
l = 0
r = 10 ** 6
for i in range(M):
    a,b = map(int, input().split())
    L.append(a)
    R.append(b)

for i in range(M):
    if l < L[i]:
        l = L[i]
    if r > R[i]:
        r = R[i]

ans = r-l+1
if ans > 0:
    print(ans)
else:
    print("0")
### BUGGY CODE ###

s = input()

ans = 0
mods = {0: 1} # 0 % n = 0
x = int(s)
for i in range(len(s)):
    if i != 0:
        x -= int(s[i-1]) * 10**(len(s)-i)
    a = x%2019
    if a in mods.keys():
        mods[a] += 1
    else:
        mods[a] = 1

for k in mods.keys():
    counts = mods[k]
    ans += counts // 2
print(ans)

### FIXED CODE ###

from collections import Counter
s = input()

ans = 0
mods = [0]
s = [int(a) for a in s[::-1]]
x = 0
for i in range(len(s)):
    x += s[i] * pow(10, i, 2019)
    mods.append(x%2019)

mods = Counter(mods)

for k in mods.keys():
    counts = mods[k]
    ans += counts * (counts-1) // 2
print(ans)
### BUGGY CODE ###

[n, k], [*a] = [[*map(int, t.split())] for t in open(0)]
ans = 1
for _ in range(k):
    ans = a[ans - 1]
print(ans)


### FIXED CODE ###

[n, k], [*a] = [[*map(int, t.split())] for t in open(0)]
count = 0
visited = dict()
tmp = 1
while count < k:
    visited[tmp] = count
    count += 1
    tmp = a[tmp - 1]
    if tmp in visited:
        break
if count < k:
    k = (k - count) % (count - visited[tmp])
    for _ in range(k):
        tmp = a[tmp - 1]
print(tmp)
### BUGGY CODE ###

import sys
 
def prime_calc(n):
    if n < 2:
        return False
    else:
        i = 2
        while n > i:
            if n % i == 0:
                return False
            else:
                i += 1
    return True
 
def prime(n):
    cnt = 0
    for i in range(0, n+1):
        ans = prime_calc(i)
        if ans is True:
            cnt = cnt + 1
 
    return cnt
 
def main():
    a = []
 
    for line in sys.stdin:
        a.append(int(line))
 
    for line in a:
        print(prime(line))
 
if __name__ == "__main__":
    main()


### FIXED CODE ###

import math
import sys

sup = 1000000

is_prime = [0] * sup

count = [0] * sup

def setup():
    is_prime[2] = 1
    for n in range(3,sup,2):
        flag = True
        for i in range(3, int(math.floor(math.sqrt(n) + 1)), 2):
            if n % i == 0:
                flag = False
                break
        if flag:
            is_prime[n] = 1

def precount():
    for n in range(2, sup):
        count[n] = count[n-1] + is_prime[n]

def main():
    setup()
    precount()

    l = []

    for line in sys.stdin:
        l.append(int(line))

    for line in l:
         print(count[line])

if __name__ == "__main__":
    main()
### BUGGY CODE ###

n,m=map(int,input().split())
a=[]
mod=10**9+7
for i in range(m):
  b=int(input())
  a.append(b)
block=[0,1]
for i in range(1,n+1):
  if i in a:
    block=block[1:]+[0]
  else:
    block=block[1:]+[sum(block)%mod]
print(block[-1])


### FIXED CODE ###

n,m=map(int,input().split())
mod=10**9+7
a = [int(input()) for i in range(m)]
block=[0,1]
x=[True for i in range(n)]
for j in a:
  x[j-1]=False

for i in range(1,n+1):
  if x[i-1]==False:
    block=block[1:]+[0]
  else:
    block=block[1:]+[sum(block)%mod]
print(block[-1])
### BUGGY CODE ###

import sys
input = sys.stdin.readline

N,M=map(int,input().split())
EDGE=[list(map(int,input().split())) for i in range(M)]

REVEDGE=[[] for i in range(N+1)]

LEAF=[]
for x,y in EDGE:
    REVEDGE[y].append(x)
    LEAF.append(x)

LEAF=list(set(range(1,N+1)) - set(LEAF))

from collections import deque
QUE = deque(LEAF)

DIST=[0]*(N+1)

while QUE:
    x=QUE.pop()

    for to in REVEDGE[x]:
        if DIST[to]<DIST[x]+1:
            DIST[to]=DIST[x]+1
            QUE.append(to)

print(max(DIST))
    

### FIXED CODE ###

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)

N,M=map(int,input().split())
EDGE=[list(map(int,input().split())) for i in range(M)]

#REVEDGE=[[] for i in range(N+1)]
EDGELIST=[[] for i in range(N+1)]
LEAF=[]
for x,y in EDGE:
    #REVEDGE[y].append(x)
    EDGELIST[x].append(y)

for i in range(1,N+1):
    if EDGELIST[i]==[]:
        LEAF.append(i)

DIST=[-1]*(N+1)
for l in LEAF:
    DIST[l]=0

def distance(x):
    if DIST[x]!=-1:
        return DIST[x]
    ANS=0
    for to in EDGELIST[x]:
        if ANS<distance(to)+1:
            ANS=distance(to)+1

    DIST[x]=ANS
    return ANS

for i in range(1,N+1):
    DIST[i]=distance(i)

print(max(DIST))