// The graph is a DAG.  As such, we can do the following:
//
// Label all vertices with value 0.
// While vertices remain:
//      Find a vertex v with no in-edges.
//      For all edges from v to w:
//          Label w with value max(label(v) + 1, label(w)).
//          Remove v.
// Return the maximum label.
//
// If we compute the topological sort of G beforehand, we get
// traversal of vertices in our desired order for free, without
// having to delete vertices or otherwise alter the graph.  The
// algorithm thus becomes O(|V| + |E|).

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

typedef struct node_t
{
	int data;
	struct node_t *next;
} node_t;

node_t *list_add(node_t *head, int data)
{
	node_t *new_node = (node_t *)malloc(sizeof(node_t));
	new_node->data = data;
	
	if (head == NULL)
	{
		return new_node;
	}
	else
	{
		node_t *cur = head;
		while (cur->next != NULL)
		{
			cur = cur->next;
		}
		cur->next = new_node;
		
		return head;
	}
}

int list_find(node_t *head, int data)
{
	node_t *cur = head;
	while (cur != NULL)
	{
		if (cur->data == data)
		{
			return 1;
		}
		cur = cur->next;
	}
	
	return 0;
}

void list_print(node_t *head)
{
	node_t *cur = head;
	printf("[");
	while (cur != NULL)
	{
		printf("%d, ", (cur->data)+1);
		cur = cur->next;
	}
	printf("]\n");
}

void visit(int *t_sort, int *cur, int v, unsigned char *mark_list, node_t **list, int n)
{
    int w;
    
    if (mark_list[v])
    {
        return;
    }
    
    node_t *w_list = list[v];
    while (w_list != NULL)
    {
        int w = w_list->data;
        visit(t_sort, cur, w, mark_list, list, n);
        w_list = w_list->next;
    }
    
    mark_list[v] = 1;
    t_sort[*cur] = v;
    *cur -= 1;
}

int *topological_sort(node_t **list, int n)
{
    unsigned char mark_list[n];
    int *t_sort = (int *)malloc(sizeof(int)*n);
    int v, cur;
    
    for (v=0; v<n; v++)
    {
        mark_list[v] = 0;
    }
    
    cur = n - 1;
    
    for (v=0; v<n; v++)
    {
        if (!mark_list[v])
        {
            visit(t_sort, &cur, v, mark_list, list, n);
        }
    }
    
    return t_sort;
}

int get_longest_path(node_t **list, int n, int *t_sort)
{
    int path_len[n];
    int i;
    
    for (i=0; i<n; i++)
    {
        path_len[i] = 0;
    }
    
    for (i=0; i<n; i++)
    {
        int v = t_sort[i];
        node_t *w_list = list[v];
        while (w_list != NULL)
        {
            int w = w_list->data;
            if (path_len[v] + 1 > path_len[w])
            {
                path_len[w] = path_len[v] + 1;
            }
            w_list = w_list->next;
        }
    }
    
    int max_path_len = -1;
    for (i=0; i<n; i++)
    {
        if (path_len[i] > max_path_len)
        {
            max_path_len = path_len[i];
        }
    }
    
    return max_path_len;
}

int main(int argc, char **argv)
{
    int n, m;
    
    scanf("%d %d", &n, &m);
    
    node_t **list = (node_t **)malloc(sizeof(node_t *)*n);
    int i, j;
    
    for (i=0; i<n; i++)
    {
        list[i] = NULL;
    }
    
    for (i=0; i<m; i++)
    {
        int v, w;
        scanf("%d %d", &v, &w);
        
        list[v-1] = list_add(list[v-1], w-1);
    }
    
    int *t_sort = topological_sort(list, n);
    printf("%d\n", get_longest_path(list, n, t_sort));
    
    return 0;
}

Measured memory_bytes: 7936