#include <iostream>
#include <algorithm> // for sort, mainly
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <array>
#include <string>
#include <cstdio>
#include <iterator>
#include <unordered_set>
#include <cstdint> // for int64_t, int32_t, etc
#include <queue>
#include <stack>
#include <deque>
#include <numeric> // gcd, lcm
#include <fstream>
#include <bitset> // for bitset
#include <iomanip>
#include <cassert> // for set with custom ordering
#include <type_traits> // for set with custom ordering
#include <utility> // for swap, forward, etc
using namespace std;
#pragma GCC optimize("O2")
// #pragma GCC optimize("O1","O2","O3","Ofast","unroll-loops")
// #pragma GCC target("sse","sse2","sse3","sse4.1","sse4.2","avx","avx2","fma")
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) { os << '{'; string sep; for (const T &x : v) os << sep << x, sep = ", "; return os << '}'; }
void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }
#ifdef LOCAL
#define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif
/*
notes:
int64_t
stoi(string s) -> string to int
to_string() -> int (or else) to string
vector declaration:
vector<ll> v(n, 0)
vector<vector<ll>> v(n, vector<ll>(n, 0));
{if statement} ? {truth value} : {false value}
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
std::lcm(ll a, ll b), std::gcd(int a, int b)
cout << fixed << setprecision(n);
set with custom ordering
set<ll, decltype(&cmp)> qu(cmp);
*/
typedef int64_t ll;
vector<vector<ll>> out;
vector<vector<ll>> into;
vector<ll> ord;
vector<ll> comp;
vector<ll> compsize;
void dfs_out(ll curr, vector<bool> &vis) {
for(const auto & o : out[curr]) {
if(vis[o] == false) {
vis[o] = true;
dfs_out(o, vis);
}
}
ord.push_back(curr);
}
void dfs_into(ll curr, vector<bool> &vis, ll currcomp) {
for(const auto & o : into[curr]) {
if(vis[o] == false) {
vis[o] = true;
dfs_into(o, vis, currcomp);
}
}
comp[curr] = currcomp;
compsize[currcomp]++;
}
void solve() {
ll n;
cin >> n;
out.resize(n+1);
into.resize(n+1);
comp.resize(n+1, -1);
for(ll i = 1; i <= n; i++) {
ll where;
cin >> where;
out[i].push_back(where);
into[where].push_back(i);
}
//cerr << "\nread in";
vector<bool> b(n+1, false);
for(ll i = 1; i <= n; i++) {
if(b[i] == false) {
b[i] = true;
dfs_out(i, b);
}
}
reverse(ord.begin(), ord.end());
//cerr << "\ndfs out, ord=" << ord;
b.clear();
b.resize(n+1, false);
ll c = 0;
for(const auto & x : ord) {
if(b[x] == false) {
compsize.push_back(0);
b[x] = true;
dfs_into(x, b, c);
c++;
}
}
//cerr << "\ncomp-ed, comps=" << comp;
//cerr << "\ncompsize=" << compsize;
// basszam meg
// ezt is tulkomplikaltam bazdmeg tudom
// de hulye vagyok es nem jovok ra az egyszeru megoldasra
// szoval nesze, SCC
vector<vector<ll>> int2(c);
vector<ll> oc(c, 0);
for(ll i = 1; i <= n; i++) {
ll from = i;
ll to = out[i][0];
if(comp[to] != comp[from]) {
int2[comp[to]].push_back(comp[from]);
oc[comp[from]]++;
}
}
queue<ll> q;
for(ll i = 0; i < c; i++) {
if(oc[i] == 0) {
q.push(i);
}
}
while(!q.empty()) {
ll curr = q.front();
q.pop();
for(const auto & bck : int2[curr]) {
compsize[bck] += compsize[curr];
q.push(bck);
}
}
ll mx = 0;
ll mcomp = 0;
for(ll i = 0; i < c; i++) {
if(compsize[i] > mx) {
mx = compsize[i];
mcomp = i;
}
}
ll node = 0;
for(ll i = 1; i <= n; i++) {
if(comp[i] == mcomp) {
node = i;
break;
}
}
cout << node << " " << mx;
}
int main()
{
std::ios_base::sync_with_stdio(false);
//cin.tie(nullptr);
//cout.tie(nullptr);
solve();
return 0;
}