{$Q+,R+,I+,O-}

uses SysUtils,Math;


const FileName = 'weakconn';
      Maxn = 1000;

var cc,n:integer;
    gone:array[1..MaxN]of boolean;
    vert:array[1..MaxN] of integer;
    a:array[1..MaxN,1..MaxN] of boolean;

procedure poisk(v:integer);
var i:integer;
begin
  gone[v]:=true;
  for i:=1 to n do 
    if a[v,i] and not gone[i] then
      poisk(i);
  inc(cc);
  vert[cc]:=v;
end;

var col:array[1..MaxN] of integer;

procedure ksiop(v:integer);
var i:integer;
begin
  gone[v]:=true;
  col[v]:=cc;
  for i:=1 to n do
    if a[i,v] and not gone[i] then
      ksiop(i);
end;

var res:array[1..MaxN] of integer;
    b:array[1..MaxN,1..Maxn] of boolean; 

procedure count(m:integer);
var s,i:integer;
begin
  s:=0;
  for i:=m+1 to cc do
    if b[m,i] and (s<res[i]+1) then s:=res[i]+1;
  res[m]:=s;
end;


var i,j,m,x,y:integer;

begin
  reset(input,FileName+'.in');
  rewrite(output,FileName+'.out');
  while not seekeof do begin
    read(n,m);
    fillchar(a,sizeof(a),0);
    for i:=1 to m do begin
      read(x,y);
      a[x,y]:=true;
    end;
    cc:=0;
    for i:=1 to n do
      if not gone[i] then begin
        poisk(i);
      end;
    cc:=0;
    fillchar(gone,sizeof(gone),0);
    for i:=n downto 1 do
      if not gone[vert[i]] then begin
        inc(cc); ksiop(vert[i]);
      end;
    fillchar(b,sizeof(b),0);
    for i:=1 to n do
      for j:=1 to n do
        if a[i,j] then 
          b[col[i],col[j]]:=true;
    for i:=cc downto 1 do
      count(i);
    m:=0;
    for i:=1 to cc do 
      if res[i]>m then m:=res[i];
    writeln(m);
  end;
end.
      
