#include <bits/stdc++.h>
using namespace std;


using ll = long long;
const int inf = 1e9 + 10;

const int mod = 1e9 + 7;

int add(int a, int b) {
    return a + b >= mod ? a + b - mod : a + b;
}
int sub(int a, int b) {
    return a >= b ? a - b : a + mod - b;
}
int mul(int a, int b) {
    return 1ll * a * b % mod;
}

int solve(vector<vector<int>> g) {
    int n = g.size();
    vector<vector<int>> in(n);
    for (int i = 0; i < n; ++i) {
        for (auto j : g[i]) in[j].push_back(i);
    }
    vector<bool> used(n);
    vector<vector<bool>> adj(n, vector<bool>(n, false));
    auto dfs = [&](auto dfs, int u) -> void {
        used[u] = true;
        adj[u][u] = true;
        for (auto to : g[u]) {
            if (!used[to]) dfs(dfs, to);
            for (int k = 0; k < n; ++k) {
                if (adj[to][k]) adj[u][k] = true;
            }
        }
    };
    for (int i = 0; i < n; ++i) {
        if (!used[i]) dfs(dfs, i);
    }
    int mn = 0;
    for (int i = 0; i < n; ++i) {
        for (auto j : in[i]) {
            bool ok = true;
            for (auto k : in[i]) {
                if (j == k) continue;
                ok &= !adj[j][k];
            }
            if (ok) {
                mn++;
            }
        }
    }
    return mn;
}

struct DSU {
    vector<int> p;

    DSU() = default;
    DSU(int n) : p(n, 0) {
        iota(p.begin(), p.end(), 0);
    }

    int get(int u) {
        while (u != p[u]) u = p[u] = p[p[u]];
        return u;
    }

    bool unite(int u, int v) {
        u = get(u), v = get(v);
        if (u == v) return false;
        p[v] = u;
        return true;
    }
};

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int n, m, group;
    cin >> n >> m >> group;
    vector<vector<int>> g(n), in(n);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        v--, u--;
        g[u].push_back(v);
        in[v].push_back(u);
    }
    vector<int> topsort;
    vector<bool> used(n);
    auto dfs = [&](auto dfs, int u) -> void {
        used[u] = true;
        for (auto to : g[u]) {
            if (!used[to]) dfs(dfs, to);
        }
        topsort.push_back(u);
    };
    for (int i = 0; i < n; ++i) {
        if (!used[i]) {
            dfs(dfs, i);
        }
    }
    reverse(topsort.begin(), topsort.end());
    vector<int> col(n, -1);
    int c = 0;
    vector<int> vert;
    auto dfs2 = [&](auto dfs2, int u) -> void {
        col[u] = c;
        vert.push_back(u);
        for (auto to : in[u]) {
            if (col[to] == -1) dfs2(dfs2, to);
        }
    };
    int cnt = 1;
    int ret = 0;
    DSU dsu(n);
    for (auto i : topsort) {
        if (col[i] == -1) {
            vert.clear();
            dfs2(dfs2, i);
            for (auto x : vert) {
                for (auto y : g[x]) {
                    if (col[y] != c) continue;
                    int c1 = 0, c2 = 0;
                    auto dfs3 = [&](auto dfs3, int u) -> void {
                        used[u] = true;
                        c1++;
                        for (auto to: g[u]) {
                            if (make_pair(u, to) == make_pair(x, y)) continue;
                            if (col[to] == c && !used[to]) dfs3(dfs3, to);
                        }
                    };
                    fill(used.begin(), used.end(), false);
                    dfs3(dfs3, x);
                    auto dfs4 = [&](auto dfs4, int u) -> void {
                        used[u] = true;
                        c2++;
                        for (auto to: in[u]) {
                            if (make_pair(to, u) == make_pair(x, y)) continue;
                            if (col[to] == c && !used[to]) dfs4(dfs4, to);
                        }
                    };
                    fill(used.begin(), used.end(), false);
                    dfs4(dfs4, x);
                    if (c1 == vert.size() || c2 == vert.size()) {
                        ret += dsu.unite(x, y);
                    }
                }
            }
            c++;
        }
    }
    vector<set<int>> adj(c);
    int ss = 0;
    for (int i = 0; i < n; ++i) {
        for (auto j : g[i]) {
            if (col[i] != col[j]) {
                ss++;
                adj[col[i]].insert(col[j]);
            }
        }
    }
    vector<vector<int>> _adj(c);
    for (int i = 0; i < c; ++i) _adj[i] = vector(adj[i].begin(), adj[i].end());
    cout << ss - solve(_adj) + ret << endl << cnt;
}