#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[200005],dp_up[200005],dp_down[200005],ans1,ans2;
const int mod=1000000007;
vector<int>numbers;
int find_numbers(int x){
return lower_bound(numbers.begin(),numbers.end(),x)-numbers.begin()+1;
}
struct Segment_tree{
int maximum;
}Tree[1000005];
int ls(int p){return p*2;}
int rs(int p){return p*2+1;}
void pushup(int p){
Tree[p].maximum=max(Tree[ls(p)].maximum,Tree[rs(p)].maximum);
}
void Build_tree(int p,int l,int r){
Tree[p].maximum=0;
if(l==r){
Tree[p].maximum=0;
return;
}
int mid=(l+r)/2;
Build_tree(ls(p),l,mid);
Build_tree(rs(p),mid+1,r);
pushup(p);
}
bool check1(int l1,int r1,int l2,int r2){
if(l1>=l2&&l1<=r2)return true;
if(r1>=l2&&r1<=r2)return true;
if(l2>=l1&&l2<=r1)return true;
if(r2>=l1&&r2<=r1)return true;
return false;
}
void Amend(int p,int l,int r,int ql,int qr,int k){
if(l==r){
Tree[p].maximum=max(Tree[p].maximum,k);
return;
}
int mid=(l+r)/2;
if(check1(l,mid,ql,qr)){
Amend(ls(p),l,mid,ql,qr,k);
}
if(check1(mid+1,r,ql,qr)){
Amend(rs(p),mid+1,r,ql,qr,k);
}
pushup(p);
}
int Query(int p,int l,int r,int ql,int qr){
if(ql>qr)return 0;
if(l>=ql&&r<=qr)return Tree[p].maximum;
int res=0,mid=(l+r)/2;
if(check1(l,mid,ql,qr))res=max(res,Query(ls(p),l,mid,ql,qr));
if(check1(mid+1,r,ql,qr))res=max(res,Query(rs(p),mid+1,r,ql,qr));
return res;
}
long long fastpow(int u,int v){
if(!v)return 1ll;
int temp=fastpow(u,v/2);
temp=(temp*temp)%mod;
if(v&1)temp=(temp*u)%mod;
return temp;
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
numbers.push_back(a[i]);
}
sort(numbers.begin(),numbers.end());
numbers.erase(unique(numbers.begin(),numbers.end()),numbers.end());
for(int i=1;i<=n;i++){
a[i]=find_numbers(a[i]);
}
Build_tree(1,1,numbers.size());
for(int i=n;i>=1;i--){
int res=Query(1,1,numbers.size(),1,a[i]-1)+1;
dp_down[i]=max(1ll,res);
Amend(1,1,numbers.size(),a[i],a[i],dp_down[i]);
}
Build_tree(1,1,numbers.size());
for(int i=n;i>=1;i--){
int res=Query(1,1,numbers.size(),a[i]+1,numbers.size())+1;
dp_up[i]=max(1ll,res);
Amend(1,1,numbers.size(),a[i],a[i],dp_up[i]);
}
for(int i=1;i<=n;i++){
ans1=max(ans1,dp_up[i]+dp_down[i]-1);
}
printf("%lld ",ans1);
for(int i=1;i<=n;i++){
if(dp_up[i]+dp_down[i]-1==ans1){
ans2=(ans2+fastpow(2,n-ans1))%mod;
}
}
printf("%lld",ans2);
}