#include <cstdio>
#include <cstdlib>
#include <cstring>
//#include <cmath>
#include <algorithm>
//#include <ctime>
using namespace std;
const double inf = 1e15;
int p[5010],f[5010]; //p[i]为值,f[i]为以第i元素为末元素的最长上升子序列长度
int best[5010]; //best[i]表示长度为i的序列的当前最小末元素
int num[5010]; //num[i]表示以第i元素为末元素的最长上升子序列方案数
int find(int l,int r,int key)
{
int mid;
while (1)
{
mid=(l+r)>>1;
if (best[mid]<key && key<=best[mid+1])
return mid+1;
if (best[mid-1]<key && key<=best[mid])
return mid;
if ( key<best[mid] )
r=mid-1;
else l=mid+1;
}
}
int main()
{
//freopen("buylow.in","r",stdin);
//freopen("buylow.out","w",stdout);
int n;
scanf("%d",&n);
for (int i=n;i>=1;i--)
scanf("%d",&p[i]);
memset(best,-1,sizeof(best));
int k;
int ans=1;
best[1]=p[1];f[1]=1;
for (int i=2;i<=n;i++)
{
if (p[i]<=best[1]) k=1; //这里寻k值要很小心,不然容易死循环
else if (p[i]>best[ans]) k=++ans;
else k=find(1,ans,p[i]);
best[k]=p[i];
f[i]=k;
}
printf("%d ",ans);
//如果相同的序列只能算一种方案,那需要判重,最简单的就是用bool数组了,但由于序列的特性,这里只使用now同样可以
for (int i=1;i<=n;i++)
{
if (f[i]==1) { num[i][0]=num[i][1]=1; continue; }
int now=-1;
for (int j=i-1;j>=1;j--)
if (f[j]+1==f[i] && p[j]<p[i] && now!=p[j])
{
num[i]+=num[j];
now=p[j]; //这里值得思考一下,很简单,对于符合条件的
} //重复的两个数(假设为p[i1]=p[i2])肯定是连续枚举的,因为如果中
} //还枚举了其他数(假设有p[j])那会矛盾。
//若p[j]>p[i1],就有f[j]至少为f[i1]+1,不符合枚举条件;
//若p[j]<p[i1],就有f[i2]至少为f[j]+1,这样p[i2]不会枚举到,矛盾。
int now=-1;
int sum=0;
for (int i=1;i<=n;i++)
if (f[i]==ans && now!=p[i])
{
sum+=num[i];
now=p[i];
}
printf("%d/n",sum);
return 0;
}