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


struct UnionFind{
    vector<int> dat;

    UnionFind(int sz){
        dat.assign(sz, -1);
    }

    bool unite(int x, int y){
        x = root(x), y = root(y);
        if(x == y) return false;
        if(dat[x] > dat[y]) swap(x, y);
        dat[x] += dat[y];
        dat[y] = x;
        return true;
    }
    int root(int k){
        if(dat[k] < 0) return k;
        return dat[k] = root(dat[k]);
    }

    int size(int k){
        return -dat[root(k)];
    }
};

struct BipartiteMatching{
    using Graph = vector<vector<int>>;
    Graph G;
    vector<int> match, alive, used;
    int ts;

    BipartiteMatching(int n) : G(n), alive(n, 1),
                               used(n, 0), match(n, -1), ts(0) {}

    void add_edge(int u, int v){
        G[u].push_back(v);
        G[v].push_back(u);
    }

    int dfs(int idx){
        used[idx] = ts;
        for(auto &&to: G[idx]){
            int w = match[to];
            if(alive[to] == 0) continue;
            if(w < 0 || (used[w] != ts && dfs(w))){
                match[idx] = to;
                match[to] = idx;
                return 1;
            }
        }
        return 0;
    }

    int bimatch(){
        int res = 0;
        for(int i=0; i<G.size(); i++){
            if(alive[i] == 0) continue;
            if(match[i] == -1){
                ++ts;
                res += dfs(i);
            }
        }
        return res;
    }
};


int main(){
    int n, m;
    cin >> n >> m;
    vector<int> x(m), y(m);
    BipartiteMatching BM(2*n);
    for(int i=0; i<m; i++){
         cin >> x[i] >> y[i];
         x[i]--; y[i]--;
         BM.add_edge(x[i], y[i]+n);
     }
         

    UnionFind UF(m);
    for(int i=0; i<m; i++){
        for(int j=0; j<m; j++){
            if(x[i] == x[j] || y[i] == y[j]){
                UF.unite(i, j);
            }
        }
    }
    int ansmx = 0;
    for(int i=0; i<m; i++){
        if(UF.root(i) == i) ansmx += UF.size(i) - 1;
    }

    int ansmn = BM.bimatch();
    cout << m-ansmn << " " << ansmx << endl;

}

