#include<iostream>
#include<list>
#include<string>
using namespace std;
class Ball;
typedef list<Ball*> BallList;
class Ball{
private:
BallList NextBall_List;
public:
Ball(){};
BallList * get_NextBall_List(){return &NextBall_List;}
};
int CountMax=0;
void getCountMax(BallList* ballList){
int static Count=0;
for(auto it=ballList->begin();it!=ballList->end();it++){
Count++;
getCountMax((*it)->get_NextBall_List());
}
if(Count>CountMax)CountMax=Count;
Count--;
}
int main(){
int const N_Max=10000+100000;
int hight[N_Max];
int N=0;
string *str=new string;
getline(cin,*str);
while(1)
{
N++;
int index=(int)str->find(" ");
string subStr;
if(index!=(int)string::npos){
subStr=str->substr(0,index);
*str = str->substr(index+1);
hight[N-1]=stoi(subStr);
}else{
subStr=str->substr(0);
hight[N-1]=stoi(subStr);
break;
}
}
Ball ball[N];
for(int i=0;i<N;i++){
for(int j=i+1;j<N;j++){
BallList* myList=ball[i].get_NextBall_List();
if(hight[i]>hight[j]){
myList->push_back(ball+j);
}
}
}
BallList beginBall;
for(int i=0;i<N;i++){
beginBall.push_back(ball+i);
}
getCountMax(&beginBall);
cout<<CountMax<<endl;
list<int> systemList;
systemList.push_back(hight[0]);
list<int> MaxInt;
MaxInt.push_back(INT_MAX);
for(int i=1;i<N;i++){
auto itBegin=systemList.begin();
auto itEnd=systemList.end();
auto greater_Hight_Min=MaxInt.begin();
bool FlagLunch=false;
for(;itBegin!=itEnd;itBegin++)
{
if(hight[i] <= (*itBegin) && (*itBegin) < (*greater_Hight_Min)){
greater_Hight_Min=itBegin;
FlagLunch=true;
}
}
if(FlagLunch){
*greater_Hight_Min = hight[i];
}else
{
systemList.push_back(hight[i]);
}
}
cout<<systemList.size()<<endl;
}