#include <bits/stdc++.h>
using namespace std;
#define int long long
constexpr int mod = 1e9 + 7;
struct node { int mx, cnt; };
node merge(node left, node right) {
if (left.mx > right.mx) return left;
if (right.mx > left.mx) return right;
return {left.mx, (left.cnt + right.cnt) % mod};
}
struct segment_tree {
int n;
vector<node> t;
segment_tree(int n) : n(n), t(n << 2, {1, 1}) {}
void update(int i, int dp, int cn, int v = 1, int l = 0, int r = -1) {
if (r < 0) r += n;
if (l == r) t[v] = merge(t[v], {dp, cn});
else {
int m = (l + r) >> 1;
if (i <= m) update(i, dp, cn, v << 1, l, m);
else update(i, dp, cn, v << 1 | 1, m + 1, r);
t[v] = merge(t[v << 1], t[v << 1 | 1]);
}
}
node get(int L, int R, int v = 1, int l = 0, int r = -1) {
if (L > R) return {1, 1};
if (r < 0) r += n;
if (L <= l && r <= R) return t[v];
int m = (l + r) >> 1;
if (R <= m) return get(L, R, v << 1, l, m);
if (L > m) return get(L, R, v << 1 | 1, m + 1, r);
return merge(get(L, R, v << 1, l, m), get(L, R, v << 1 | 1, m + 1, r));
}
};
int binpow(int x, int y) {
if (!y) return 1;
int z = binpow(x, y >> 1);
z = z * z % mod;
if (y & 1) z = z * x % mod;
return z;
}
int32_t main() {
#ifdef JahonaliX
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, m;
cin >> n;
node ans{0, 0};
vector<int> a(n), u, pw(n * 2, 1);
for (int i = 1; i < n * 2; ++i) pw[i] = pw[i - 1] * 2 % mod;
for (int &i : a) cin >> i, u.emplace_back(i);
sort(u.begin(), u.end()), u.erase(unique(u.begin(), u.end()), u.end()), m = u.size();
segment_tree lis(m), lds(m);
for (int &i : a) i = lower_bound(u.begin(), u.end(), i) - u.begin();
reverse(a.begin(), a.end());
for (int i : a) {
node is = lis.get(0, i - 1), ds = lds.get(i + 1, m - 1), cr = {is.mx + ds.mx - 1, is.cnt * ds.cnt % mod};
cr.cnt = cr.cnt * pw[n - cr.mx] % mod;
ans = merge(ans, cr);
lis.update(i, is.mx + 1, is.cnt), lds.update(i, ds.mx + 1, ds.cnt);
}
cout << ans.mx << ' ' << ans.cnt;
return 0;
}