#include <iostream>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;
#define int long long
vector<int> order;
vector<bool> used;

void dfs(int v, vector<vector<int>> &g) {
    used[v] = true;
    for (int u: g[v]) {
        if (!used[u]) {
            dfs(u, g);
        }
    }
    order.push_back(v);
}

vector<vector<int>> g, t;

int C = 0;

int ve = 0;
vector<int> clr;

void paint(int v) {
    clr[v] = C;
    ve++;
    for (int u: t[v]) {
        if (!clr[u]) {
            paint(u);
        }
    }
}

signed main() {
    int n, m, q;
    cin >> n >> m >> q;
    g.resize(n);
    t.resize(n);
    for (int i = 0; i < m; ++i) {
        int v, u;
        cin >> v >> u;
        --v;
        --u;
        g[v].push_back(u);
        t[u].push_back(v);
    }
    used.resize(n);
    clr.resize(n);
    for (int i = 0; i < n; ++i) {
        if (!used[i]) dfs(i, g);
    }
    reverse(order.begin(), order.end());
    int ans = 0;
    for (int v: order) {
        if (!clr[v]) {
            ++C;
            ve = 0;
            paint(v);
            if (ve > 1)
            ans += ve - ve / 2;
        }
    }
    vector<vector<int>> ng(C + 1);
    order.clear();
    for (int i = 0; i < n; ++i) {
        for (int u: g[i]) {
            if (clr[i] != clr[u]) {
                ng[clr[i]].push_back(clr[u]);
            }
        }
    }
    used.assign(n, false);
    for (int i = 1; i <= C; ++i) {
        if (!used[i]) {
            dfs(i, ng);
        }
    }
    reverse(order.begin(), order.end());
    used.resize(C + 1, false);
    used.assign(C + 1, false);
    set <int> lol;
    for (int c : order) {
        used[c] = true;
        for (int u: ng[c]) {
            if (used[u]) {
                lol.insert(u);
            }
        }
        for (int u: ng[c]) {
            used[u] = true;
        }
    }
    cout << ans + lol.size() << '\n' << 1;
    return 0;
}
