#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using ld = long double;
using o_set = tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>;

//find_by_order()
//order_of_key()

constexpr ll mod = 1e9 + 7;

int cur = 0, max1 = 0;

struct T {
    int v, u;
};

vector<set<int>> g, g1;
vector<bool> used;
vector<int> color, color_check, pr;
vector<ll> cnt_cycle;

void dfs(int v) {
    used[v] = true;
    for (auto to : g[v]) {
        if (!used[to]) {
            dfs(to);
        }
    }
    pr.push_back(v);
}

void dfs1(int v, int cnt = 0) {
    color[v] = cur;
    for (auto to : g1[v]) {
        if (color[to] == -1) {
            dfs1(to, cnt + 1);
        } else if (color[to] == color[v]) {
            max1 = max(max1, cnt);
        }
    }
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m, gr;
    cin >> n >> m >> gr;
    g.resize(n);
    g1.resize(n);
    used.resize(n, false);
    color.resize(n, -1);
    cnt_cycle.resize(n + 1, 0);
    vector<ll> cnt_all(n + 1, 0);
    vector<T> e(m);
    ll cnt_comp = 0;
    for (int i = 0; i < m; i++) {
        cin >> e[i].v >> e[i].u;
        e[i].v--;
        e[i].u--;
        g[e[i].v].insert(e[i].u);
        g1[e[i].u].insert(e[i].v);
    }
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs(i);
        }
    }
    ll ans = 0;
    for (int i = 0; i < int(pr.size()); i++) {
        if (color[pr[int(pr.size()) - i - 1]] == -1) {
            max1 = 0;
            dfs1(pr[int(pr.size()) - i - 1]);
            ans += max1 - 1;
            cur++;
        }
    }
    cout << max1;
    return 0;
}
