import std.stdio, std.algorithm, std.conv, std.array, std.string, std.math, std.typecons, std.numeric;

int[][10^^5] PS;
int[10^^5] MEMO;

void main()
{
    auto nm = readln.split.to!(int[]);
    auto N = nm[0];
    auto M = nm[1];
    foreach (_; 0..M) {
        auto xy = readln.split.to!(int[]);
        PS[xy[0]-1] ~= xy[1]-1;
    }

    MEMO[0..N] = -1;

    foreach (i; 0..N) {
        auto stk = [i];
        while (!stk.empty) {
            auto from = stk[0];
            stk = stk[1..$];
            if (MEMO[from] != -1) continue;
            int max_p, to_;
            foreach (to; PS[from]) {
                if (MEMO[to] == -1) {
                    to_ = to;
                    max_p = -1;
                    break;
                } else {
                    max_p = max(max_p, MEMO[to]);
                }
            }
            if (max_p == -1) {
                stk = [to_] ~ stk ~ [from];
            } else {
                MEMO[from] = max_p + 1;
            }
        }
    }

    int ret;
    foreach (mp; MEMO[0..N]) ret = max(ret, mp);
    writeln(ret);
}