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

using namespace std;
using namespace __gnu_pbds;
//-------------------------------------------//
#define int long long
//-------------------------------------------//
#pragma GCC optimize("O3")
//-------------------------------------------//
#define pii pair<int, int>
#define ft first
#define sd second
#define fast                      \
    ios_base::sync_with_stdio(0); \
    cin.tie(0)
#define cout_float cout.setf(ios::fixed); cout.precision(20)
//-------------------------------------------//
typedef long long ll;
typedef long double ld;
typedef tree<int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update> ordered_set;
//---------------------------------------------------------------------------------------//

struct Node {
    int value;
    int size;

    Node* left = nullptr;
    Node* right = nullptr;

    Node(int x): value(x), size(1) {}
};

int size(Node* N) {
    if (!N) return 0;
    return N->size;
}

void upd(Node* N) {
    N->size = size(N->left) + size(N->right);
}

Node* merge(Node* L, Node* R) {
    if (!L) return R;
    if (!R) return L;
    if (rand() % (L->size + R->size) < L->size) {
        L->right = merge(L->right, R);
        upd(L);
        return L;
    } else {
        R->left = merge(L, R->left);
        upd(R);
        return R;
    }
}

pair<Node*, Node*> splitV(Node* rt, int x) { //left - strictly less than x
    if (!rt) return {nullptr, nullptr};
    if (rt->value >= x) {
        pair<Node*, Node*> p = splitV(rt->left, x);
        rt->left = p.second;
        upd(rt);
        return {p.first, rt};
    } else {
        pair<Node*, Node*> p = splitV(rt->right, x);
        rt->right = p.first;
        upd(rt);
        return {rt, p.second};
    }
}

pair<Node*, Node*> splitI(Node* rt, int k) { //exactly k nodes in the left part
    if (!rt) return {nullptr, nullptr};
    if (size(rt->left) >= k) {
        pair<Node*, Node*> p = splitI(rt->left, k);
        rt->left = p.second;
        upd(rt);
        return {p.first, rt};
    } else {
        pair<Node*, Node*> p = splitI(rt->right, k - size(rt->left) - 1);
        rt->right = p.first;
        upd(rt);
        return {rt, p.second};
    }
}

//Node* root = nullptr;

//-----------------------------------------------------------------------------------------//

struct segtree {
    int size = 1;
    vector<int> tree;

    void init(int n) {
        while (size < n) size *= 2;
        tree.assign(2 * size - 1, 0);
    }

    void upd(int x, int lx, int rx) {
        if (rx - lx == 1) return;
        tree[x] = tree[2 * x + 1] + tree[2 * x + 2];
    }

    void build(vector<int> &a, int x, int lx, int rx) {
        if (rx - lx == 1) {
            if (lx < (int)a.size()) {
                tree[x] = a[lx];
            }
            return;
        }
        int mx = (lx + rx) / 2;
        build(a, 2 * x + 1, lx, mx);
        build(a, 2 * x + 2, mx, rx);
        upd(x, lx, rx);
    }

    void build(vector<int> &a) {
        init((int)a.size());
        build(a, 0, 0, size);
    }

    void set(int i, int v, int x, int lx, int rx) {
        if (rx - lx == 1) {
            tree[x] = v;
            return;
        }
        int mx = (lx + rx) / 2;
        if (i < mx) {
            set(i, v, 2 * x + 1, lx, mx);
        } else {
            set(i, v, 2 * x + 2, mx, rx);
        }
        upd(x, lx, rx);
    }

    void set(int i, int v) {
        set(i, v, 0, 0, size);
    }

    int get_sum(int l, int r, int x, int lx, int rx) {
        if (r <= lx || rx <= l) {
            return 0;
        }
        if (l <= lx && rx <= r) {
            return tree[x];
        }
        int mx = (lx + rx) / 2;
        int s1 = get_sum(l, r, 2 * x + 1, lx, mx);
        int s2 = get_sum(l, r, 2 * x + 2, mx, rx);
        return s1 + s2;
    }

    int get_sum(int l, int r) {
        return get_sum(l, r, 0, 0, size);
    }
};

//------------------------------------------------------------------//

struct node {
    int sum;

    node* left = nullptr;
    node* right = nullptr;

    node(int x): sum(x) {}
    node(): sum(0) {}
    node(node* L, node* R): sum(L->sum + R->sum), left(L), right(R) {}
};

int sz = 1;

void init(int n) {
    while (sz < n) sz *= 2;
}

node* build(vector<int> &a, int lx, int rx) {
    if (rx - lx == 1) {
        if (lx < (int)a.size()) {
            return new node(a[lx]);
        } else {
            return new node();
        }
    }
    int mx = (lx + rx) / 2;
    return new node(build(a, lx, mx), build(a, mx, rx));
}

node* build(vector<int> &a) {
    init((int)a.size());
    return build(a, 0, sz);
}

node* setT(int i, int v, int lx, int rx, node* cur) {
    if (rx - lx == 1) {
        return new node(v);
    }
    int mx = (lx + rx) / 2;
    if (i < mx) {
        return new node(setT(i, v, lx, mx, cur->left), cur->right);
    } else {
        return new node(cur->left, setT(i, v, mx, rx, cur->right));
    }
}

int get_sum(int l, int r, int lx, int rx, node* cur) {
    if (r <= lx || rx <= l) {
        return 0;
    }
    if (l <= lx && rx <= r) {
        return cur->sum;
    }
    int mx = (lx + rx) / 2;
    int s1 = get_sum(l, r, lx, mx, cur->left);
    int s2 = get_sum(l, r, mx, rx, cur->right);
    return s1 + s2;
}

//node* versions[q + 1];
//versions[0] = build(a);
//versions[i + 1] = setT(j, val, 0, sz, versions[i]);
//to get sum -> get_sum(l, r, 0, sz, versions[query]);

//-----------------------------------------------------------------------//

const int N = 2025;
vector<int> G[N];
vector<int> GP[N];
bool used[N];

void dfs(int v) {
    if (used[v]) return;
    used[v] = true;
    for (auto u : G[v]) {
        dfs(u);
    }
    for (auto u : GP[v]) {
        dfs(u);
    }
}

signed main() {
    fast;
    int n, m, g;
    cin >> n >> m >> g;
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        G[u].push_back(v);
        GP[v].push_back(u);
    }
    int curCmp = 0;
    for (int v = 1; v <= n; ++v) {
        if (!used[v]) {
            ++curCmp;
            dfs(v);
        }
    }
    cout << m - n + curCmp << "\n" << -1;
    return 0;
}
