| 
 
 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <cmath>
 #include <set>
 #include <vector>
 #include <map>
 #include <queue>
 #include <set>
 #include <algorithm>
 #include <limits.h>
 using namespace std;
 typedef long long LL;
 const int MAXN=1e+4;
 const int MAXM=1e+5;
 const int INF = INT_MAX;
 struct Edge
 {
 int from,to,ci,next;
 Edge(){}
 Edge(int _from,int _to,int _ci,int _next):from(_from),to(_to),ci(_ci),next(_next){}
 }e[MAXM];
 int head[MAXN],tot;
 int dis[MAXN];
 int top,sta[MAXN],cur[MAXN];
 inline void init(){
 memset(head,-1,sizeof(head));
 tot=0;
 }
 inline void AddEdge(int u,int v,int ci0,int ci1=0){
 e[tot]=Edge(u,v,ci0,head[u]);
 head[u]=tot++;
 e[tot]=Edge(v,u,ci1,head[v]);
 head[v]=tot++;
 }
 inline bool bfs(int st,int et){
 memset(dis,0,sizeof(dis));
 dis[st]=1;
 queue <int> q;
 q.push(st);
 while(!q.empty()){
 int now=q.front();
 q.pop();
 for(int i=head[now];i!=-1;i=e[i].next){
 int next=e[i].to;
 if(e[i].ci&&!dis[next]){
 dis[next]=dis[now]+1;
 if(next==et)return true;
 q.push(next);
 }
 }
 }
 return false;
 }
 LL Dinic(int st,int et){
 LL ans=0;
 while(bfs(st,et)){
 
 top=0;
 memcpy(cur,head,sizeof(head));
 int u=st,i;
 while(1){
 if(u==et){
 int pos,minn=INF;
 
 for(i=0;i<top;i++)
 {
 if(minn>e[sta[i]].ci){
 minn=e[sta[i]].ci;
 pos=i;
 }
 
 }
 for(i=0;i<top;i++){
 e[sta[i]].ci-=minn;
 e[sta[i]^1].ci+=minn;
 }
 top=pos;
 u=e[sta[top]].from;
 ans+=minn;
 
 }
 for(i=cur[u];i!=-1;cur[u]=i=e[i].next)
 if(e[i].ci&&dis[u]+1==dis[e[i].to])break;
 if(cur[u]!=-1){
 sta[top++]=cur[u];
 u=e[cur[u]].to;
 }
 else {
 if(top==0)break;
 dis[u]=0;
 u=e[sta[--top]].from;
 }
 }
 }
 return ans;
 }
 int a[MAXN],cs[MAXN],dp[MAXN];
 int main()
 {
 int n;
 while(~scanf("%d",&n)){
 for(int i=1;i<=n;i++)
 scanf("%d",&a[i]);
 dp[1]=a[1];
 cs[1]=1;
 int len=1;
 for(int i=2,j;i<=n;i++){
 if(dp[len]<a[i])j=++len;
 else j=lower_bound(dp+1,dp+1+len,a[i])-dp;
 dp[j]=a[i];
 cs[i]=j;
 }
 
 init();
 for(int i=1;i<=n;i++){
 if(cs[i]==1){
 AddEdge(0,i,1);
 }
 if(cs[i]==len)AddEdge(i,n+1,1);
 for(int j=i+1;j<=n;j++)
 if(a[i]<a[j]&&cs[i]+1==cs[j])
 AddEdge(i,j,1);
 }
 LL ans=Dinic(0,n+1);
 printf("%d\n",len);
 printf("%I64d\n",ans);
 }
 return 0;
 }
 
 |