#ifdef _DEBUG
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <limits>
#include <array>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <numeric>
#include <algorithm>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <bitset>
#include <chrono>
#include <random>
#include <assert.h>

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ui = unsigned int;
using ld = long double;
using pii = pair<int, int>;
using pli = pair<long long, int>;
using pil = pair<int, long long>;
using pll = pair<long long, long long>;
template <typename T>
using uset = unordered_set<T>;
template <typename T1, typename T2>
using umap = unordered_map<T1, T2>;

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

const int mod = 1e9 + 7;

struct mint {
	int val = 0;

	mint(int val = 0) : val(val) {}

	mint operator+=(const mint& other) {
		val += other.val;
		if (val >= mod)
			val -= mod;
		return *this;
	}

	mint operator-=(const mint& other) {
		val -= other.val;
		if (val < 0)
			val += mod;
		return *this;
	}

	mint operator*=(const mint& other) {
		val = (1ll * val * other.val) % mod;
		return *this;
	}

	mint power(ll k) const {
		mint a(*this);
		mint b = 1;
		for (; k; k >>= 1, a *= a)
			if (k & 1)
				b *= a;
		return b;
	}

	mint inv() const {
		return power(mod - 2);
	}

	mint operator/=(const mint& other) {
		val = (1ll * val * other.inv().val) % mod;
		return *this;
	}

	friend mint operator+(const mint& a, const mint& b) {
		return mint(a) += b;
	}

	friend mint operator-(const mint& a, const mint& b) {
		return mint(a) -= b;
	}

	friend mint operator*(const mint& a, const mint& b) {
		return mint(a) *= b;
	}

	friend mint operator/(const mint& a, const mint& b) {
		return mint(a) /= b;
	}

	friend istream& operator>>(istream& in, mint& a) {
		in >> a.val;
		return in;
	}

	friend ostream& operator<<(ostream& out, const mint& a) {
		out << a.val;
		return out;
	}
};

const int N = 2000;
vector<int> g[N], tg[N];
pii edges[N];
int SCC[N];
int used[N];
vector<int> ord;
int n, m;
bool used[N];
int cmp[N];

void dfs(int v) {
	used[v] = 1;
	for (int u : g[v])
		if (!used[u]) {
			cmp[u] = cmp[v];
			dfs(u);
		}
}

inline void solve() {
	int USELESS;
	cin >> n >> m >> USELESS;
	for (int i = 0; i < m; i++) {
		int v, u;
		cin >> v >> u;
		v--;
		u--;
		edges[i] = { v, u };
		g[v].push_back(u);
		g[u].push_back(v);
	}
	int id = 0;
	for (int v = 0; v < n; v++)
		if (!used[v]) {
			cmp[v] = id++;
			dfs(v);
		}
	cout << m - id << ' ' << 1 << '\n';
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
#ifdef _DEBUG
	freopen("01.dat", "r", stdin);
#endif
	int tt = 1;
#ifdef _DEBUG
	cin >> tt;
#endif
	for (int test_id = 1; test_id <= tt; test_id++) {
#ifdef _DEBUG
		cout << "TESTCASE# " << test_id << '\n';
#endif
		solve();
	}
	return 0;
}
