Problem:
Score : 100 points

Problem Statement

There is a directed graph G with N vertices and M edges.
The vertices are numbered 1, 2, \ldots, N, and for each i (1 \leq i \leq M), the i-th directed edge goes from Vertex x_i to y_i.
G does not contain directed cycles.

Find the length of the longest directed path in G.
Here, the length of a directed path is the number of edges in it.

Constraints

All values in input are integers.

2 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq x_i, y_i \leq N

All pairs (x_i, y_i) are distinct.

G does not contain directed cycles.

Input

Input is given from Standard Input in the following format:

N M
x_1 y_1
x_2 y_2
:
x_M y_M

Output

Print the length of the longest directed path in G.

Sample Input 1

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

Sample Output 1

3

The red directed path in the following figure is the longest:

Sample Input 2

6 3
2 3
4 5
5 6

Sample Output 2

2

The red directed path in the following figure is the longest:

Sample Input 3

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

Sample Output 3

3

The red directed path in the following figure is one of the longest:

Solution in Rust (1.15.1) (judge verdict: Accepted)

// -----------------------------------------------
// Framework <https://github.com/vain0x/procon>
//
// See the bottom of file for solution.
// -----------------------------------------------

#![allow(unused_imports)]
#![allow(non_snake_case)]

use std::cell::RefCell;
use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::fmt::{Debug, Formatter, Write as FmtWrite};
use std::io::{stderr, stdin, BufRead, Write};
use std::mem::{replace, swap};
use std::ops::*;
use std::rc::Rc;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), stderr());
            writeln!(err, "\x1B[33m{}\x1B[0m = {:?}", e, $e).unwrap()
        })*
    };
}

#[allow(unused_macros)]
macro_rules! read {
    ([$t:ty] ; $n:expr) =>
        ((0..$n).map(|_| read!([$t])).collect::<Vec<_>>());
    ($($t:ty),+ ; $n:expr) =>
        ((0..$n).map(|_| read!($($t),+)).collect::<Vec<_>>());
    ([$t:ty]) =>
        (rl().split_whitespace().map(|w| w.parse().unwrap()).collect::<Vec<$t>>());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

#[allow(dead_code)]
fn rl() -> String {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim_right().to_owned()
}

// -----------------------------------------------
// Solution
// -----------------------------------------------

struct Solver {
    // len[v]: 点 v から出る最長のパスの長さ
    len: Vec<usize>,
    // next[v]: 点 v から出る最長のパスの次の点
    next: Vec<usize>,
    N: usize,
    G: Vec<Vec<usize>>,
}

impl Solver {
    fn dfs(&mut self, u: usize) -> usize {
        let mut max_len = 0;

        if self.len[u] != std::usize::MAX {
            return self.len[u];
        }

        for i in 0..self.G[u].len() {
            let v = self.G[u][i];

            let len = self.dfs(v) + 1;
            if max_len < len {
                max_len = len;
                self.next[u] = v;
            }
        }

        self.len[u] = max_len;
        max_len
    }

    fn run(mut self) {
        for v in 0..self.N {
            self.dfs(v);
        }

        let m = (0..self.N).map(|v| self.len[v]).max().unwrap();
        println!("{}", m);
    }
}

fn main() {
    let (N, M) = read!(usize, usize);
    let E = read![usize, usize; M];

    let mut G = vec![vec![]; N];
    for (u, v) in E {
        G[u - 1].push(v - 1);
    }

    Solver {
        N: N,
        G: G,
        len: vec![std::usize::MAX; N],
        next: vec![0; N],
    }
    .run()
}