#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
const int mod = 1000000007;
int a[N], b[N];
int lowbit(int x) {
return x & -x;
}
struct Result {
int max_val, sum;
Result() {
max_val = sum = 0;
}
Result(int a, int b) {
max_val = a;
sum = b;
}
};
Result operator + (const Result & a, const Result & b) {
Result c;
c.max_val = max(a.max_val, b.max_val);
if (c.max_val == a.max_val) {
c.sum += a.sum;
}
if (c.max_val == b.max_val) {
c.sum += b.sum;
}
return c;
}
struct Node {
int l, r;
Result res;
} tf[4 * N], tg[4 * N];
void push_up(Node node[], int p) {
node[p].res = node[2 * p].res + node[2 * p + 1].res;
}
void build(Node node[], int p, int l, int r) {
node[p].l = l;
node[p].r = r;
if (l != r) {
int mid = (l + r) / 2;
build(node, 2 * p, l, mid);
build(node, 2 * p + 1, mid + 1, r);
}
}
void add(Node node[], int p, int pos, Result res) {
if (node[p].l == node[p].r) {
node[p].res = node[p].res + res;
} else {
int mid = (node[p].l + node[p].r) / 2;
if (pos <= mid) {
add(node, 2 * p, pos, res);
} else {
add(node, 2 * p + 1, pos, res);
}
push_up(node, p);
}
}
Result query(Node node[], int p, int l, int r) {
if (l > r) {
return Result();
} else if (l <= node[p].l && node[p].r <= r) {
return node[p].res;
} else {
Result ans;
int mid = (node[p].l + node[p].r) / 2;
if (l <= mid) {
ans = ans + query(node, 2 * p, l, r);
}
if (mid + 1 <= r) {
ans = ans + query(node, 2 * p + 1, l, r);
}
return ans;
}
}
int pow(int a, int b) {
int ans = 1;
while (b != 0) {
if (b % 2 == 1) {
ans = 1ll * ans * a % mod;
}
a = 1ll * a * a % mod;
b = b / 2;
}
return ans;
}
int f[N], g[N], fnum[N], gnum[N];
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b + 1, b + n + 1);
int len = unique(b + 1, b + n + 1) - (b + 1);
for (int i = 1; i <= n; i++) {
a[i] = lower_bound(b + 1, b + len + 1, a[i]) - b;
}
build(tf, 1, 1, len);
build(tg, 1, 1, len);
for (int i = n; i >= 1; i--) {
Result res = query(tf, 1, a[i] + 1, len);
f[i] = res.max_val + 1;
fnum[i] = res.sum;
if (f[i] == 1) {
fnum[i] = (fnum[i] + 1) % mod;
}
res = query(tg, 1, 1, a[i] - 1);
g[i] = res.max_val + 1;
gnum[i] = res.sum;
if (g[i] == 1) {
gnum[i] = (gnum[i] + 1) % mod;
}
add(tf, 1, a[i], Result(f[i], fnum[i]));
add(tg, 1, a[i], Result(g[i], gnum[i]));
}
int res = 0;
for (int i = 1; i <= n; i++) {
res = max(res, f[i] + g[i] - 1) % mod;
}
int ans = 0;
for (int i = 1; i <= n; i++) {
if (f[i] + g[i] - 1 == res) {
ans = (ans + 1ll * fnum[i] * gnum[i] % mod * pow(2, n - res)) % mod;
}
}
printf("%d %d", res, ans);
return 0;
}