#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1000000007;
#define sz(x) (ll)(x).size()
#define rd ({ll x; cin >> x; x; })
#define dbg(x) cerr << "[" #x "] " << (x) << "\n\n"
// #define errv(x) {cerr << "["#x"] ["; for (const auto& ___ : (x)) cerr << ___ << ", "; cerr << "]\n";}
// #define errvn(x, n) {cerr << "["#x"] ["; for (auto ___ = 0; ___ < (n); ++___) cerr << (x)[___] << ", "; cerr << "]\n";}
#define cerr if(0)cerr
#define xx first
#define yy second
mt19937 rnd(std::chrono::high_resolution_clock::now().time_since_epoch().count());
/*_________________________________________________________________________________________________________________________*/
vector<ll> out;
struct cNode {
ll u, len;
};
ll dfs(vector<cNode> adj[], ll node, ll par)
{
cerr << node << "<---" << par << "\n";
// cerr << node << endl;
if (out[node] != -1)
return out[node];
ll newLen = 0;
for (cNode& it : adj[node]) {
if (it.u == par)
continue;
if (it.len == -1)
it.len = dfs(adj, it.u, node);
newLen = max(newLen, it.len + 1);
}
return out[node] = newLen;
}
void Solve()
{
ll n;
cin >> n;
out = vector<ll>(n + 1, -1);
vector<cNode> adj[n + 1];
for (int i = 0; i < n - 1; i++) {
ll u, v;
cin >> u >> v;
adj[u].push_back({ v, -1 });
adj[v].push_back({ u, -1 });
}
set<pair<ll, ll>> st;
for (int i = 1; i <= n; i++) {
st.insert({ dfs(adj, i, 0), i });
}
cout << st.rbegin()->first << " " << st.rbegin()->second << "\n";
}
int32_t main()
{
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
for (int i = 1; i <= t; i++) {
// cout << "Case #" << i << ": "; // cout << "Case " << i << ": ";
Solve();
}
return 0;
}
// Coded by Tahsin Arafat (@TahsinArafat)