integer N,M
integer X,Y
integer,allocatable,dimension(:,:)::EDGE
integer,allocatable,dimension(:)::Nindex
integer,allocatable,dimension(:)::DP
integer ans
!読み込み
read*,N,M
allocate(DP(N))
allocate(EDGE(N,M))
allocate(Nindex(N))
EDGE=0
Nindex=0
do i=1,M
  read*,X,Y
  Nindex(X)=Nindex(X)+1
  EDGE(X,Nindex(X))=Y
end do
!読み込み終了

DP = -1
!DP[i]とはノードiからのびる経路のうち最短のもの
!まだ調べていない状態は-1とする
ans = 0
do i=1,N
  if(DP(i)==-1)DP(i)=DFS(i)
  ans=max(ans,DP(i) )
end do

print"(I0)",ans

contains

recursive function DFS(u)result(res)
integer u,res
  if(DP(u) >= 0)then
    res=DP(u)
  else
    DP(u)=0
    do j=1,Nindex(u)
      DP(u)=max(DP(u),DFS(EDGE(u,j))+1)
    end do
  res=DP(u)
  endif
end function DFS
end