function dfs(root, list, memo) {
  if (memo[root.toString()]) {
    return memo[root.toString()]
  }
  if (!list[root].length) {
    return 0
  }
  let max = 0
  for (let r of list[root]) {
    max = Math.max(max, 1 + dfs(r, list, memo))
  }
  memo[root.toString()] = max
  return max
}

function adjList(N, edges) {
  let res = new Array(N+1).fill(0).map(e => [])
  let incoming = new Array(N+1).fill(0)
  for (let e of edges) {
    res[e[0]].push(e[1])
    incoming[e[1]]++
  }
  return {
    list: res,
    incoming: incoming
  }
}

function solve(N, edges) {
  let adjListRes = adjList(N, edges)
  let list = adjListRes.list
  let incoming = adjListRes.incoming
  let max = 0
  for (let i = 1; i <= incoming.length; i++) {
    if (incoming[i] === 0) {
      let memo = {}
      max = Math.max(max, dfs(i, list, memo))
    }
  }
  return max
}

function main(input) {
  const lines = input.split("\n")
  const NM = lines[0].split(' ').map(i => parseInt(i))
  const N = NM[0]
  const edges = lines.slice(1).map(l => l.split(' ').map(e => parseInt(e)))
  const ans = solve(N, edges)
  return ans
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));