/*
TASK:post
LANG:C
*/
#include <stdio.h>

//using namespace std;

//ifstream cin( "post.in" );
//ofstream cout( "post.out" );

int n, m;
struct edge
{ int v, next; } edges[ 65536 ];
int beg[ 2048 ];
int ts[ 2048 ], vis[ 2048 ], d[ 2048 ];
int pred[ 2048 ];
int tc;


void 	init( )
{	int i, u, v;
//	cin >> n >> m;
	scanf( "%d %d", &n, &m );
	for ( i=1; i<=n; i++ ) { beg[ i ] = -1; vis[ i ] = 0; }
	for ( i=1; i<=m; i++ )
   {	//cin >> u >> v;
		scanf( "%d %d", &u, &v );
		edges[ i ].v = v;
		edges[ i ].next = beg[ u ];
		beg[ u ] = i;
   }
	tc = n;
}

void	dfs( int u )
{	int v, i;
	vis[ u ] = 1;
	for ( i=beg[ u ]; i > 0; i = edges[ i ].next )
	{	v = edges[ i ].v;
		if ( !vis[ v ] )  dfs( v );
	}
	ts[ tc-- ] = u;
}


void	solve( )
{	int i, j, u, v, ans=0, ans2=0;
	for ( i = 1; i<=n; i++ ) d[ i ] = 0; d[ 1 ] = 1;
	pred[ 1 ] = -1;
	for ( i=1; i<=n; i++ )
	{	u = ts[ i ];
		for ( j = beg[ u ]; j > 0; j = edges[ j ].next )
      {	v = edges[ j ].v;
			if ( pred[ u ] != v && d[ u ] + 1 >  d[ v ] )
			{ pred[ v ] = u;
			  d[ v ] = d[ u ] + 1;
			}
      }
	}
	for ( i=1; i<=n; i++ )
		if ( d[ i ] > ans ) { ans = d[ i ]; v = i; }
	for ( i = 1; i<=n; i++ ) d[ i ] = -1;
	while ( v > 0 )
   { d[ v ] = 0; v = pred[ v ]; }
	for ( i = 1; i<=n; i++ ) pred[ i ] = -1;

	for ( i=1; i<=n; i++ )
	{	u = ts[ i ];
		for ( j = beg[ u ]; j > 0; j = edges[ j ].next )
      {	v = edges[ j ].v;
			if ( d[ v ] != 0 && pred[ u ] != v && d[ u ] + 1 >  d[ v ] )
			{ pred[ v ] = u;
			  d[ v ] = d[ u ] + 1;
			}
      }
	}
	for ( i=1; i<=n; i++ )
		if ( d[ i ] > ans2 ) ans2 = d[ i ];
//   cout << (ans+ans2) << endl;
	printf( "%d\n", ans+ans2 );
}

int main( )
{	init( );
	dfs( 1 );
	solve( );

	return 0;
}
