#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,a,c1=0,c2=0,sum=0,b;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a;
		if(a==1)c1++;
		else c2++;
		sum+=a;
	}
	b=sum-min(c1,c2)*3;
	cout<<(min(c1,c2)+b/3);
}


#include<bits/stdc++.h>
using namespace std;

int () {
    int n;
    int a=0, b=0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (x == 1) a++;
        else b++;
        cout << min(a, b) + max(a-b, 0) / 3 << endl;
    }
}


#include<bits/stdc++.h>
using namespace std;

int main() {
    int n;
    int a=0, b=0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (x == 1) a++;
        else b++;
        cout << min(a, b) + max(a-b, 0) / 3 << endl;
    }
}


#include<bits/stdc++.h>
using namespace std;

int main() {
    int n;
    int a=0, b=0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (x == 1) a++;
        else b++;
    }
    cout << min(a, b) + max(a-b, 0) / 3 << endl;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a[200005],i,n,j,n1=0,n2=0,ans=0;
	cin>>n;
	for (i=1;i<=n;i++)
		cin>>a[i];
	for (i=n;i>=1;i--)
		for (j=1;j<=i-1;j++)
			if (a[i]>a[j]) swap(a[i],a[j]);
	i=1;
	while (a[i]==2)
	{
		n2++;
		i++;
	}
	n1=n-n2;
	ans+=min(n1,n2);
	if (n1-n2<0)
	{
		cout<<ans<<endl;
		return 0;
	}
	else
	{
		n1-=n2;
		ans+=n1/3;
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a[200005],i,n,j,n1=0,n2=0,ans=0;
	cin>>n;
	for (i=1;i<=n;i++)
		cin>>a[i];
	sort(a+1,a+n+1);
	i=1;
	while (a[i]==1)
	{
		n1++;
		i++;
	}
	n2=n-n1;
	ans+=min(n1,n2);
	if (n1-n2<0)
	{
		cout<<ans<<endl;
		return 0;
	}
	else
	{
		n1-=n2;
		ans+=n1/3;
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main()
{
    long n,a[1000],i,c=0,d=0,p;
    cin>>n;
    for(i=1; i<=n; i++)
    {
        cin>>a[i];
        if(a[i]==1)
            c++;
        else
            d++;
    }
    if(c==d || d>c)
        cout<<c;
    if(c>d)
    {
        p=c-d;
        cout<<d+p/3;
    }
}


#include<bits/stdc++.h>
using namespace std;

int main()
{
    long long n,a[10000],i,c=0,d=0,p;
    cin>>n;
    for(i=1; i<=n; i++)
    {
        cin>>a[i];
        if(a[i]==1)
            c++;
        else
            d++;
    }
    if(c==d || d>c)
        cout<<c;
    if(c>d)
    {
        p=c-d;
        cout<<d+p/3;
    }
}


#include<bits/stdc++.h>
using namespace std;

int main()
{
    long n,a[100000],i,c=0,d=0,p;
    cin>>n;
    for(i=1; i<=n; i++)
    {
        cin>>a[i];
        if(a[i]==1)
            c++;
        else
            d++;
    }
    if(c==d || d>c)
        cout<<c;
    if(c>d)
    {
        p=c-d;
        cout<<d+p/3;
    }
}


#include<bits/stdc++.h>
using namespace std;

int main()
{
    long long n,a,i,c=0,d=0,p;
    cin>>n;
    for(i=1; i<=n; i++)
    {
        cin>>a;
        if(a==1)
            c++;
        else
            d++;
    }
    if(c==d || d>c)
        cout<<c;
    if(c>d)
    {
        p=c-d;
        cout<<d+p/3;
    }
}


#include<iostream>
int main()
{
    using namespace std;
    long n,count=0;
    cin>>n;
    long a[n];
    for(long i=0;i<n;i++)
    {
        cin>>a[i];
    }
    long f1=0,f2=0;
    for(long i=0;i<n;i++)
    {
        if(a[i]==1)
            f1++;
    }
    f2=n-f1;
    if(f2<f1)
    {
        count=f2;
    }
    else if(f1>=f2)
    {
        count=f1;
        count+=(f1-f2)/3;
    }
    count+=(f1-f2)/3;
    cout<<count<<endl;
}


#include<iostream>
int main()
{
    using namespace std;
    long n,count=0;
    cin>>n;
    long a[n];
    for(long i=0;i<n;i++)
    {
        cin>>a[i];
    }
    long f1=0,f2=0;
    for(long i=0;i<n;i++)
    {
        if(a[i]==1)
            f1++;
    }
    f2=n-f1;
    if(f2<f1)
    {
        count=f2;
    }
    else if(f2>=f1)
    {
        count=f1;
    }
    count+=(f1-f2)/3;
    cout<<count<<endl;
}


#include<iostream>
int main()
{
    using namespace std;
    long long int n,count=0;
    cin>>n;
    long long int a[n];
    for(long long int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    long f1=0,f2=0;
    for(long long int i=0;i<n;i++)
    {
        if(a[i]==1)
            f1++;
    }
    f2=n-f1;
    if(f2<f1)
    {
        count=f2;
        count+=(f1-f2)/3;
    }
    else if(f2>=f1)
    {
        count=f1;
    }
    cout<<count<<endl;
}


#include<iostream>
int main()
{
    using namespace std;
    long n,count=0;
    cin>>n;
    long a[n];
    for(long i=0;i<n;i++)
    {
        cin>>a[i];
    }
    long f1=0,f2=0;
    for(long i=0;i<n;i++)
    {
        if(a[i]==1)
            f1++;
    }
    f2=n-f1;
    if(f2<f1)
    {
        count=f2;
    }
    else if(f1>f2)
    {
        count=f1;
        count+=(f1-f2)/3;
    }
    count+=(f1-f2)/3;
    cout<<count<<endl;
}


#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
int main(){
	int n,i,a[10000],s2=0,s1=0,t;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);
	for(i=0;i<n;i++)
	{
		if(a[i]==1)
		s1++;
		}
		s2=n-s1;
	if(s1==0)
	printf("%d",s1);
	else
	{
	if(s2<=s1)
		printf("%d",(s1-s2)/3+s2);
		else
		printf("%d",s2);
	}
}


#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
	int n,i,a[100],s2=0,s1=0,t;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	for(i=0;i<n;i++)
	sort(a,a+n);
	for(i=0;i<n;i++)
//	cout<<" "<<a[i];
		t=a[0];
	for(i=0;i<n;i++)
	{
		if(1==a[i])
		s1++;
		}
		s2=n-s1;
	//	cout<<"s1="<<s1;
	//	cout<<"s2="<<s2;
	if(s1==0)
	cout<<s1;
	else
	{
	if(s2<=s1)
		cout<<(s1-s2)/3+s2;
		else
		cout<<s2;
	}
}


#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
	int n,i,a[100],s2=0,s1=1,t;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	for(i=0;i<n;i++)
	sort(a,a+n);
	for(i=0;i<n;i++)
//	cout<<" "<<a[i];
		t=a[0];
	for(i=1;i<n;i++)
	{
		if(t==a[i])
		s1++;
		}
		s2=n-s1;
	//	cout<<"s1="<<s1;
	//	cout<<"s2="<<s2;
	if(s2<=s1)
		cout<<(s1-s2)/3+s2;
		else
		cout<<s2;
}


#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
	long n,i,a[200000],s2=0,s1=0,t;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	for(i=0;i<n;i++)
	{
		if(1==a[i])
		s1++;
		}
		s2=n-s1;
	//	cout<<"s1="<<s1;
	//	cout<<"s2="<<s2;
	if(s1==0)
	cout<<s1;
	else
	{
	if(s2<=s1)
		cout<<(s1-s2)/3+s2;
		else
		cout<<s1;
	}
}


#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
	int n,i,a[100],s2=0,s1=0,t;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	for(i=0;i<n;i++)
	{
		if(1==a[i])
		s1++;
		}
		s2=n-s1;
	//	cout<<"s1="<<s1;
	//	cout<<"s2="<<s2;
	if(s1==0)
	cout<<s1;
	else
	{
	if(s2<=s1)
		cout<<(s1-s2)/3+s2;
		else
		cout<<s2;
	}
}


#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
	long n,i,a[200000],s2=0,s1=0,t;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	for(i=0;i<n;i++)
	{
		if(1==a[i])
		s1++;
		}
		s2=n-s1;
	//	cout<<"s1="<<s1;
	//	cout<<"s2="<<s2;
	if(s1==0)
	cout<<s1;
	else
	{
	if(s2<=s1)
		cout<<(s1-s2)/3+s2;
		else
		cout<<s2;
	}
}


#include<stdio.h>

int a[10000];
int main(){
    int n,sum = 0,sum1 = 0,sum2 = 0;
    scanf("%d",&n);
    for(int i = 0;i < n;i++){
        scanf("%d",&a[i]);
        if(a[i] == 1)
            sum1++;
        if(a[i] == 2)
            sum2++;
    }
    if(sum2 >= sum1)
        printf("%d\n",sum1);
    if(sum1 > sum2){
        sum = sum2 + (sum1 - sum2) / 3;
        printf("%d\n",sum);
    }
    return 0;
}


#include<stdio.h>

int main(){
    int n,a[100000],sum = 0,sum1 = 0,sum2 = 0;
    scanf("%d",&n);
    for(int i = 0;i < n;i++){
        scanf("%d",&a[i]);
        if(a[i] == 1)
            sum1++;
        if(a[i] == 2)
            sum2++;
    }
    if(sum2 >= sum1)
        printf("%d\n",sum1);
    if(sum1 > sum2){
        sum = sum2 + (sum1 - sum2) / 3;
        printf("%d\n",sum);
    }
    return 0;
}


#include<stdio.h>

int a[300000];
int main(){
    int n,sum = 0,sum1 = 0,sum2 = 0;
    scanf("%d",&n);
    for(int i = 0;i < n;i++){
        scanf("%d",&a[i]);
        if(a[i] == 1)
            sum1++;
        if(a[i] == 2)
            sum2++;
    }
    if(sum2 >= sum1)
        printf("%d\n",sum1);
    if(sum1 > sum2){
        sum = sum2 + (sum1 - sum2) / 3;
        printf("%d\n",sum);
    }
    return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<string.h>
#include<cmath>
#include<stack>
#include<queue>
#include<list>
#include<set>
#include<map>
using namespace std;
#define MOD 1000000009
#define N 200005
typedef long long LL;
int a[N];
int main()
{
	int n;
	int one,two;
	int cnt;
	while(~scanf("%d",&n)){
		memset(a,0,sizeof(a));
		one=0;
		two=0;
		for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		if(a[i]==1) one++;
		if(a[i]==2) two++;
	}
	cnt=0;
	if(two!=0){
		while(two){
		if(one>0){
			cnt++;
			two--;
			one--;
		}
		else break;
	}
	}
	if(one!=0){
		cnt=cnt+one/3;
	}
	printf("%d\n",cnt);
}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<string.h>
#include<cmath>
#include<stack>
#include<queue>
#include<list>
#include<set>
#include<map>
using namespace std;
#define MOD 1000000009
#define N 200005
typedef long long LL;
int a[N];
int main()
{
	int n;
	int one,two;
	int cnt;
	while(~scanf("%d",&n)){
		memset(a,0,sizeof(a));
		one=0;
		two=0;
		for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		if(a[i]==1) one++;
		if(a[i]==2) two++;
	}
	cnt=0;
	if(two!=0){
		while(two){
		if(one>0){
			cnt++;
			two--;
			one--;
		}
		else break;
	}
	}
	else if(one!=0){
		cnt=cnt+one/3;
	}
	printf("%d\n",cnt);
}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main () {
	int n,m=0,g=0;
	cin>>n;
	int a[n+1];
	for (int k=1;k<=n;k++){

	cin>>a[k];

}
for (int k=1;k<=n;k++){
	if (a[k]==2)

	m++;
	if (a[k]==1)
	g++;
}

if (g==0){
	cout<<0;
	return  0;
}
if (g>m){

	cout<<m+(g-m)/3;

}
else
cout<<1;

	return 0;

}


#include <bits/stdc++.h>
using namespace std;
int main () {
	int n,m=0,g=0;
	cin>>n;
	int a[n+1];
	for (int k=1;k<=n;k++){

	cin>>a[k];

}
for (int k=1;k<=n;k++){
	if (a[k]==2)

	m++;
	if (a[k]==1)
	g++;
}

if (g==0){
	cout<<0;
	return  0;
}
if (g>m){

	cout<<m+(g-m)/3;

}
else
cout<<g;

	return 0;

}


#include <bits/stdc++.h>
using namespace std;
int main () {
	int n,m=0;
	cin>>n;
	int a[n+1];
	for (int k=1;k<=n;k++){

	cin>>a[k];

m+=a[k];
}

cout<<m/3;

	return 0;

}


#include <bits/stdc++.h>
using namespace std;
int main () {
	int n,m=0,g=0;
	cin>>n;
	int a[n+1];
	for (int k=1;k<=n;k++){

	cin>>a[k];

}
for (int k=1;k<=n;k++){
	if (a[k]==2)

	m++;
	if (a[k]==1)
	g++;
}

if (g==0){
	cout<<0;
	return  0;
}
if (g>m){

	cout<<m+(g-m)/3;

}
else
cout<<m/3;

	return 0;

}


#include <bits/stdc++.h>
using namespace std;
int main () {
	int n,m=0;
	cin>>n;
	int a[n+1];
	for (int k=1;k<=n;k++){

	cin>>a[k];

m+=a[k];
}

if (n==2 && a[1]==2 && a[2]==2){
	cout<<0;
	return  0;
}
cout<<m/3;

	return 0;

}


#include<bits/stdc++.h>
#define MAXN 200000 + 10

using namespace std;
int N , a[MAXN];
int q1 , q2;
int main(){
	cin >> N;
	for(int i = 1;i <= N;i++){
		cin >> a[i];
		if(a[i] == 1) q1++;
		else q2++;
	}
	//cout << q1 << " " << q2 << endl;
	cout << max(q1 / 3 , min(q1 , q2) + (q1 - q2) / 3);
	return 0;
}


#include<bits/stdc++.h>
#define MAXN 200000 + 10

using namespace std;
int N , a[MAXN];
int q1 , q2;
int main(){
	cin >> N;
	for(int i = 1;i <= N;i++){
		cin >> a[i];
		if(a[i] == 1) q1++;
		else q2++;
	}
	//cout << q1 << " " << q2 << endl;
	if(q1 > q2)cout << q2 + (q1 - q2) / 3;
	else cout << q1;
	return 0;
}


#include<bits/stdc++.h>
#define MAXN 200000 + 10

using namespace std;
int N , a[MAXN];
int q1 , q2;
int main(){
	cin >> N;
	for(int i = 1;i <= N;i++){
		cin >> a[i];
		if(a[i] == 1) q1++;
		else q2++;
	}
	//cout << q1 << " " << q2 << endl;
	cout << max(q1 / 3 , min(q1 , q2));
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int arr[n+3];
    int one=0;
    int second=0;
    for(int i=0;i<n;i++){
    cin>>arr[i];
    if(arr[i]==1)
    one++;
    else
    second++;
    }
    int x=min(one,second);
    cout<<x<<endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int arr[n+3];
    int one=0;
    int second=0;
    for(int i=0;i<n;i++){
    cin>>arr[i];
    if(arr[i]==1)
    one++;
    else
    second++;
    }
    int ans;
    if(second==0)
    ans=one/3;
    else
     ans=min(one,second);

     cout<<ans<<endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int arr[n+3];
    int one=0;
    int second=0;
    for(int i=0;i<n;i++){
    cin>>arr[i];
    if(arr[i]==1)
    one++;
    else
    second++;
    }
    int x;
    if(second==0){
    x=one/3;
    cout<<x<<endl;
    }
    else{
    x=min(one,second);
     one-=x;
     second-=x;
     int p=one/3;
     int r=second/3;
     int ans=x+p+r;
     cout<<ans<<endl;
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int arr[n+3];
    int one=0;
    int second=0;
    for(int i=0;i<n;i++){
    cin>>arr[i];
    if(arr[i]==1)
    one++;
    else
    second++;
    }
    int ans;
    int x=0;
    if(second==0)
    ans=one/3;
    else{
     ans=min(one,second);
      x=(one-min(one,second))/3;
    }
     cout<<ans+x<<endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,result;
    int a;
    cin>>n;

    int count1=0,count2=0;

    for(int i=1;i<=n;i++)
    {
        cin>>a;
        if(a==1) count1++;
        else if(a==2) count2++;
    }

    if(count1==0) result=0;

    if(count1>count2) { result=count2 + (count1-count2)/3 ; }

    else if(count2>count1 && count1!=0) { result=count1 + (count2-count1)/3; }

    else if(count1==count2) result=count1;

    cout<<result<<endl;

    return 0;

}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,result;
    int a;
    cin>>n;

    int Count1=0,Count2=0;

    for(int i=1;i<=n;i++)
    {
        cin>>a;
        if(a==1) Count1++;
        else if(a==2) Count2++;
    }

    result=min(Count1,Count2);

    Count1-=result;
    result+=(Count1/3);

    cout<<result<<endl;

    return 0;

}


#include<bits/stdc++.h>
typedef long long LL;
#define MAXN 200005
using namespace std;
int main()
{
 int n,x,s1=0,s2=0,s=0;
 cin>>n;
 for(int i=1;i<=n;i++)
 {
  cin>>x;
  if(x==1) s1++;
  else s2++;
 }
 while(s2&&s1) s++,s2--,s1--;
 s=s+s1/3;
 cout<<s;
 return 0;
}
//08:07 BeiJing


#include<bits/stdc++.h>
typedef long long LL;
#define MAXN 200005
using namespace std;
int main()
{
 int n,x,s1=0,s2=0,s=0;
 cin>>n;
 for(int i=1;i<=n;i++)
 {
  cin>>x;
  if(x==1) s1++;
  else s2++;
 }
 while(s2&&s1) s++,s2--,s1--;
 s=s+s1/3;
 cout<<s;
 return 0;
}


#include<bits/stdc++.h>
typedef long long LL;
//test
#define MAXN 200005
using namespace std;
int main()
{
 int n,x,s1=0,s2=0,s=0;
 cin>>n;
 for(int i=1;i<=n;i++)
 {
  cin>>x;
  if(x==1) s1++;
  else s2++;
 }
 while(s2&&s1) s++,s2--,s1--;
 s=s+s1/3;
 cout<<s;
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){
    long long sum,a,b[2000000],x,y;
    cin>>a;
    for(int i=1;i<=a;i++){
        cin>>b[i];
    }
    for(int i=0;i<=a;i++){
        if(b[i]==1) x++;
        else if(b[i]==2) y++;
    }
     if(x>y) cout<<y+(x-y)/3;
     else cout<<x;
}


#include<bits/stdc++.h>
using namespace std;
int n;
int g[3];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int k;
		cin>>k;
		g[k]++;
	}
	cout<<min(g[1],g[2]);
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,a=0,b=0,x,ans=0;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>x;
		if(x==1)a++;
		else b++;
	}
	for(int i=0;i<n;i++)
		if(b<a)
		{
			ans=b;
			x=a-b;
			x=x/3;
			ans=ans+x;
		}
		else ans=a;
	cout<<ans;
return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int N=1e6+5;

int n,a[N],b[N],pos[N],t[N],ans;

int get(int pos){
    int cur=0;
    for(;pos>=0;pos&=pos+1,pos--){
        cur=max(cur,t[pos]);
    }
    return cur;
}

void update(int pos,int val){
    for(;pos<=n;pos|=pos+1){
        t[pos]=max(t[pos],val);
    }
}

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=n;i++){
        cin>>b[i];
        pos[b[i]]=i;
    }
    for(int i=1;i<=n;i++){
        b[i]=pos[a[i]];
    }
    for(int i=n;i>=1;i--){
        ///cout<<b[i]<<" ";
        int cur=get(b[i]-1)+1;
        ans=max(ans,cur);
        update(b[i],cur);
    }
    cout<<ans;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman001 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
ll seg[6000005],n,x[1000005],y[1000005],arr[1000005];
void update(ll node,ll s,ll e,ll ind,ll val)
{
    if(s == e)
    {
        seg[node] = val;
        return;
    }
    ll mid = s + (e-s)/2;
    if(mid >= ind)
        update(node*2,s,mid,ind,val);
    else
        update(node*2+1,mid+1,e,ind,val);
    seg[node] = max(seg[node*2],seg[node*2+1]);
}
ll query(ll node,ll s,ll e,ll l,ll r)
{
    if(r < s || l > e)
        return 0;
    if(s>=l && e<=r)
        return seg[node];
    ll mid = s + (e-s)/2;
    return max(query(node*2,s,mid,l,r),query(node*2+1,mid+1,e,l,r));
}
int main()
{
    abdelrahman001
    cin >> n;
    for(int i = 0;i<n;i++)
        cin >> x[i];
    for(int i=0,x;i<n;i++)
        cin >> x,y[x] = i;
    for(int i = 0;i<n;i++)
        arr[i] = y[x[i]];
    for(int i = 0;i<n;i++)
        update(1,0,n-1,arr[i],query(1,0,n-1,arr[i],n-1)+1);
    cout << seg[1];
    return 0;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e6 + 5;
int n , x[N] , y[N] , seg[4 * N];
void update(int node , int s , int e , int i , int val) {
    if(s == e) {
        seg[node] = val;
        return;
    }
    int mid = s + e >> 1;
    if(i <= mid)
        update(node << 1 , s , mid , i , val);
    else
        update(node << 1 | 1 , mid + 1 , e , i , val);
    seg[node] = max(seg[node << 1] , seg[node << 1 | 1]);
}
int query(int node , int s , int e , int l , int r) {
    if(l > e || s > r)
        return 0;
    if(l <= s && r >= e)
        return seg[node];
    int mid = s + e >> 1;
    return max(query(node << 1 , s , mid , l , r) , query(node << 1 | 1 , mid + 1 , e , l , r));
}
int main() {
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n;
    for(int i = 1;i <= n;i++)
        cin >> x[i];
    for(int i = 1;i <= n;i++) {
        int r;
        cin >> r;
        y[r] = i;
    }
    for(int i = 1;i <= n;i++) {
        int mx = query(1 , 1 , n , y[x[i]] , n);
        update(1 , 1 , n , y[x[i]] , mx + 1);
    }
    cout << seg[1];
    return 0;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman001 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
ll seg[6000005],n,x[1000005],y[1000005],arr[1000005];
void update(ll node,ll s,ll e,ll ind,ll val)
{
    if(s == e)
    {
        seg[node] = val;
        return;
    }
    ll mid = s + (e-s)/2;
    if(mid <= ind)
        update(node*2,s,mid,ind,val);
    else
        update(node*2+1,mid+1,e,ind,val);
    seg[node] = max(seg[node*2],seg[node*2+1]);
}
ll query(ll node,ll s,ll e,ll l,ll r)
{
    if(r < s || l > e)
        return 0;
    if(s>=l && e<=r)
        return seg[node];
    ll mid = s + (e-s)/2;
    return max(query(node*2,s,mid,l,r),query(node*2+1,mid+1,e,l,r));
}
int main()
{
    abdelrahman001
    cin >> n;
    for(int i = 0;i<n;i++)
        cin >> x[i];
    for(int i=0,x;i<n;i++)
        cin >> x,y[x] = i;
    for(int i = 0;i<n;i++)
        arr[i] = y[x[i]];
    for(int i = 0;i<n;i++)
        update(1,0,n-1,arr[i],query(1,0,n-1,arr[i],n-1)+1);
    cout << seg[1];
    return 0;
}


// Example program
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e6 + 1;

pair <int, int> a[MAXN];
int last[MAXN];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        a[x].first = i;
    }
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        a[x].second = i;
    }
    sort(a + 1, a + n + 1);
    //for (int i = 1; i <= n; i++)
      //  cout << a[i].first << " " << a[i].second << "\n";
    reverse(a + 1, a + n + 1);
    last[0] = 0;
    for (int i = 1; i < MAXN; i++)
        last[i] = MAXN;
    int best = 0;
    for (int i = 1; i <= n; i++)
    {
        int x = lower_bound(last + 1, last + 1 + n, a[i].second) - last;
        best = max(best, x);
        last[x] = min(last[x], a[i].second);
    }
    cout << best;
}


#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#include<unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define mod 1000000007
#define mod1 mod
#define mod2 100000009
#define li long long int
#define ll li
// #define INT_MAX 5000000
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s", x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define si short int
#define INTMAX 1000000000
#define MAXN 1000000000000000000
#define MINN -1000000000000000000
// #define INTMAX 1000001000
#define pii pair<ll,ll>
#define pdd pair<double,double>
#define pic pair<int,char>
#define N 1000005
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20

// #define INTMAX 200000000
// using namespace boost;
// #define si short int

using namespace std;
using namespace __gnu_pbds;
typedef priority_queue<pii , vector<pii > > max_pq;
// typedef priority_queue<pii, vector<pii> , greater<pii >  > min_pq;
ll toint(const string &s) {stringstream ss; ss << s; ll x; ss >> x; return x;}
string tostring ( ll number ){stringstream ss; ss<< number; return ss.str();}

// using namespace __gnu_pbds;
// typedef priority_queue<pair<ll,char> , vector<pair<ll , char> > > max_pq;
// typedef priority_queue<pii , vector<pii > ,greater<pii > > min_pq;
typedef tree<ll , null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> OST;
// typedef priority_queue<pair < ll , pair < pii , ll > >  , vector<pair < ll , pair < pii , ll > >  > ,greater<pair < ll , pair < pii , ll > >  > > min_pq;
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cout << name << " : " << arg1 << std::endl;
        //use cerr if u want to display at the bottom
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif
ll seg[ N << 2 ];
ll n;
ll ar[ N ];
ll br[ N ];
void update ( ll low, ll high, ll pos, ll q , ll val )
{
    if ( low == high and low == q )
        seg[pos] = val;
    else if ( high < q or low > q )
        return;
    else
    {
        ll mid = (low+high)/2;
        update(low,mid,2*pos+1,q,val);
        update(mid+1,high,2*pos+2,q,val);
        seg[pos] = max(seg[2*pos+1],seg[2*pos+2]);
    }
}
ll query( ll qlow, ll qhigh, ll low, ll high , ll pos )
{
    if ( qlow <= low and qhigh >= high )
        return seg[pos];
    else if ( qlow > high or qhigh < low )
        return 0;
    else
    {
        ll mid = (low+high)/2;
        return max(query(qlow,qhigh,low,mid,2*pos+1),query(qlow,qhigh,mid+1,high,2*pos+2));
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output6.txt","w",stdout);
    #endif
    cin >> n;
    for ( ll i = 1; i <= n; i ++)
    {
        ll p;
        cin >> p;
        ar[p] = i;
    }
    for ( ll i = 1; i <= n; i ++)
    {
        ll p;
        cin >> p;
        br[i] = ar[p];
    }
    ll ans = 1;
    for ( ll i = n; i >= 1; i-- )
    {
        ll val;
        if ( br[i]== 1 )
            val = 1;
        else
            val = query(1,br[i]-1,1,n,0) + 1 ;
        // trace(val);
        update(1,n,0,br[i],val);
        ans = max(ans,val);
    }
    cout << ans;

}


#include <stdio.h>
const int N=1000050;
int a[N],b[N],id[N],m,sol[N];
int main()
{
	int n,i;
	scanf("%i",&n);
	for(i=1;i<=n;i++) scanf("%i",&a[i]);
	for(i=1;i<=n;i++) scanf("%i",&b[i]),id[b[i]]=i;
	for(i=1;i<=n;i++)
	{
		int top=m,bot=1,mid,ans=m+1;
		while(top>=bot)
		{
			mid=top+bot>>1;
			if(id[a[sol[mid]]]>id[a[i]]) ans=mid,bot=mid+1;
			else top=mid-1;
		}
		if(ans==m+1) m++;
		sol[ans]=i;
	}
	printf("%i\n",m);
	return 0;
}


#include <stdio.h>
const int N=1000050;
int a[N],b[N],id[N],m,sol[N];
int main()
{
	int n,i;
	scanf("%i",&n);
	for(i=1;i<=n;i++) scanf("%i",&a[i]);
	for(i=1;i<=n;i++) scanf("%i",&b[i]),id[b[i]]=i;
	for(i=1;i<=n;i++)
	{
		int top=m,bot=1,mid,ans=m+1;
		while(top>=bot)
		{
			mid=top+bot>>1;
			if(id[a[sol[mid]]]<id[a[i]]) ans=mid,top=mid-1;
			else bot=mid+1;
		}
		if(ans==m+1) m++;
		sol[ans]=i;
	}
	printf("%i\n",m);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1 << 20;

int n, a[N], b[N], c[N], d[N];
int top, s[N];

int bs(int l, int r, int v) {
	while (r - l > 1) {
		int m = (l + r) / 2;
		if (s[m] < v) r = m;
		else l = m;
	}
	return s[l] < v ? l : r;
}

int main() {

	scanf("%d", &n);
	for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
	for (int i = 0; i < n; ++i) { scanf("%d", &b[i]); c[b[i]] = i; }
	for (int i = 0; i < n; ++i) d[i] = c[a[i]];

	top = 0;
	for (int i = 0; i < n; ++i) {
		if (top == 0 || s[top - 1] > d[i]) s[top++] = d[i];
		else s[bs(0, top - 1, d[i])] = d[i];
	}
	printf("%d\n", top);

	return 0;
}


#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

#ifdef WIN32
#define INT64 "%I64d"
#else
#define INT64 "%lld"
#endif

typedef long long int64;
typedef double real;

const int MaxN = 1000006, MaxC = 0x3F3F3F3F, NA = -1;

int p [MaxN], q [MaxN], r [MaxN], s [MaxN], t [MaxN];
int k, n;

int main (void)
{
 int i, lo, me, hi;
 while (scanf (" %d", &n) != EOF)
 {
  for (i = 1; i <= n; i++)
   scanf (" %d", &p[i]);
  for (i = 1; i <= n; i++)
   scanf (" %d", &q[i]);
  for (i = 1; i <= n; i++)
   t[p[i]] = i;
  for (i = 1; i <= n; i++)
   r[i] = t[q[i]];
  for (i = 1; i <= n; i++)
   s[i] = 0;
  k = 0;
  for (i = 1; i <= n; i++)
  {
   lo = 1;
   hi = n;
   while (lo < hi)
   {
    me = (lo + hi) >> 1;
    if (s[me] > r[i])
     lo = me + 1;
    else
     hi = me;
   }
   s[lo] = r[i];
   if (k < lo)
    k++;
  }
  printf ("%d\n", k);
 }
 return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int N,S[1000005],P[1000005],B[1000005],ans,X[1000005],L,t;

int main(){
	scanf("%d",&N);
	for(int i=1;i<=N;++i){
		scanf("%d",&S[i]);
		P[S[i]] = i;
	}
	for(int i=1;i<=N;++i){
		scanf("%d",&B[i]);
		B[i] = P[B[i]];
	}
	reverse(B+1,B+N+1);
	for(int i=1;i<=N;++i){
		t = lower_bound(X,X+L,B[i])-X;
		X[t] = B[i];
		L = max(L,t+1);
	}
	printf("%d\n",L);
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
ll inf = 1LL<<60;
ll mod = 1000000007;

using namespace std;

int a[1000010], b[1000010], t[1000010], s[1000010];

int main(void){
  //freopen("in.in","r",stdin);
  int n;
  scanf("%i", &n);
  for(int i=0 ; i<n ; i++){
    scanf("%i", a+i);
    t[a[i]] = i;
  }
  for(int i=0 ; i<n ; i++){
    scanf("%i", b+i);
  }
  reverse(b, b+n);
  for(int i=0 ; i<n ; i++){
    int idx = t[b[i]];
    s[i] = idx;
  }
  set<int> ds;
  set<int>:: iterator it;
  for(int i=0 ; i<n ; i++){
    ds.insert(s[i]);
    it = ds.find(s[i]);
    it++;
    if(it!=ds.end()) ds.erase(it);
  }
  printf("%i", ds.size());
  return 0;
}


/*
          * AUTHOR : Divyanshu *
*/

#include<bits/stdc++.h>
//      #include <ext/pb_ds/assoc_container.hpp>
//      #include <ext/pb_ds/tree_policy.hpp>

//      using namespace __gnu_pbds;
using namespace std;

#define ll long long
#define ull unsigned long long
#define f(a,b) for(ll i=a; i<b; i++)
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pl pair<ll,ll>
#define vll vector<ll>
#define pll vector<pair<ll,ll>>
#define ld long double
#define fr(a,b) for(ll j=a; j>=b; j--)
#define fi(a,b) for(ll j=a; j<b; j++)
#define fii(a,b) for(ll k=a; k<b; k++)
//      typedef tree<ll ,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

int main()
{
    #ifndef ONLINE_JUDGE
	   freopen("input.txt", "rt", stdin);
 //    freopen("output.txt", "wt", stdout); *Nope*
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n, x;
    cin>>n;
    pair<ll, ll> p[n+1];
    ll m[n+1], m1[n+1];
    f(0, n)     cin>>x,     m[x] = i+1;
    f(0, n)     cin>>x,     m1[x] = i+1;
    f(1, n+1) p[i].first = m[i],  p[i].second = m1[i];
    sort(p+1, p+n+1);
    ll ans = 0;
    vll v(n+5);
    f(0, n+5)     v[i] = 1e18;
    fr(n, 1)
    {
        ll k = p[j].second;
      //  cout<<p[j].first<<" "<<p[j].second<<"\n";
        *lower_bound(v.begin(), v.end(), k) = k;
    }
    f(0, n+3)
    {
        if(v[i] == 1e18)
        {   cout<<i;    return 0;   }
    }

    #ifndef ONLINE_JUDGE
    	cout<<"\nTime Elapsed : " << 1.0*clock() / CLOCKS_PER_SEC << " s\n";
    #endif
    return 0;
}


/*
          * AUTHOR : Divyanshu *
*/

#include<bits/stdc++.h>
//      #include <ext/pb_ds/assoc_container.hpp>
//      #include <ext/pb_ds/tree_policy.hpp>

//      using namespace __gnu_pbds;
using namespace std;

#define ll long long
#define ull unsigned long long
#define f(a,b) for(ll i=a; i<b; i++)
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pl pair<ll,ll>
#define vll vector<ll>
#define pll vector<pair<ll,ll>>
#define ld long double
#define fr(a,b) for(ll j=a; j>=b; j--)
#define fi(a,b) for(ll j=a; j<b; j++)
#define fii(a,b) for(ll k=a; k<b; k++)
//      typedef tree<ll ,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

int main()
{
    #ifndef ONLINE_JUDGE
	   freopen("input.txt", "rt", stdin);
 //    freopen("output.txt", "wt", stdout); *Nope*
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n, x;
    cin>>n;
    pair<ll, ll> p[n+1];
    map<ll, ll> m, m1;
    f(0, n)     cin>>x,     m[x] = i+1;
    f(0, n)     cin>>x,     m1[x] = i+1;
    f(1, n+1) p[i].first = m[i],  p[i].second = m1[i];
    sort(p+1, p+n+1);
    ll ans = 0;
    vll v(n+5);
    f(0, n+5)     v[i] = 1e18;
    fr(n, 1)
    {
        ll k = p[j].second;
      //  cout<<p[j].first<<" "<<p[j].second<<"\n";
        *lower_bound(v.begin(), v.end(), k) = k;
    }
    f(0, n+3)
    {
        if(v[i] == 1e18)
        {   cout<<i;    return 0;   }
    }

    #ifndef ONLINE_JUDGE
    	cout<<"\nTime Elapsed : " << 1.0*clock() / CLOCKS_PER_SEC << " s\n";
    #endif
    return 0;
}


/*
          * AUTHOR : Divyanshu *
*/

#include<bits/stdc++.h>
//      #include <ext/pb_ds/assoc_container.hpp>
//      #include <ext/pb_ds/tree_policy.hpp>

//      using namespace __gnu_pbds;
using namespace std;

#define ll long long
#define ull unsigned long long
#define f(a,b) for(ll i=a; i<b; i++)
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pl pair<ll,ll>
#define vll vector<ll>
#define pll vector<pair<ll,ll>>
#define ld long double
#define fr(a,b) for(ll j=a; j>=b; j--)
#define fi(a,b) for(ll j=a; j<b; j++)
#define fii(a,b) for(ll k=a; k<b; k++)
//      typedef tree<ll ,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

int main()
{
    #ifndef ONLINE_JUDGE
	   freopen("input.txt", "rt", stdin);
 //    freopen("output.txt", "wt", stdout); *Nope*
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n, x;
    cin>>n;
    pair<ll, ll> p[n+1];
    map<ll, ll> m, m1;
    f(0, n)     cin>>x,     m[x] = i+1;
    f(0, n)     cin>>x,     m1[x] = i+1;
    f(1, n+1) p[i].first = m[i],  p[i].second = m1[i];
    sort(p, p+n);
    ll ans = 0;
    vll v(n+5);
    f(0, n+5)     v[i] = 1e18;
    fr(n, 1)
    {
        ll k = p[j].second;
      //  cout<<p[j].first<<" "<<p[j].second<<"\n";
        *lower_bound(v.begin(), v.end(), k) = k;
    }
    f(0, n+3)
    {
        if(v[i] == 1e18)
        {   cout<<i;    return 0;   }
    }

    #ifndef ONLINE_JUDGE
    	cout<<"\nTime Elapsed : " << 1.0*clock() / CLOCKS_PER_SEC << " s\n";
    #endif
    return 0;
}


/*
          * AUTHOR : Divyanshu *
*/

#include<bits/stdc++.h>
//      #include <ext/pb_ds/assoc_container.hpp>
//      #include <ext/pb_ds/tree_policy.hpp>

//      using namespace __gnu_pbds;
using namespace std;

#define ll long long
#define ull unsigned long long
#define f(a,b) for(ll i=a; i<b; i++)
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pl pair<ll,ll>
#define vll vector<ll>
#define pll vector<pair<ll,ll>>
#define ld long double
#define fr(a,b) for(ll j=a; j>=b; j--)
#define fi(a,b) for(ll j=a; j<b; j++)
#define fii(a,b) for(ll k=a; k<b; k++)
//      typedef tree<ll ,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

int main()
{
    #ifndef ONLINE_JUDGE
	   freopen("input.txt", "rt", stdin);
 //    freopen("output.txt", "wt", stdout); *Nope*
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll n;
    cin>>n;
    pair<ll, ll> p[n];
    f(0, n)     cin>>p[i].first;
    f(0, n)     cin>>p[i].second;
    sort(p, p+n);
    ll ans = 0;
    vll v(n+1);
    f(0, n)     v[i] = 1e18;
    fr(n-1, 0)
    {
        ll k = p[j].second;
        *lower_bound(v.begin(), v.end(), k) = k;
    }
    f(0, n+1)
    {
        if(v[i] == 1e18)
        {   cout<<i;    return 0;   }
    }

    #ifndef ONLINE_JUDGE
    	cout<<"\nTime Elapsed : " << 1.0*clock() / CLOCKS_PER_SEC << " s\n";
    #endif
    return 0;
}


#pragma GCC optimize("O3")

#include <bits/stdc++.h>

using namespace std;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

#define n_l '\n'
#define dbg(...) cout << "[" << #__VA_ARGS__ << "]: "; cout << to_string(__VA_ARGS__) << endl
template <typename T, size_t N> int SIZE(const T (&t)[N]){ return N; } template<typename T> int SIZE(const T &t){ return t.size(); } string to_string(const string s, int x1=0, int x2=1e9){ return '"' + ((x1 < s.size()) ? s.substr(x1, x2-x1+1) : "") + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(const bool b) { return (b ? "true" : "false"); } string to_string(const char c){ return string({c}); } template<size_t N> string to_string(const bitset<N> &b, int x1=0, int x2=1e9){ string t = ""; for(int __iii__ = min(x1,SIZE(b)),  __jjj__ = min(x2, SIZE(b)-1); __iii__ <= __jjj__; ++__iii__){ t += b[__iii__] + '0'; } return '"' + t + '"'; } template <typename A, typename... C> string to_string(const A (&v), int x1=0, int x2=1e9, C... coords); int l_v_l_v_l = 0, t_a_b_s = 0; template <typename A, typename B> string to_string(const pair<A, B> &p) { l_v_l_v_l++; string res = "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; l_v_l_v_l--; return res; } template <typename A, typename... C> string to_string(const A (&v), int x1, int x2, C... coords) { int rnk = rank<A>::value; string tab(t_a_b_s, ' '); string res = ""; bool first = true; if(l_v_l_v_l == 0) res += n_l; res += tab + "["; x1 = min(x1, SIZE(v)), x2 = min(x2, SIZE(v)); auto l = begin(v); advance(l, x1); auto r = l; advance(r, (x2-x1) + (x2 < SIZE(v))); for (auto e = l; e != r; e = next(e)) { if (!first) { res += ", "; } first = false; l_v_l_v_l++; if(e != l){ if(rnk > 1) { res += n_l; t_a_b_s = l_v_l_v_l; }; } else{ t_a_b_s = 0; } res += to_string(*e, coords...); l_v_l_v_l--; } res += "]"; if(l_v_l_v_l == 0) res += n_l; return res; } void dbgm(){;} template<typename Heads, typename... Tails> void dbgm(Heads H, Tails... T){ cout << to_string(H) << " | "; dbgm(T...); }
#define dbgm(...) cout << "[" << #__VA_ARGS__ << "]: "; dbgm(__VA_ARGS__); cout << endl

#define REP(i,b) for(int i=0;i<(b);i++)
#define REPP(i,b) for(int i=1;i<=(b);i++)
#define PER(i,a,b) for(int i=(a);i>(b);i++)
#define SZ(a) int((a).size())
#define ALL(a) (a).begin(), (a).end()
#define MS(s) memset(s, 0, sizeof(s))
#define PB push_back
#define MP make_pair

typedef vector<pair<int, int>> VPII;
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = (int) 1e9 + 7;
string ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
string ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

struct hashLL { /* mp.rehash(n << 2); */
    size_t operator()(ll x) const {
        x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
        x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
        x = x ^ (x >> 31);
        return x;
    }
};

long long inv(long long a, long long b) {
    return 1 < a ? b - inv(b % a, a) * b / a : 1;
}

const ll INF = 1e6;

// unordered_map<int, int, custom_hash> mp;
// unordered_map<int, unordered_map<int, int, custom_hash>, custom_hash> g;

ll gcd(ll a, ll b, ll &x, ll &y) {
    if (a == 0) {
        x = 0;
        y = 1;
        return b;
    }
    ll x1, y1;
    ll d = gcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return d;
}

ll distsq(ll x1, ll y1, ll x2, ll y2) {
    return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
}

ll n, m;
const int N = 1000006;
int fenw[N];
void upd(int p, int v) {
    while (p <= n) {
        fenw[p] = max(fenw[p], v);
        p = p | (p + 1);
    }
}
int get(int p) {
    int ans = 0;
    while (p >= 0) {
        ans = max(ans, fenw[p]);
        p = (p & (p+1)) - 1;
    }
    return ans;
}
int a[N];
int b[N];
int main() {
    // freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    ll u;
    REPP(i, n) { cin >> u; a[u] = i + 1; }
    REPP(i, n) { cin >> u; b[u] = i + 1; }
    VPII v;
    REPP(i, n) {
        v.PB(MP(a[i], b[i]));
    }
    MS(fenw);
    sort(ALL(v));
    int ans = 0;
    for (int i = n - 1; i >= 0; i--) {
        auto p = v[i];
        int curr = get(p.second);
        ans = max(ans, curr + 1);
        upd(p.second, curr + 1);
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("O3")

#include <bits/stdc++.h>

using namespace std;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

#define n_l '\n'
#define dbg(...) cout << "[" << #__VA_ARGS__ << "]: "; cout << to_string(__VA_ARGS__) << endl
template <typename T, size_t N> int SIZE(const T (&t)[N]){ return N; } template<typename T> int SIZE(const T &t){ return t.size(); } string to_string(const string s, int x1=0, int x2=1e9){ return '"' + ((x1 < s.size()) ? s.substr(x1, x2-x1+1) : "") + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(const bool b) { return (b ? "true" : "false"); } string to_string(const char c){ return string({c}); } template<size_t N> string to_string(const bitset<N> &b, int x1=0, int x2=1e9){ string t = ""; for(int __iii__ = min(x1,SIZE(b)),  __jjj__ = min(x2, SIZE(b)-1); __iii__ <= __jjj__; ++__iii__){ t += b[__iii__] + '0'; } return '"' + t + '"'; } template <typename A, typename... C> string to_string(const A (&v), int x1=0, int x2=1e9, C... coords); int l_v_l_v_l = 0, t_a_b_s = 0; template <typename A, typename B> string to_string(const pair<A, B> &p) { l_v_l_v_l++; string res = "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; l_v_l_v_l--; return res; } template <typename A, typename... C> string to_string(const A (&v), int x1, int x2, C... coords) { int rnk = rank<A>::value; string tab(t_a_b_s, ' '); string res = ""; bool first = true; if(l_v_l_v_l == 0) res += n_l; res += tab + "["; x1 = min(x1, SIZE(v)), x2 = min(x2, SIZE(v)); auto l = begin(v); advance(l, x1); auto r = l; advance(r, (x2-x1) + (x2 < SIZE(v))); for (auto e = l; e != r; e = next(e)) { if (!first) { res += ", "; } first = false; l_v_l_v_l++; if(e != l){ if(rnk > 1) { res += n_l; t_a_b_s = l_v_l_v_l; }; } else{ t_a_b_s = 0; } res += to_string(*e, coords...); l_v_l_v_l--; } res += "]"; if(l_v_l_v_l == 0) res += n_l; return res; } void dbgm(){;} template<typename Heads, typename... Tails> void dbgm(Heads H, Tails... T){ cout << to_string(H) << " | "; dbgm(T...); }
#define dbgm(...) cout << "[" << #__VA_ARGS__ << "]: "; dbgm(__VA_ARGS__); cout << endl

#define REP(i,b) for(int i=0;i<(b);i++)
#define PER(i,a,b) for(int i=(a);i>(b);i++)
#define SZ(a) int((a).size())
#define ALL(a) (a).begin(), (a).end()
#define MS(s) memset(s, 0, sizeof(s))
#define PB push_back
#define MP make_pair

typedef vector<pair<int, int>> VPII;
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = (int) 1e9 + 7;
string ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
string ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

struct hashLL { /* mp.rehash(n << 2); */
    size_t operator()(ll x) const {
        x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
        x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
        x = x ^ (x >> 31);
        return x;
    }
};

long long inv(long long a, long long b) {
    return 1 < a ? b - inv(b % a, a) * b / a : 1;
}

const ll INF = 1e6;

unordered_map<int, int, custom_hash> mp;
// unordered_map<int, unordered_map<int, int, custom_hash>, custom_hash> g;

ll gcd(ll a, ll b, ll &x, ll &y) {
    if (a == 0) {
        x = 0;
        y = 1;
        return b;
    }
    ll x1, y1;
    ll d = gcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return d;
}

ll distsq(ll x1, ll y1, ll x2, ll y2) {
    return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
}

ll n, m;
const int N = 1000001;
ll toIdx[N];
int main() {
    // freopen("in.txt", "r", stdin);
    cin >> n;
    ll tmp;
    REP(i, n) {
        cin >> tmp;
        toIdx[tmp] = i + 1;
    }
    set<ll, greater<ll>> s;
    REP(i, n) {
        cin >> tmp;
        auto it = s.lower_bound(toIdx[tmp]);
        if (it == s.end()) {
            s.emplace(toIdx[tmp]);
        } else {
            s.erase(it);
            s.emplace(toIdx[tmp]);
        }
    }
    printf("%d\n", s.size());

    return 0;
}


#pragma GCC optimize("O3")

#include <bits/stdc++.h>

using namespace std;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

#define n_l '\n'
#define dbg(...) cout << "[" << #__VA_ARGS__ << "]: "; cout << to_string(__VA_ARGS__) << endl
template <typename T, size_t N> int SIZE(const T (&t)[N]){ return N; } template<typename T> int SIZE(const T &t){ return t.size(); } string to_string(const string s, int x1=0, int x2=1e9){ return '"' + ((x1 < s.size()) ? s.substr(x1, x2-x1+1) : "") + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(const bool b) { return (b ? "true" : "false"); } string to_string(const char c){ return string({c}); } template<size_t N> string to_string(const bitset<N> &b, int x1=0, int x2=1e9){ string t = ""; for(int __iii__ = min(x1,SIZE(b)),  __jjj__ = min(x2, SIZE(b)-1); __iii__ <= __jjj__; ++__iii__){ t += b[__iii__] + '0'; } return '"' + t + '"'; } template <typename A, typename... C> string to_string(const A (&v), int x1=0, int x2=1e9, C... coords); int l_v_l_v_l = 0, t_a_b_s = 0; template <typename A, typename B> string to_string(const pair<A, B> &p) { l_v_l_v_l++; string res = "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; l_v_l_v_l--; return res; } template <typename A, typename... C> string to_string(const A (&v), int x1, int x2, C... coords) { int rnk = rank<A>::value; string tab(t_a_b_s, ' '); string res = ""; bool first = true; if(l_v_l_v_l == 0) res += n_l; res += tab + "["; x1 = min(x1, SIZE(v)), x2 = min(x2, SIZE(v)); auto l = begin(v); advance(l, x1); auto r = l; advance(r, (x2-x1) + (x2 < SIZE(v))); for (auto e = l; e != r; e = next(e)) { if (!first) { res += ", "; } first = false; l_v_l_v_l++; if(e != l){ if(rnk > 1) { res += n_l; t_a_b_s = l_v_l_v_l; }; } else{ t_a_b_s = 0; } res += to_string(*e, coords...); l_v_l_v_l--; } res += "]"; if(l_v_l_v_l == 0) res += n_l; return res; } void dbgm(){;} template<typename Heads, typename... Tails> void dbgm(Heads H, Tails... T){ cout << to_string(H) << " | "; dbgm(T...); }
#define dbgm(...) cout << "[" << #__VA_ARGS__ << "]: "; dbgm(__VA_ARGS__); cout << endl

#define REP(i,b) for(int i=0;i<(b);i++)
#define PER(i,a,b) for(int i=(a);i>(b);i++)
#define SZ(a) int((a).size())
#define ALL(a) (a).begin(), (a).end()
#define MS(s) memset(s, 0, sizeof(s))
#define PB push_back
#define MP make_pair

typedef vector<pair<int, int>> VPII;
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = (int) 1e9 + 7;
string ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
string ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

struct hashLL { /* mp.rehash(n << 2); */
    size_t operator()(ll x) const {
        x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
        x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
        x = x ^ (x >> 31);
        return x;
    }
};

long long inv(long long a, long long b) {
    return 1 < a ? b - inv(b % a, a) * b / a : 1;
}

const ll INF = 1e6;

unordered_map<int, int, custom_hash> mp;
// unordered_map<int, unordered_map<int, int, custom_hash>, custom_hash> g;

ll gcd(ll a, ll b, ll &x, ll &y) {
    if (a == 0) {
        x = 0;
        y = 1;
        return b;
    }
    ll x1, y1;
    ll d = gcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return d;
}

ll distsq(ll x1, ll y1, ll x2, ll y2) {
    return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
}

ll n, m;
const int N = 1000001;
ll top[N];
ll bot[N];
map<ll, ll> toIdx;
int main() {
    // freopen("in.txt", "r", stdin);
    cin >> n;
    ll tmp;
    REP(i, n) {
        cin >> tmp;
        toIdx[tmp] = i + 1;
    }
    set<ll, greater<ll>> s;
    REP(i, n) {
        cin >> tmp;
        auto it = s.lower_bound(toIdx[tmp]);
        if (it == s.end()) {
            s.emplace(toIdx[tmp]);
        } else {
            s.erase(it);
            s.emplace(toIdx[tmp]);
        }
    }
    printf("%d\n", s.size());

    return 0;
}


#pragma GCC optimize("O3")

#include <bits/stdc++.h>

using namespace std;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

#define n_l '\n'
#define dbg(...) cout << "[" << #__VA_ARGS__ << "]: "; cout << to_string(__VA_ARGS__) << endl
template <typename T, size_t N> int SIZE(const T (&t)[N]){ return N; } template<typename T> int SIZE(const T &t){ return t.size(); } string to_string(const string s, int x1=0, int x2=1e9){ return '"' + ((x1 < s.size()) ? s.substr(x1, x2-x1+1) : "") + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(const bool b) { return (b ? "true" : "false"); } string to_string(const char c){ return string({c}); } template<size_t N> string to_string(const bitset<N> &b, int x1=0, int x2=1e9){ string t = ""; for(int __iii__ = min(x1,SIZE(b)),  __jjj__ = min(x2, SIZE(b)-1); __iii__ <= __jjj__; ++__iii__){ t += b[__iii__] + '0'; } return '"' + t + '"'; } template <typename A, typename... C> string to_string(const A (&v), int x1=0, int x2=1e9, C... coords); int l_v_l_v_l = 0, t_a_b_s = 0; template <typename A, typename B> string to_string(const pair<A, B> &p) { l_v_l_v_l++; string res = "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; l_v_l_v_l--; return res; } template <typename A, typename... C> string to_string(const A (&v), int x1, int x2, C... coords) { int rnk = rank<A>::value; string tab(t_a_b_s, ' '); string res = ""; bool first = true; if(l_v_l_v_l == 0) res += n_l; res += tab + "["; x1 = min(x1, SIZE(v)), x2 = min(x2, SIZE(v)); auto l = begin(v); advance(l, x1); auto r = l; advance(r, (x2-x1) + (x2 < SIZE(v))); for (auto e = l; e != r; e = next(e)) { if (!first) { res += ", "; } first = false; l_v_l_v_l++; if(e != l){ if(rnk > 1) { res += n_l; t_a_b_s = l_v_l_v_l; }; } else{ t_a_b_s = 0; } res += to_string(*e, coords...); l_v_l_v_l--; } res += "]"; if(l_v_l_v_l == 0) res += n_l; return res; } void dbgm(){;} template<typename Heads, typename... Tails> void dbgm(Heads H, Tails... T){ cout << to_string(H) << " | "; dbgm(T...); }
#define dbgm(...) cout << "[" << #__VA_ARGS__ << "]: "; dbgm(__VA_ARGS__); cout << endl

#define REP(i,b) for(int i=0;i<(b);i++)
#define REPP(i,b) for(int i=1;i<=(b);i++)
#define PER(i,a,b) for(int i=(a);i>(b);i++)
#define SZ(a) int((a).size())
#define ALL(a) (a).begin(), (a).end()
#define MS(s) memset(s, 0, sizeof(s))
#define PB push_back
#define MP make_pair

typedef vector<pair<int, int>> VPII;
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = (int) 1e9 + 7;
string ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
string ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

struct hashLL { /* mp.rehash(n << 2); */
    size_t operator()(ll x) const {
        x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
        x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
        x = x ^ (x >> 31);
        return x;
    }
};

long long inv(long long a, long long b) {
    return 1 < a ? b - inv(b % a, a) * b / a : 1;
}

const ll INF = 1e6;

// unordered_map<int, int, custom_hash> mp;
// unordered_map<int, unordered_map<int, int, custom_hash>, custom_hash> g;

ll gcd(ll a, ll b, ll &x, ll &y) {
    if (a == 0) {
        x = 0;
        y = 1;
        return b;
    }
    ll x1, y1;
    ll d = gcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return d;
}

ll distsq(ll x1, ll y1, ll x2, ll y2) {
    return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
}

ll n, m;
const int N = 1000006;
int fenw[N];
void upd(int p, int v) {
    while (p <= n) {
        fenw[p] = max(fenw[p], v);
        p = p | (p + 1);
    }
}
int get(int p) {
    int ans = 0;
    while (p >= 0) {
        ans = max(ans, fenw[p]);
        p = (p & (p+1)) - 1;
    }
    return ans;
}
int a[N];
int b[N];
int main() {
    // freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    ll u;
    REPP(i, n) { cin >> u; a[u] = i; }
    REPP(i, n) { cin >> u; b[u] = i; }
    VPII v;
    REPP(i, n) {
        v.PB(MP(a[i], b[i]));
    }
    MS(fenw);
    sort(ALL(v));
    int ans = 0;
    for (int i = n - 1; i >= 0; i--) {
        auto p = v[i];
        int curr = get(p.second);
        ans = max(ans, curr + 1);
        upd(p.second, curr + 1);
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("O3")

#include <bits/stdc++.h>

using namespace std;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

#define n_l '\n'
#define dbg(...) cout << "[" << #__VA_ARGS__ << "]: "; cout << to_string(__VA_ARGS__) << endl
template <typename T, size_t N> int SIZE(const T (&t)[N]){ return N; } template<typename T> int SIZE(const T &t){ return t.size(); } string to_string(const string s, int x1=0, int x2=1e9){ return '"' + ((x1 < s.size()) ? s.substr(x1, x2-x1+1) : "") + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(const bool b) { return (b ? "true" : "false"); } string to_string(const char c){ return string({c}); } template<size_t N> string to_string(const bitset<N> &b, int x1=0, int x2=1e9){ string t = ""; for(int __iii__ = min(x1,SIZE(b)),  __jjj__ = min(x2, SIZE(b)-1); __iii__ <= __jjj__; ++__iii__){ t += b[__iii__] + '0'; } return '"' + t + '"'; } template <typename A, typename... C> string to_string(const A (&v), int x1=0, int x2=1e9, C... coords); int l_v_l_v_l = 0, t_a_b_s = 0; template <typename A, typename B> string to_string(const pair<A, B> &p) { l_v_l_v_l++; string res = "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; l_v_l_v_l--; return res; } template <typename A, typename... C> string to_string(const A (&v), int x1, int x2, C... coords) { int rnk = rank<A>::value; string tab(t_a_b_s, ' '); string res = ""; bool first = true; if(l_v_l_v_l == 0) res += n_l; res += tab + "["; x1 = min(x1, SIZE(v)), x2 = min(x2, SIZE(v)); auto l = begin(v); advance(l, x1); auto r = l; advance(r, (x2-x1) + (x2 < SIZE(v))); for (auto e = l; e != r; e = next(e)) { if (!first) { res += ", "; } first = false; l_v_l_v_l++; if(e != l){ if(rnk > 1) { res += n_l; t_a_b_s = l_v_l_v_l; }; } else{ t_a_b_s = 0; } res += to_string(*e, coords...); l_v_l_v_l--; } res += "]"; if(l_v_l_v_l == 0) res += n_l; return res; } void dbgm(){;} template<typename Heads, typename... Tails> void dbgm(Heads H, Tails... T){ cout << to_string(H) << " | "; dbgm(T...); }
#define dbgm(...) cout << "[" << #__VA_ARGS__ << "]: "; dbgm(__VA_ARGS__); cout << endl

#define REP(i,b) for(int i=0;i<(b);i++)
#define PER(i,a,b) for(int i=(a);i>(b);i++)
#define SZ(a) int((a).size())
#define ALL(a) (a).begin(), (a).end()
#define MS(s) memset(s, 0, sizeof(s))
#define PB push_back
#define MP make_pair

typedef vector<pair<int, int>> VPII;
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = (int) 1e9 + 7;
string ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
string ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

struct hashLL { /* mp.rehash(n << 2); */
    size_t operator()(ll x) const {
        x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
        x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
        x = x ^ (x >> 31);
        return x;
    }
};

long long inv(long long a, long long b) {
    return 1 < a ? b - inv(b % a, a) * b / a : 1;
}

const ll INF = 1e6;

unordered_map<int, int, custom_hash> mp;
// unordered_map<int, unordered_map<int, int, custom_hash>, custom_hash> g;

ll gcd(ll a, ll b, ll &x, ll &y) {
    if (a == 0) {
        x = 0;
        y = 1;
        return b;
    }
    ll x1, y1;
    ll d = gcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return d;
}

ll distsq(ll x1, ll y1, ll x2, ll y2) {
    return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
}

ll n, m;
const int N = 1000001;
ll toIdx[N];
vector<int> v;
int main() {
    // freopen("in.txt", "r", stdin);
    cin >> n;
    ll tmp;
    REP(i, n) {
        cin >> tmp;
        toIdx[tmp] = i + 1;
    }
    v.reserve(n);
    set<ll, greater<ll>> s;
    REP(i, n) {
        cin >> tmp;
        auto it = lower_bound(v.begin(), v.end(), n - toIdx[tmp] + 1);
        if (it == v.end()) {
            v.PB(n - toIdx[tmp]+1);
        } else {
            *it = n - toIdx[tmp]+1;
        }
    }
    printf("%d\n", v.size());

    return 0;
}


#pragma GCC optimize("O3")

#include <bits/stdc++.h>

using namespace std;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

#define n_l '\n'
#define dbg(...) cout << "[" << #__VA_ARGS__ << "]: "; cout << to_string(__VA_ARGS__) << endl
template <typename T, size_t N> int SIZE(const T (&t)[N]){ return N; } template<typename T> int SIZE(const T &t){ return t.size(); } string to_string(const string s, int x1=0, int x2=1e9){ return '"' + ((x1 < s.size()) ? s.substr(x1, x2-x1+1) : "") + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(const bool b) { return (b ? "true" : "false"); } string to_string(const char c){ return string({c}); } template<size_t N> string to_string(const bitset<N> &b, int x1=0, int x2=1e9){ string t = ""; for(int __iii__ = min(x1,SIZE(b)),  __jjj__ = min(x2, SIZE(b)-1); __iii__ <= __jjj__; ++__iii__){ t += b[__iii__] + '0'; } return '"' + t + '"'; } template <typename A, typename... C> string to_string(const A (&v), int x1=0, int x2=1e9, C... coords); int l_v_l_v_l = 0, t_a_b_s = 0; template <typename A, typename B> string to_string(const pair<A, B> &p) { l_v_l_v_l++; string res = "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; l_v_l_v_l--; return res; } template <typename A, typename... C> string to_string(const A (&v), int x1, int x2, C... coords) { int rnk = rank<A>::value; string tab(t_a_b_s, ' '); string res = ""; bool first = true; if(l_v_l_v_l == 0) res += n_l; res += tab + "["; x1 = min(x1, SIZE(v)), x2 = min(x2, SIZE(v)); auto l = begin(v); advance(l, x1); auto r = l; advance(r, (x2-x1) + (x2 < SIZE(v))); for (auto e = l; e != r; e = next(e)) { if (!first) { res += ", "; } first = false; l_v_l_v_l++; if(e != l){ if(rnk > 1) { res += n_l; t_a_b_s = l_v_l_v_l; }; } else{ t_a_b_s = 0; } res += to_string(*e, coords...); l_v_l_v_l--; } res += "]"; if(l_v_l_v_l == 0) res += n_l; return res; } void dbgm(){;} template<typename Heads, typename... Tails> void dbgm(Heads H, Tails... T){ cout << to_string(H) << " | "; dbgm(T...); }
#define dbgm(...) cout << "[" << #__VA_ARGS__ << "]: "; dbgm(__VA_ARGS__); cout << endl

#define REP(i,b) for(int i=0;i<(b);i++)
#define REPP(i,b) for(int i=1;i<=(b);i++)
#define PER(i,a,b) for(int i=(a);i>(b);i++)
#define SZ(a) int((a).size())
#define ALL(a) (a).begin(), (a).end()
#define MS(s) memset(s, 0, sizeof(s))
#define PB push_back
#define MP make_pair

typedef vector<pair<int, int>> VPII;
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = (int) 1e9 + 7;
string ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
string ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

struct hashLL { /* mp.rehash(n << 2); */
    size_t operator()(ll x) const {
        x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
        x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
        x = x ^ (x >> 31);
        return x;
    }
};

long long inv(long long a, long long b) {
    return 1 < a ? b - inv(b % a, a) * b / a : 1;
}

const ll INF = 1e6;

// unordered_map<int, int, custom_hash> mp;
// unordered_map<int, unordered_map<int, int, custom_hash>, custom_hash> g;

ll gcd(ll a, ll b, ll &x, ll &y) {
    if (a == 0) {
        x = 0;
        y = 1;
        return b;
    }
    ll x1, y1;
    ll d = gcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return d;
}

ll distsq(ll x1, ll y1, ll x2, ll y2) {
    return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
}

ll n, m;
const int N = 1000006;
int fenw[N];
void upd(int p, int v) {
    while (p <= n) {
        fenw[p] = max(fenw[p], v);
        p = p | (p + 1);
    }
}
int get(int p) {
    int ans = 0;
    while (p >= 0) {
        ans = max(ans, fenw[p]);
        p = (p & (p+1)) - 1;
    }
    return ans;
}
int a[N];
int b[N];
int main() {
    // freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    REP(i, n) cin >> a[i];
    REP(i, n) cin >> b[i];
    VPII v;
    REP(i, n) {
        v.PB(MP(b[i], a[i]));
    }
    MS(fenw);
    sort(ALL(v));
    int ans = 0;
    for (int i = n - 1; i >= 0; i--) {
        auto p = v[i];
        int curr = get(p.second);
        ans = max(ans, curr + 1);
        upd(p.second, curr + 1);
    }
    cout << ans;
    return 0;
}


#include<bits/stdc++.h>
#define long long long
using namespace std;
const int N=1e6;
int aa[N+2],bit[N+2],pos[N+2];
void upd(int x,int vl)
{
  for( ;x<=N;x+=x&-x)
    bit[x]=max(bit[x],vl);
}
int qry(int x)
{
  int ret=0;
  for( ;x>0;x-=x&-x)
    ret=max(ret,bit[x]);
  return ret;
}
int main()
{
  ios_base::sync_with_stdio(0);cin.tie(0);
  int n;cin>>n;
  for(int i=1;i<=n;i++)
  {
    int x;cin>>x;pos[x]=i;
  }
  for(int i=1;i<=n;i++)
  {
    int x;cin>>x;
    aa[i]=pos[x];
  }
  int mx=0;
  for(int i=n;i>=1;i--)
  {
    int xx=qry(aa[i])+1;
    mx=max(mx,xx);upd(aa[i],xx);
  }
  cout<<mx<<endl;
  return 0;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int N = 1e6 + 5;
int tree[4 * N];

void update(int node, int l, int r, int idx, int val)
{
	if(idx > r || idx < l)
		return;
	if(l == r)
	{
		tree[node] = val;
		return;
	}
	int mid = (l + r) >> 1;
	update(node << 1, l, mid, idx, val);
	update((node << 1) + 1, mid + 1, r, idx, val);
	tree[node] = max(tree[node << 1], tree[(node << 1) + 1]);
}

int query(int node, int l, int r, int st, int en)
{
		if(st > r || en < l || st > en)
			return 0;
		if(st <= l && r <= en)
			return tree[node];
		int mid = (l + r) >> 1;
		return max(query(node << 1, l, mid, st, en), query((node << 1) + 1, mid + 1, r, st, en));
}

int arr1[N];
int pos[N];
int arr[N];

int main()
{
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	// freopen("input.txt", "r", stdin);
	// freopen("output.txt", "w", stdout);
	int n;
	cin >> n;
	for(int i = 0; i < n; i++)
	{
		cin >> arr1[i];
	}
	for(int i = 0; i < n; i++)
	{
		int x;
		cin >> x;
		pos[x] = i;
	}
	for(int i = 0; i < n; i++)
	{
		arr[i] = pos[arr1[i]];
	}
	for(int i = 0; i < n; i++)
	{
		int mx = query(1, 0, n - 1, arr[i], n - 1);
		update(1, 0, n - 1, arr[i], mx + 1);
	}
	cout << tree[1];
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
#include <cassert>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e6 + 10;
class BIT
{
public:
	int a[N];
	void add(int x)
	{
		int t = sum(x - 1) + 1;
		while (x < N)
		{
			a[x] = max(a[x], t);
			x += x & -x;
		}
	}
	int sum(int x)
	{
		int ret = 0;
		while (x)
		{
			ret = max(ret, a[x]);
			x -= x & -x;
		}
		return ret;
	}
} b;
pair<int, int> p[N];
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		int x;
		scanf("%d", &x);
		p[x].first = i;
	}
	for (int i = 1; i <= n; i++)
	{
		int x;
		scanf("%d", &x);
		p[x].second = n - i + 1;
	}
	sort(p + 1, p + n + 1);
	for (int i = 1; i <= n; i++)
	{
		b.add(p[i].second);
	}
	printf("%d\n", b.sum(N - 1));
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
#include <cassert>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e6 + 10;
class BIT
{
public:
	int a[N];
	void add(int x)
	{
		int t = sum(x - 1) + 1;
		while (x < N)
		{
			a[x] = max(a[x], t);
			x += x & -x;
		}
	}
	int sum(int x)
	{
		int ret = 0;
		while (x)
		{
			ret = max(ret, a[x]);
			x -= x & -x;
		}
		return ret;
	}
} b;
pair<int, int> p[N];
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d", &p[i].first);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &p[i].second);
		p[i].second = n - p[i].second + 1;
	}
	sort(p + 1, p + n + 1);
	for (int i = 1; i <= n; i++)
	{
		b.add(p[i].second);
	}
	printf("%d\n", b.sum(N - 1));
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define PB push_back
#define ZERO (1e-10)
#define INF int(1e9+1)
#define CL(A,I) (memset(A,I,sizeof(A)))
#define DEB printf("DEB!\n");
#define D(X) cout<<"  "<<#X": "<<X<<endl;
#define EQ(A,B) (A+ZERO>B&&A-ZERO<B)
typedef long long ll;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
#define IN(n) int n;scanf("%d",&n);
#define FOR(i, m, n) for (int i(m); i < n; i++)
#define F(n) FOR(i,0,n)
#define FF(n) FOR(j,0,n)
#define FT(m, n) FOR(k, m, n)
#define aa first
#define bb second
void ga(int N,int *A){F(N)scanf("%d",A+i);}
#define MX 1000006
int lis(int *a,int AS,int *b){
    if(!AS)return 0;
    static int p[MX];
    int u,v,L(1),c;
    *b=0;
    FT(1,AS)if(a[b[L-1]]<a[k])p[k]=b[L],b[L++]=k;
        else{
            for(u=0,v=L-1;u<v;)if(a[b[c=(u+v)>>1]]<a[k])u=c+1;
                               else v=c;
            if(a[k]<a[b[u]]){
                if(u>0)p[k]=b[u-1];
                b[u]=k;
            }
        }
    for(u=L,v=b[L-1];--u;v=p[v])b[u]=v;
    return L;
}
int N,A[MX],B[MX],C[MX];
int main(void){
    scanf("%d",&N),ga(N,A),ga(N,B);
    F(N)C[A[i]]=i;
    F(N)B[i]=N-C[B[i]];
    printf("%d\n",lis(B,N,A));
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define PB push_back
#define ZERO (1e-10)
#define INF int(1e9+1)
#define CL(A,I) (memset(A,I,sizeof(A)))
#define DEB printf("DEB!\n");
#define D(X) cout<<"  "<<#X": "<<X<<endl;
#define EQ(A,B) (A+ZERO>B&&A-ZERO<B)
typedef long long ll;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
#define IN(n) int n;scanf("%d",&n);
#define FOR(i, m, n) for (int i(m); i < n; i++)
#define F(n) FOR(i,0,n)
#define FF(n) FOR(j,0,n)
#define FT(m, n) FOR(k, m, n)
#define aa first
#define bb second
void ga(int N,int *A){F(N)scanf("%d",A+i);}
#define MX 1000006
int lis(int *a,int AS,int *b){
    if(!AS)return 0;
    static int p[MX];
    int u,v,L(1),c;
    *b=0;
    FT(1,AS)if(a[b[L-1]]<a[k])p[k]=b[L],b[L++]=k;
        else{
            for(u=0,v=L-1;u<v;)if(a[b[c=(u+v)>>1]]<a[k])u=c+1;
                               else v=c;
            if(a[k]<a[b[u]]){
                if(u>0)p[k]=b[u-1];
                b[u]=k;
            }
        }
    for(u=L,v=b[L-1];--u;v=p[v])b[u]=v;
    return L;
}
int N,A[MX],B[MX];
int main(void){
    scanf("%d",&N),ga(N,A+1),ga(N,B);
    F(N)A[i]=MX-B[A[i]];
    printf("%d\n",lis(B,N,A));
    return 0;
}//not true :/


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fs first
#define sc second

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e6 + 7;
pii a[maxn];
bool cmp(pii a, pii b){
	return a.fs > b.fs;
}

int main(){
	ios :: sync_with_stdio(false); cin.tie(0);
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++)
		cin >> a[i].fs;
	for(int i = 1; i <= n; i++)
		cin >> a[i].sc;
	sort(a + 1, a + n + 1, cmp);

	vector<int> f;
	f.pb(a[1].sc);
	for(int i = 2; i <= n; i++){
		int id = lower_bound(f.begin(), f.end(), a[i].sc) - f.begin();
		if (id == f.size())
			f.pb(a[i].sc);
		else f[id] = a[i].sc;
	}
	cout << f.size() << endl;
	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fs first
#define sc second

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e6 + 7;
pii a[maxn];
bool cmp(pii a, pii b){
	return a.fs > b.fs;
}

int main(){
	ios :: sync_with_stdio(false); cin.tie(0);
	int n;
	cin >> n;
	int x;
	for(int i = 1; i <= n; i++){
		cin >> x;
		a[x].fs = i;
	}
	for(int i = 1; i <= n; i++){
		cin >> x;
		a[x].sc = i;
	}
	sort(a + 1, a + n + 1, cmp);

	vector<int> f;
	f.pb(a[1].sc);
	for(int i = 2; i <= n; i++){
		int id = lower_bound(f.begin(), f.end(), a[i].sc) - f.begin();
		if (id == f.size())
			f.pb(a[i].sc);
		else f[id] = a[i].sc;
	}
	cout << f.size() << endl;
	return 0;
}


#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
using namespace std;

const int N = 1e6 + 100;
int d[N], w[N], r[N];

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	scanf("%d", &n);

	for (int i = 0; i < n; i++) {
		int a;
		scanf("%d", &a);
		w[a - 1] = i;
	}
	for (int i = 0; i < n; i++) {
		int a;
		scanf("%d", &a);
		r[w[a - 1]] = i;
	}

	setv(d, 127);
	d[0] = 0;
	for (int i = n - 1; i >= 0; i--) {
		*upper_bound(d, d + N, r[i]) = r[i];
	}

	printf("%d\n", upper_bound(d, d + N, 1e9) - d - 1);

	return 0;
}


#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>s
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
using namespace std;

const int N = 1e6 + 100;
int r[N], w[N], t[N];

int que(int x) {
	int ans = 0;
	for (; x >= 0; x = (x & (x + 1)) - 1)
		ans = max(t[x], ans);
	return ans;
}

void upd(int x, int a) {
	for (; x < N; x |= x + 1)
		t[x] = max(t[x], a);
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	scanf("%d", &n);

	for (int i = 0; i < n; i++) {
		int a;
		scanf("%d", &a);
		w[a - 1] = i;
	}
	for (int i = 0; i < n; i++) {
		int a;
		scanf("%d", &a);
		r[w[a - 1]] = i;
	}

	for (int i = n - 1; i >= 0; i--) {
		int mx = que(r[i]);
		upd(r[i], mx + 1);
	}

	printf("%d", que(N - 1));

	return 0;
}


#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
using namespace std;

const int N = 1e6 + 100;
int r[N], w[N], t[N];

int que(int x) {
	int ans = 0;
	for (; x >= 0; x = (x & (x + 1)) - 1)
		ans = max(t[x], ans);
	return ans;
}

void upd(int x, int a) {
	for (; x < N; x |= x + 1)
		t[x] = max(t[x], a);
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	scanf("%d", &n);

	for (int i = 0; i < n; i++) {
		int a;
		scanf("%d", &a);
		w[a - 1] = i;
	}
	for (int i = 0; i < n; i++) {
		int a;
		scanf("%d", &a);
		r[w[a - 1]] = i;
	}

	for (int i = n - 1; i >= 0; i--) {
		int mx = que(r[i]);
		upd(r[i], mx + 1);
	}

	printf("%d", que(N - 1));

	return 0;
}


// copied by Nurstan Duisengaliev
// skatal
#include <bits/stdc++.h>
 //hellooo
#define ll long long
#define all(x) x.begin(), x.end()
#define in insert
#define mp make_pair
#define F first
#define S second
#define ppf pop_front
#define pb push_back
#define ppb pop_back
#define pf push_front
#define pii pair <int, int>
#define boost() ios_base::sync_with_stdio(0), cin.tie(0)
#define sz(x) x.size()

using namespace std;

const int N = (int)1e6 + 123;
const int mod = (int)1e9 + 7;
const ll INF = (ll)1e18 + 7;
int n;
int cnt[N];
int a[N];
int dp[N];
int d[N * 4];
int get (int v, int l, int r, int nl, int nr) {
	if (l > nr || nl > r) return 0;
	if (nl <= l && r <= nr) return d[v];
	int mid = l + r >> 1;
	return max (get (v * 2, l, mid, nl, nr), get (v * 2 + 1, mid + 1, r, nl, nr));
}
void update (int v, int l, int r, int pos, int x) {
	if (l == r) {
		d[v] = x;
		return;
	}
	int mid = l + r >> 1;
	if (pos <= mid) update (v * 2, l, mid, pos, x);
	else update (v * 2 + 1, mid + 1, r, pos, x);
	d[v] = max (d[v * 2], d[v * 2 + 1]);
}
void solve () {
	cin >> n;
	for (int i = 1; i <= n; i ++) {
		int x;
		cin >> x;
		cnt[x] = i;
	}
	for (int i = 1; i <= n; i ++) {
		int x;
		cin >> x;
		a[i] = cnt[x];
	}
	int maxi = 1;
	for (int i = 1; i <= n; i ++) {
		int gg = get (1, 1, n, a[i] + 1, n);
		dp[a[i]] = gg + 1;
		update (1, 1, n, a[i], dp[a[i]]);
		maxi = max(maxi, dp[a[i]]);
	}
	cout << maxi;
}

main () {
//	freopen (".in", "r", stdin);
//	freopen (".out", "w", stdout);
	boost ();
	int TT = 1;
//  cin >> TT;
	while (TT --) {
		solve ();
	}
	return 0;
}


#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <limits>
#include <memory>
#include <queue>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define all(a) (a).begin(), (a).end()
#define sz(a) static_cast<int>((a).size())
#define fillchar(a, x) memset(a, x, sizeof(a))
#define rep(i, a, b) for(int i=int(a); i<=int(b); ++i)
#define irep(i, a, b) for(int i=int(a); i>=int(b); --i)
#define replr(i, a, b) rep(i, a, (b)-1)
#define reprl(i, a, b) irep(i, (b)-1, a)
#define repn(i, n) rep(i, 0, (n)-1)
#define irepn(i, n) irep(i, (n)-1, 0)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
typedef long long LL;
typedef pair<LL,LL> PLL;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
typedef vector<LL> VL;
typedef vector<int> VI;
typedef vector<PII> VPI;
typedef vector<string> VS;
template<class T, class S> ostream& operator<<(ostream& os, const pair<T, S>& v) { return os<<"("<<v.first<<", "<<v.second<<")"; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& v) { os<<"["; repn(i, sz(v)) { if(i) os<<", "; os<<v[i]; } return os<<"]"; }
template<class T> bool setmax(T &_a, T _b) { if(_b>_a) { _a=_b; return true; } return false; }
template<class T> bool setmin(T &_a, T _b) { if(_b<_a) { _a=_b; return true; } return false; }
template<class T> T gcd(T _a, T _b) { return _b==0?_a:gcd(_b,_a%_b); }

int solve(VI a) {
    const int n=sz(a);
    VI tr(n+1);
    const auto upt=[&tr,n](int x, int v) {
        for(; x<=n; x+=x&-x) setmax(tr[x], v);
    };
    const auto get=[&tr](int x) {
        int r=0;
        for(; x>=1; x-=x&-x) setmax(r, tr[x]);
        return r;
    };
    int ans=0;
    repn(i, n) {
        int cur=get(n-a[i])+1;
        upt(n-a[i], cur);
        setmax(ans, cur);
    }
    return ans;
}

int main() {
    int n; scanf("%d", &n);
    VI a(n);
    repn(i, n) {
        int x; scanf("%d", &x);
        --x; a[x]=i;
    }
    VI b(n);
    repn(i, n) {
        int x; scanf("%d", &x);
        --x; b[i]=a[x];
    }
    int ans=solve(b);
    printf("%d\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1<<20;

class tree {
  vector <int> t;

  int get(int v, int tl, int tr, int l, int r) {
    if (l < tl) {
      l = tl;
    }
    if (r > tr) {
      r = tr;
    }
    if (l > r) {
      return 0;
    }
    if (l == tl && r == tr) {
      return t[v];
    }
    return max(get(v * 2, tl, (tl + tr) / 2, l, r), get(v * 2 + 1, (tl + tr) / 2 + 1, tr, l, r));
  }

  void set(int v, int tl, int tr, int pos, int value) {
    if (tl == tr) {
      t[v] = value;
      return;
    }
    if (pos <= (tl + tr) / 2)
      set(v * 2, tl, (tl + tr) / 2, pos, value);
    else
      set(v * 2 + 1, (tl + tr) / 2 + 1, tr, pos, value);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
public:
  tree() : t(N * 2) {
  }
  int get(int l, int r) {
    return get(1, 0, N - 1, l, r);
  }

  void set(int pos, int value) {
    set(1, 0, N - 1, pos, value);
  }
};

int main() {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
#endif
  int n;
  cin >> n;
  vector <int> x(n + 1), y(n + 1);
  for (int i = 1; i <= n; ++i) {
    cin >> x[i];
  }
  for (int i = 1; i <= n; ++i) {
    cin >> y[i];
  }
  vector <int> b(n + 1);
  for (int i = 1; i <= n; ++i) {
    b[y[i]] = i;
  }
  vector <int> a(n + 1);
  for (int i = 1; i <= n; ++i) {
    a[i] = b[x[i]];
  }
  tree t;
  for (int i = 1; i <= n; ++i) {
    int cur = t.get(a[i] + 1, n) + 1;
    t.set(a[i], cur);
  }
  cout << t.get(1, n) << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1<<20;

class tree {
  vector <int> t;

  int get(int v, int tl, int tr, int l, int r) {
    if (l < tl) {
      l = tl;
    }
    if (r > tr) {
      r = tr;
    }
    if (l > r) {
      return 0;
    }
    if (l == tl && r == tr) {
      return t[v];
    }
    return max(get(v * 2, tl, (tl + tr) / 2, l, r), get(v * 2 + 1, (tl + tr) / 2 + 1, tr, l, r));
  }

  void set(int v, int tl, int tr, int pos, int value) {
    if (tl == tr) {
      t[v] = value;
      return;
    }
    if (pos <= (tl + tr) / 2)
      set(v * 2, tl, (tl + tr) / 2, pos, value);
    else
      set(v * 2 + 1, (tl + tr) / 2 + 1, tr, pos, value);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
public:
  tree() : t(N * 2) {
  }
  int get(int l, int r) {
    return get(1, 0, N - 1, l, r);
  }

  void set(int pos, int value) {
    set(1, 0, N - 1, pos, value);
  }
};

int main() {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
#endif
  int n;
  cin >> n;
  vector <int> x(n), y(n);
  for (int i = 0; i < n; ++i) {
    cin >> x[i];
  }
  for (int i = 0; i < n; ++i) {
    cin >> y[i];
  }
  vector <int> a(n + 1);
  for (int i = 0; i < n; ++i) {
    a[x[i]] = y[i];
  }
  tree t;
  for (int i = 1; i <= n; ++i) {
    int cur = t.get(a[i] + 1, n) + 1;
    t.set(a[i], cur);
  }
  cout << t.get(1, n) << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1<<20;

class tree {
  vector <int> t;

  int get(int v, int tl, int tr, int l, int r) {
    if (l < tl) {
      l = tl;
    }
    if (r > tr) {
      r = tr;
    }
    if (l > r) {
      return 0;
    }
    if (l == tl && r == tr) {
      return t[v];
    }
    return max(get(v * 2, tl, (tl + tr) / 2, l, r), get(v * 2 + 1, (tl + tr) / 2 + 1, tr, l, r));
  }

  void set(int v, int tl, int tr, int pos, int value) {
    if (tl == tr) {
      t[v] = value;
      return;
    }
    if (pos <= (tl + tr) / 2)
      set(v * 2, tl, (tl + tr) / 2, pos, value);
    else
      set(v * 2 + 1, (tl + tr) / 2 + 1, tr, pos, value);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
public:
  tree() : t(N * 2) {
  }
  int get(int l, int r) {
    return get(1, 0, N - 1, l, r);
  }

  void set(int pos, int value) {
    set(1, 0, N - 1, pos, value);
  }
};

int main() {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector <int> x(n + 1), y(n + 1);
  for (int i = 1; i <= n; ++i) {
    cin >> x[i];
  }
  for (int i = 1; i <= n; ++i) {
    cin >> y[i];
  }
  vector <int> b(n + 1);
  for (int i = 1; i <= n; ++i) {
    b[y[i]] = i;
  }
  vector <int> a(n + 1);
  for (int i = 1; i <= n; ++i) {
    a[i] = b[x[i]];
  }
  tree t;
  for (int i = 1; i <= n; ++i) {
    int cur = t.get(a[i] + 1, n) + 1;
    t.set(a[i], cur);
  }
  cout << t.get(1, n) << endl;
  return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;

int conv[1000000];
int a[1000000];
int b[1000000];
int n;

int best = 0;
int d[1000000];

int main() {
	ios_base::sync_with_stdio(0);
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		a[i]--;
	}
	for (int i = 0; i < n; i++) {
		cin >> b[i];
		b[i]--;
	}

	for (int i = 0; i < n; i++) {
		conv[a[i]] = i;
	}
	for (int i = 0; i < n; i++) {
		b[i] = conv[b[i]];
	}

	reverse(b, b + n);
	for (int i = 0; i < n; i++) {
		int l = -1;
		int r = best;
		while (r - l > 1) {
			int mid = (r + l) >> 1;
			if (d[mid] > b[i]) {
				r = mid;
			} else {
				l = mid;
			}
		}
		if (r == best) {
			d[best++] = b[i];
		} else {
			d[r] = b[i];
		}
	}
	cout << best;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define mod 1000000007
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define tr(x,it) for(auto it = x.begin();it!=x.end();++it)
#define fpresent(x,c) ((c).find(x) != (c).end())  //set,map
#define present(c,x) (find(all(c),x) != (c).end()) //vector
#define pr(a,b) cout<<a<<" "<<b<<endl
#define pr1(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define pr2(a,b,c,d) cout<<a<<" " <<b<<" "<<c<<" "<<d<<endl
#define pb push_back
#define mp make_pair
#define N 100001
#define F first
#define S second
typedef pair<ll, ll> iPair;
template< class T > T max3(const T &a, const T &b, const T &c) { return max(a, max(b, c)); }
template< class T > T min3(const T &a, const T &b, const T &c) { return min(a, min(b, c)); }
template< class T > T gcd(const T a, const T b) { return (b ? gcd<T>(b, a%b) : a); }
template< class T > T lcm(const T a, const T b) { return (a / gcd<T>(a, b) * b); }

int main()
{
	ll i,j=0,k=0,n,m,q,ans=0,f;
	cin>>n;
	ll b[n];
	ll ma[n+1];
	for(i=0;i<n;i++)
	{
		cin>>j;
		ma[j]=i;
	}
	for(i=0;i<n;i++)
		cin>>j,b[i]=ma[j];
	std::vector<ll> v;
	for(i=0;i<n/2;i++)
		swap(b[i],b[n-1-i]);
	v.pb(b[0]);
	for(i=1;i<n;i++)
	{
		if(b[i]>v.back())
			v.pb(b[i]);
		else
		{
			auto x=upper_bound(all(v),b[i])-v.begin();
			v[x]=b[i];
		}
	}
	cout<<v.size();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define mod 1000000007
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define tr(x,it) for(auto it = x.begin();it!=x.end();++it)
#define fpresent(x,c) ((c).find(x) != (c).end())  //set,map
#define present(c,x) (find(all(c),x) != (c).end()) //vector
#define pr(a,b) cout<<a<<" "<<b<<endl
#define pr1(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define pr2(a,b,c,d) cout<<a<<" " <<b<<" "<<c<<" "<<d<<endl
#define pb push_back
#define mp make_pair
#define N 100001
#define F first
#define S second
typedef pair<ll, ll> iPair;
template< class T > T max3(const T &a, const T &b, const T &c) { return max(a, max(b, c)); }
template< class T > T min3(const T &a, const T &b, const T &c) { return min(a, min(b, c)); }
template< class T > T gcd(const T a, const T b) { return (b ? gcd<T>(b, a%b) : a); }
template< class T > T lcm(const T a, const T b) { return (a / gcd<T>(a, b) * b); }

int main()
{
	ll i,j=0,k=0,n,m,q,ans=0,f;
	cin>>n;
	ll b[n];
	std::map<ll, ll> ma;
	for(i=0;i<n;i++)
	{
		cin>>j;
		ma[j]=i;
	}
	for(i=0;i<n;i++)
		cin>>j,b[i]=ma[j];
	std::vector<ll> v;
	for(i=0;i<n/2;i++)
		swap(b[i],b[n-1-i]);
	v.pb(b[0]);
	for(i=1;i<n;i++)
	{
		if(b[i]>v.back())
			v.pb(b[i]);
		else
		{
			auto x=upper_bound(all(v),b[i])-v.begin();
			v[x]=b[i];
		}
	}
	cout<<v.size();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define mod 1000000007
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define tr(x,it) for(auto it = x.begin();it!=x.end();++it)
#define fpresent(x,c) ((c).find(x) != (c).end())  //set,map
#define present(c,x) (find(all(c),x) != (c).end()) //vector
#define pr(a,b) cout<<a<<" "<<b<<endl
#define pr1(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define pr2(a,b,c,d) cout<<a<<" " <<b<<" "<<c<<" "<<d<<endl
#define pb push_back
#define mp make_pair
#define N 100001
#define F first
#define S second
typedef pair<ll, ll> iPair;
template< class T > T max3(const T &a, const T &b, const T &c) { return max(a, max(b, c)); }
template< class T > T min3(const T &a, const T &b, const T &c) { return min(a, min(b, c)); }
template< class T > T gcd(const T a, const T b) { return (b ? gcd<T>(b, a%b) : a); }
template< class T > T lcm(const T a, const T b) { return (a / gcd<T>(a, b) * b); }

int main()
{
    fastio;
	ll i,j=0,k=0,n,m,q,ans=0,f;
	cin>>n;
	ll b[n];
	std::map<ll, ll> ma;
	for(i=0;i<n;i++)
	{
		cin>>j;
		ma[j]=i;
	}
	for(i=0;i<n;i++)
		cin>>j,b[i]=ma[j];
	std::vector<ll> v;
	for(i=0;i<n/2;i++)
		swap(b[i],b[n-1-i]);
	v.pb(b[0]);
	for(i=1;i<n;i++)
	{
		if(b[i]>v.back())
			v.pb(b[i]);
		else
		{
			auto x=upper_bound(all(v),b[i])-v.begin();
			v[x]=b[i];
		}
	}
	cout<<v.size();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define mod 1000000007
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define tr(x,it) for(auto it = x.begin();it!=x.end();++it)
#define fpresent(x,c) ((c).find(x) != (c).end())  //set,map
#define present(c,x) (find(all(c),x) != (c).end()) //vector
#define pr(a,b) cout<<a<<" "<<b<<endl
#define pr1(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define pr2(a,b,c,d) cout<<a<<" " <<b<<" "<<c<<" "<<d<<endl
#define pb push_back
#define mp make_pair
#define N 100001
#define F first
#define S second
typedef pair<ll, ll> iPair;
template< class T > T max3(const T &a, const T &b, const T &c) { return max(a, max(b, c)); }
template< class T > T min3(const T &a, const T &b, const T &c) { return min(a, min(b, c)); }
template< class T > T gcd(const T a, const T b) { return (b ? gcd<T>(b, a%b) : a); }
template< class T > T lcm(const T a, const T b) { return (a / gcd<T>(a, b) * b); }

int main()
{
	ll i,j=0,k=0,n,m,q,ans=0,f;
	cin>>n;
	ll b[n];
	ll ma[n+1];
	for(i=0;i<n;i++)
	{
		scanf("%lld",&j);
		ma[j]=i;
	}
	for(i=0;i<n;i++)
		scanf("%lld",&j),b[i]=ma[j];
	std::vector<ll> v;
	for(i=0;i<n/2;i++)
		swap(b[i],b[n-1-i]);
	v.pb(b[0]);
	for(i=1;i<n;i++)
	{
		if(b[i]>v.back())
			v.pb(b[i]);
		else
		{
			auto x=upper_bound(all(v),b[i])-v.begin();
			v[x]=b[i];
		}
	}
	cout<<v.size();
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

#define VIC ios::sync_with_stdio(0);cin.tie(0);ios_base::sync_with_stdio(0);
#define sfi(x) scanf("%d", &x)
#define sfi2(x, y) scanf("%d%d", &x,&y)
#define sfl2(x, y) scanf("%I64d%I64d", &x,&y)
#define sfl(x) scanf("%I64d", &x)
#define sfd(x) scanf("%lf", &x)
#define sfd2(x, y) scanf("%lf%lf", &x, &y)
#define sfs(x) scanf("%s", &x)
#define wtf(s) freopen((s), "w", stdout)
#define rff(s) freopen((s), "r", stdin)
#define mod 998244353
#define pi (2 * acos(0))
#define x first
typedef long double ld;
typedef long long ll;
const int N = 1e6 + 5;
//g++ -std=c++11 main.cpp && a.exe

int tree[4 * N], a[N], upper[N], pos[N];

void update(int node, int start, int end, int idx, int val)
{
    if(start == end)
        tree[node] = val;
    else
    {
        int mid = (start + end) / 2;
        if(start <= idx and idx <= mid)
            update(2 * node, start, mid, idx, val);
        else
            update(2 * node + 1, mid + 1, end, idx, val);
        tree[node] = max(tree[2 * node], tree[2 * node + 1]);
    }
}
int query(int node, int start, int end, int l, int r)
{
    if(r < start or end < l)
        return 0;
    if(l <= start and end <= r)
        return tree[node];
    int mid = (start + end) / 2;
    int p1 = query(2 * node, start, mid, l, r);
    int p2 = query(2 * node + 1, mid + 1, end, l, r);
    return max(p1, p2);
}

int main()
{
    VIC
    int x, n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> upper[i];
    for (int i = 0; i < n; i++)
        cin >> x, pos[x] = i;
    for (int i = 0; i < n; i++)
        a[i] = pos[upper[i]];
    for (int i = 0; i < n; i++)
        update(1, 0, n - 1, a[i], query(1, 0, n - 1, a[i], n - 1) + 1);
    cout << tree[1];
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pb push_back
#define x first
#define y second
#define fastread ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define PI (atan(1)*4)
#define mp make_pair
using namespace std;

int LIS(vector<int>& v) {
	multiset<int> s;
	multiset<int>:: iterator it;
	for (int i = 0; i < v.size(); i++) {
		s.insert(v[i]);
		it = s.lower_bound(v[i]);
		it++;
		if (it != s.end())
			s.erase(it);
	}
	return s.size();
}

const int maxn = 1e6 + 7;
int n, val[maxn], tmp;
int main()
{
	fastread;
	vector<int> v;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> tmp;
		val[tmp] = i;
	}
	for (int i = 1; i <= n; i++) {
		cin >> tmp;
		v.pb(val[tmp]);
	}
	reverse(v.begin(), v.end());
	cout << LIS(v);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int n;
vector<int> a, b, t;

void update(int i, int v) {
	t[i+n] = max(t[i+n], v);
	for(i += n; i > 1; i >>= 1) t[i>>1] = max(t[i], t[i^1]);
}

int query(int l, int r) {
	int res = 0;
	for(l += n, r += n; l < r; l >>= 1, r >>= 1) {
		if(l & 1) res = max(t[l++], res);
		if(r & 1) res = max(t[--r], res);
	}
	return res;
}

int main() {
	cin >> n;
	a.resize(n);
	b.resize(n);
	t.resize(n<<1);
	for(int i = 0; i < n; i++) cin >> a[i], a[i]--;
	for(int i = 0, x; i < n; i++) cin >> x, b[x-1] = i;
	for(int i = 0; i < n; i++) update(b[a[i]], (b[a[i]] == n-1 ? 0 : query(b[a[i]]+1, n))+1);
	cout << query(0, n);
}


#include <bits/stdc++.h>
using namespace std;

int n;
vector<int> a, b, t;

void update(int i, int v) {
	t[i+n] = max(t[i+n], v);
	for(i += n; i > 1; i >>= 1) t[i>>1] = max(t[i], t[i^1]);
}

int query(int l, int r) {
	int res = 0;
	for(l += n, r += n; l < r; l >>= 1, r >>= 1) {
		if(l & 1) res = max(t[l++], res);
		if(r & 1) res = max(t[--r], res);
	}
	return res;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	a.resize(n);
	b.resize(n);
	t.resize(n<<1);
	for(int i = 0; i < n; i++) cin >> a[i], a[i]--;
	for(int i = 0, x; i < n; i++) cin >> x, b[x-1] = i;
	for(int i = 0; i < n; i++) update(b[a[i]], (b[a[i]] == n-1 ? 0 : query(b[a[i]]+1, n))+1);
	cout << query(0, n);
}


#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair

#define fi first
#define se second

typedef long long ll;

using namespace std;
  int n;
  int pos[100500], ppos[100500];

int main(){
  cin >> n;
  for(int i=1;i<=n;i++){
    int x;
    cin >> x;
    pos[x] = i;
  }
  for(int i=1;i<=n;i++){
    int x;
    cin >> x;
    ppos[pos[x] ] = i;
  }
  int ans = -1;
  vector<int> dp(n + 1, 1e9);
  dp[0] = 1;
  reverse(ppos + 1, ppos + n + 1);
  for(int i=1;i<=n;i++){
    int j = upper_bound(dp.begin(), dp.end(), ppos[i]) - dp.begin();
    dp[j] = ppos[i];
    ans = max(ans, j);
  }
  cout << ans;

  return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair

#define fi first
#define se second

typedef long long ll;

using namespace std;
  int n;
  int pos[1005000], ppos[1005000];

int main(){
  cin >> n;
  for(int i=1;i<=n;i++){
    int x;
    cin >> x;
    pos[x] = i;
  }
  for(int i=1;i<=n;i++){
    int x;
    cin >> x;
    ppos[pos[x] ] = i;
  }
  int ans = -1;
  vector<int> dp(n + 1, 1e9);
  dp[0] = 1;
  reverse(ppos + 1, ppos + n + 1);
  for(int i=1;i<=n;i++){
    int j = upper_bound(dp.begin(), dp.end(), ppos[i]) - dp.begin();
    dp[j] = ppos[i];
    ans = max(ans, j);
  }
  cout << ans;

  return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair

#define fi first
#define se second

typedef long long ll;

using namespace std;
  int n, a[1005000];
  int pos[1005000], t[4 * 1005000];

  int get(int v, int tl, int tr, int l, int r){
    if(tr < l || tl > r){
      return 0;
    }
    if(l <= tl && tr <= r){
      return t[v];
    }
    int tm = (tl + tr) >> 1;
    return max(get(v + v, tl, tm, l, r), get(v + v + 1, tm + 1, tr, l, r) );
  }
  void update(int v, int tl, int tr, int ps, int val){
    if(tl == tr){
      t[v] = val;
      return;
    }
    int tm = (tl + tr) >> 1;
    if(ps <= tm){
      update(v + v, tl, tm, ps, val);
    }
    else{
      update(v + v + 1, tm + 1, tr, ps, val);
    }
    t[v] = max(t[v + v], t[v + v + 1] );
  }

int main(){
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);

  cin >> n;
  for(int i=1;i<=n;i++){
    int x;
    cin >> x;
    pos[x] = i;
  }
  for(int i=1;i<=n;i++){
    int x;
    cin >> x;
    a[pos[x] ] = i;
  }

  for(int i=1;i<=n;i++){
    update(1, 1, n, a[i], get(1, 1, n, a[i] + 1, n) + 1);
  }
  cout << get(1, 1, n, 1, n);

  return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair

#define fi first
#define se second

typedef long long ll;

using namespace std;
  int n;
  int pos[1005000], ppos[1005000];

int main(){
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);

  cin >> n;
  for(int i=1;i<=n;i++){
    int x;
    cin >> x;
    pos[x] = i;
  }
  for(int i=1;i<=n;i++){
    int x;
    cin >> x;
    ppos[pos[x] ] = i;
  }
  int ans = -1;
  vector<int> dp(n + 1, 1e9);
  dp[0] = 1;
  reverse(ppos + 1, ppos + n + 1);
  for(int i=1;i<=n;i++){
    int j = upper_bound(dp.begin(), dp.end(), ppos[i]) - dp.begin();
    dp[j] = ppos[i];
    ans = max(ans, j);
  }
  cout << ans;

  return 0;
}