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 C (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


#define MAX(a,b) (((a)>(b))?(a):(b))

typedef struct s_path
{
	int start;
	int end;
	int len;
} t_path;

typedef struct s_vert
{
	int name;
	int *list;
	int num;
} t_vert;

int len_of_vert(int i, t_vert *vs, int *flag, int *dp)
{
	if (vs[i].num == 0)
		return (0);
	if(flag[i] != 0)
	{
		return (dp[i]);
	}
	flag[i] = 1;
	int max = 0;
	int tmp = 0;
	int index = 0;
	while (index < vs[i].num)
	{
		tmp = len_of_vert(vs[i].list[index], vs, flag, dp);
		if (max < tmp)
			max = tmp;
		index++;
	}
	dp[i] = max + 1;
	return (max + 1);
}

int main(void)
{
	int n, m;

	scanf ("%d %d",&n, &m);
	t_vert vs[n+1];
	int x[m],y[m];
	int index = 0;
	int flag[n+1];
	int dp[n+1];
	while (index < n + 1)
	{
		vs[index].num = 0;
		flag[index] = 0;
		dp[index] = 0;
		index++;
	}
	index = 0;
	while (index < m)
	{
		scanf("%d %d",&(x[index]),&(y[index]));
		vs[x[index]].num = vs[x[index]].num + 1;
		index++;
	}
	index = 0;
	while (index < n+1)
	{
		vs[index].list = (int *)malloc(sizeof(int)*(vs[index].num));
		index++;
	}
	int i = 0;
	int j = 0;
	int k[n+1];
	while (j < n+1)
	{
		k[j] = 0;
		j++;
	}
	//printf("AAA\n");
	i = 0;
	while (i < m)
	{
		//printf("i:%d\n",i);
		//printf("x[i];%d\n",x[i]);
		//printf("k[x[i]];%d\n",k[x[i]]);
		//printf("vs[x[i]].num;%d\n",vs[x[i]].num);
		if (vs[x[i]].num > k[x[i]])
		{
			vs[x[i]].list[k[x[i]]] = y[i];
			k[x[i]] = k[x[i]] + 1;
		}
		i++;
	}
	//printf("BBB\n");
	i = 1;
	j = 0;
	int max = 0;
	int p_len = 0;
	i = 0;
	while (i < n+1)
	{
		p_len = len_of_vert(i, vs, flag, dp);
		max = MAX(p_len,max);
		//printf("i;%d\n",i);
		i++;
	}
	printf("%d\n",max);
	return (0);
}