#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 100000000 //998244353
#include<string.h>
#define inf 1000000000000000000
#define maxn 2000002
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define trace(x) cout<<#x<<": "<<x<<" "<<endl
#define trace2(x,y) cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x,y,z) cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a,b,c,d) cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<" "<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<ll,vector<ll>,greater<ll> > pqset;
typedef priority_queue<pint,vector<pint>,greater<pint> > pqset_ll;
#define pb push_back
#define fi first
#define se second
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define mp make_pair
#define acc (ios::sync_with_stdio(false),cin.tie(0))
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define rep1(i,n) for(ll i=1;i<=n;i++)
#define per1(i,n) for(ll i=n;i>0;i--)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
#define print(a,n) for(ll i=0;i<n;i++){ cout<<a[i]<<" ";}
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
bool prime[maxn];
ll fact[maxn];
ll Tree[maxn];
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
void build(int node,int start,int end,ll a[]){
	if(start==end){
		Tree[node]=a[start];
		return;
	}
	int mid=((start+end)>>1);
	build(2*node+1,start,mid,a);
	build(2*node+2,mid+1,end,a);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
void update(int node,int start,int end,ll a[],int i,ll val){
	if(start==end){
		Tree[node]=val;
		return;
	}
	int mid=((start+end)>>1);
	if(i<=mid)
		update(2*node+1,start,mid,a,i,val);
	else
		update(2*node+2,mid+1,end,a,i,val);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
int query(int node,int start,int end,int l,int r){
	if(start>end||end<l||start>r)
		return(0);//0 in case of sum , high value in case of min , low value in case of max and soooo on
	if(start==l&&end==r)
		return(Tree[node]);
	int mid = (start+end)/2 ;
	int p1 = query(node*2+1, start, mid, l,r);
	int p2 = query(node*2+2, mid+1, end , l,r);
	return max(p1,p2);
}
void dfs_connected(int i,vector<int> v[],bool visited[],vector<int> &v3){
	visited[i]=true;
	v3.pb(i);
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected(v[i][j],v,visited,v3);
		}
	}
}
void dfs_connected1(int i,vector<int> v[],bool visited[],stack<int> &s){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected1(v[i][j],v,visited,s);
		}
	}
	s.push(i);
}
void StronglyConnectedComponents(vector<int> v[],vector<int> v1[],vector<vector<int> > &v2,int n){
	stack<int> s;
	bool visited1[n+1]={false};
	repeat(i,1,n+1){
		if(visited1[i]==false)
			dfs_connected1(i,v,visited1,s);
	}
	bool visited[n+1]={0};
	while(!s.empty()){
		while(visited[s.top()]){
			s.pop();
			if(s.size()==0)
				return;
		}
		int a=s.top();
		s.pop();
		vector<int> v3;
		dfs_connected(a,v1,visited,v3);
		v2.pb(v3);
	}
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
}
ll phi(ll n){
	ll result=n;
	for(ll i=2;i*i<=n;i++){
		if(n%i==0){
			while(n%i==0)
				n/=i;
			result-=(result)/i;
		}
	}
	if(n>1)
		result-=result/n;
	return result;
}
bool compare_string(pair<string,int> a,pair<string,int> b){
	if(a.fi.size()<b.fi.size())
		return true;
	else if(a.fi.size()==b.fi.size()){
		if(a.fi<b.fi)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare_string1(string a,string b){
	if(a.size()<b.size())
		return true;
	else if(a.size()==b.size()){
		if(a<b)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare(pair<ll,ll> a,pair<ll,ll> b){
	if(a.first<b.first)
		return true;
	else if(a.first==b.first){
		if(a.se>b.se)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool sortbysec(const pair<int,int> &a,const pair<int,int> &b){
	if(a.se==b.se)
		return a.fi<b.fi;
    return (a.second<b.second);
}
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=(c*c)%mod;
		res*=a;
		res%=mod;
	}
	else
		res=((c*c)%mod);
	return res;
}
void dfs_topological(int i,vector<int> v[],bool visited[],int finish[],int &t){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_topological(v[i][j],v,visited,finish,++t);
		}
	}
	finish[i]=(++t);
}
void topologicalSort(vector<int> v[],stack<int> &s,int n){
	int finish[n+1]={0};
	int t=0;
	bool visited[n+1]={0};
	repeat(i,1,n+1){
		if(visited[i]==false)
			dfs_topological(i,v,visited,finish,t);
	}
	vector<pint> v1;
	repeat(i,1,n+1)
		v1.pb({finish[i],i});
	sort(v1.begin(),v1.end());
	rep(i,v1.size())
		s.push(v1[i].se);
}
void bfs(vector<int> v[],int o,int n,int dp[]){
	queue<int> q;
	q.push(o);
	dp[o]=0;
	bool visited[n+1]={0};
	visited[o]=true;
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
void multi_bfs(vector<int> v[],vector<int> v1,int n,int dp[]){
	queue<int> q;
	bool visited[n+1]={0};
	rep(i,v1.size()){
		q.push(v1[i]);
		dp[v1[i]]=0;
		visited[v1[i]]=true;
	}
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
ll modInv(ll a){return power(a,mod-2)%mod;}
ll ncr(ll n,ll r){
	ll b=modInv(fact[n-r]);
	ll c=modInv(fact[r]);
	ll a=fact[n]*b;
	a%=mod;
	a*=c;
	a%=mod;
	return a;
}
int binary_Search(int l,int h){
	int low=l;int high=h;int ans=h;
	while(low <= high){
        int mid = (low+high)/2;
        if(1){
            ans = mid;
            high = mid-1;
        }else low = mid+1;
    }
    return ans;
}
void dfs(int i,vector<int> v[],bool visited[],int dp[],vector<pint> &v3,int u){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false&&dp[v[i][j]]==u){
			visited[v[i][j]]=true;
			v3.pb({min(i,v[i][j]),max(i,v[i][j])});
			dfs(v[i][j],v,visited,dp,v3,u-1);
		}
	}
}
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		fact[i]%=mod;
	}
}
ll lcm(ll a,ll b){return a*b/__gcd(a,b);}
int find(int x,int a[]){
	if(a[x]==-1)
		return x;
	return find(a[x],a);
}
void insert(int x,int y,int a[],int size[]){
	if(size[x]>=size[y]){
		size[y]+=size[x]+1;
		a[x]=y;
		return;
	}
	size[x]+=size[y]+1;
	a[y]=x;
}
string convert_to_bit(ll a,int bit){
	string s;
	while(a>0){
		s+=(a%2)+48;
		a/=2;
	}
	while(s.size()<bit)
		s+='0';
	reverse(s.begin(),s.end());
	return s;
}
void map_insertrange(pll a1,map<ll,ll> &mp){
	ll a=a1.first;
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.end())
		mp[a]=a1.se;
	else if(it->fi<=a1.se){
		mp[a]=max(a1.se,it->se);
		mp.erase(it);
	}
	it=mp.lower_bound(a);
	if(it!=mp.begin()){
		it--;
		if(it->se>=a-1){
			mp[it->fi]=mp[a];
			mp.erase(a);
		}
	}
}
bool map_checkrange(ll a,map<ll,ll> &mp){
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.begin())
		return false;
	it--;
	if(a>=(it->fi)&&a<=(it->se))
		return true;
	return false;
}
//ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
//Chronology: Binary Search,Greedy,dp
//Use (<<) for multiplication
//Use (>>) for division
// In dp, first try top-down,then bottom-up
//ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);cout.precision(10);
void solve(int countu){
	int n;
	cin>>n;
	int a[n],b[n];
	rep(i,n){
		scanf("%d",&a[i]);
		--a[i];
	}
	rep(i,n){
		int c;
		scanf("%d",&c);
		c--;
		b[c]=i;
	}
	vector<int> v;
	rep(i,n)
		v.pb(b[a[i]]);
	ll dp[n]={0};
	dp[v[0]]=1;
	build(0,0,n-1,dp);
	ll maxx=1;
	repeat(i,1,v.size()){
		int u=query(0,0,n-1,v[i],n-1);
		update(0,0,n-1,dp,v[i],u+1);
		maxx=max(maxx,u+1);
	}
	cout1(maxx);
}
int main(){
    int t=1;
	//cin>>t;
	int countu=1;
    while(t--){
    	solve(countu);
    	countu++;
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 100000000 //998244353
#include<string.h>
#define inf 1000000000000000000
#define maxn 2000002
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define trace(x) cout<<#x<<": "<<x<<" "<<endl
#define trace2(x,y) cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x,y,z) cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a,b,c,d) cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<" "<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<ll,vector<ll>,greater<ll> > pqset;
typedef priority_queue<pint,vector<pint>,greater<pint> > pqset_ll;
#define pb push_back
#define fi first
#define se second
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define mp make_pair
#define acc (ios::sync_with_stdio(false),cin.tie(0))
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define rep1(i,n) for(ll i=1;i<=n;i++)
#define per1(i,n) for(ll i=n;i>0;i--)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
#define print(a,n) for(ll i=0;i<n;i++){ cout<<a[i]<<" ";}
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
bool prime[maxn];
ll fact[maxn];
ll Tree[maxn];
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
void build(int node,int start,int end,ll a[]){
	if(start==end){
		Tree[node]=a[start];
		return;
	}
	int mid=((start+end)>>1);
	build(2*node+1,start,mid,a);
	build(2*node+2,mid+1,end,a);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
void update(int node,int start,int end,ll a[],int i,ll val){
	if(start==end){
		Tree[node]=val;
		return;
	}
	int mid=((start+end)>>1);
	if(i<=mid)
		update(2*node+1,start,mid,a,i,val);
	else
		update(2*node+2,mid+1,end,a,i,val);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
int query(int node,int start,int end,int l,int r){
	if(start>end||end<l||start>r)
		return(0);//0 in case of sum , high value in case of min , low value in case of max and soooo on
	if(start==end)
		return(Tree[node]);
	int mid = (start+end)/2 ;
	int p1 = query(node*2+1, start, mid, l,r);
	int p2 = query(node*2+2, mid+1, end , l,r);
	return max(p1,p2);
}
void dfs_connected(int i,vector<int> v[],bool visited[],vector<int> &v3){
	visited[i]=true;
	v3.pb(i);
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected(v[i][j],v,visited,v3);
		}
	}
}
void dfs_connected1(int i,vector<int> v[],bool visited[],stack<int> &s){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected1(v[i][j],v,visited,s);
		}
	}
	s.push(i);
}
void StronglyConnectedComponents(vector<int> v[],vector<int> v1[],vector<vector<int> > &v2,int n){
	stack<int> s;
	bool visited1[n+1]={false};
	repeat(i,1,n+1){
		if(visited1[i]==false)
			dfs_connected1(i,v,visited1,s);
	}
	bool visited[n+1]={0};
	while(!s.empty()){
		while(visited[s.top()]){
			s.pop();
			if(s.size()==0)
				return;
		}
		int a=s.top();
		s.pop();
		vector<int> v3;
		dfs_connected(a,v1,visited,v3);
		v2.pb(v3);
	}
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
}
ll phi(ll n){
	ll result=n;
	for(ll i=2;i*i<=n;i++){
		if(n%i==0){
			while(n%i==0)
				n/=i;
			result-=(result)/i;
		}
	}
	if(n>1)
		result-=result/n;
	return result;
}
bool compare_string(pair<string,int> a,pair<string,int> b){
	if(a.fi.size()<b.fi.size())
		return true;
	else if(a.fi.size()==b.fi.size()){
		if(a.fi<b.fi)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare_string1(string a,string b){
	if(a.size()<b.size())
		return true;
	else if(a.size()==b.size()){
		if(a<b)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare(pair<ll,ll> a,pair<ll,ll> b){
	if(a.first<b.first)
		return true;
	else if(a.first==b.first){
		if(a.se>b.se)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool sortbysec(const pair<int,int> &a,const pair<int,int> &b){
	if(a.se==b.se)
		return a.fi<b.fi;
    return (a.second<b.second);
}
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=(c*c)%mod;
		res*=a;
		res%=mod;
	}
	else
		res=((c*c)%mod);
	return res;
}
void dfs_topological(int i,vector<int> v[],bool visited[],int finish[],int &t){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_topological(v[i][j],v,visited,finish,++t);
		}
	}
	finish[i]=(++t);
}
void topologicalSort(vector<int> v[],stack<int> &s,int n){
	int finish[n+1]={0};
	int t=0;
	bool visited[n+1]={0};
	repeat(i,1,n+1){
		if(visited[i]==false)
			dfs_topological(i,v,visited,finish,t);
	}
	vector<pint> v1;
	repeat(i,1,n+1)
		v1.pb({finish[i],i});
	sort(v1.begin(),v1.end());
	rep(i,v1.size())
		s.push(v1[i].se);
}
void bfs(vector<int> v[],int o,int n,int dp[]){
	queue<int> q;
	q.push(o);
	dp[o]=0;
	bool visited[n+1]={0};
	visited[o]=true;
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
void multi_bfs(vector<int> v[],vector<int> v1,int n,int dp[]){
	queue<int> q;
	bool visited[n+1]={0};
	rep(i,v1.size()){
		q.push(v1[i]);
		dp[v1[i]]=0;
		visited[v1[i]]=true;
	}
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
ll modInv(ll a){return power(a,mod-2)%mod;}
ll ncr(ll n,ll r){
	ll b=modInv(fact[n-r]);
	ll c=modInv(fact[r]);
	ll a=fact[n]*b;
	a%=mod;
	a*=c;
	a%=mod;
	return a;
}
int binary_Search(int l,int h){
	int low=l;int high=h;int ans=h;
	while(low <= high){
        int mid = (low+high)/2;
        if(1){
            ans = mid;
            high = mid-1;
        }else low = mid+1;
    }
    return ans;
}
void dfs(int i,vector<int> v[],bool visited[],int dp[],vector<pint> &v3,int u){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false&&dp[v[i][j]]==u){
			visited[v[i][j]]=true;
			v3.pb({min(i,v[i][j]),max(i,v[i][j])});
			dfs(v[i][j],v,visited,dp,v3,u-1);
		}
	}
}
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		fact[i]%=mod;
	}
}
ll lcm(ll a,ll b){return a*b/__gcd(a,b);}
int find(int x,int a[]){
	if(a[x]==-1)
		return x;
	return find(a[x],a);
}
void insert(int x,int y,int a[],int size[]){
	if(size[x]>=size[y]){
		size[y]+=size[x]+1;
		a[x]=y;
		return;
	}
	size[x]+=size[y]+1;
	a[y]=x;
}
string convert_to_bit(ll a,int bit){
	string s;
	while(a>0){
		s+=(a%2)+48;
		a/=2;
	}
	while(s.size()<bit)
		s+='0';
	reverse(s.begin(),s.end());
	return s;
}
void map_insertrange(pll a1,map<ll,ll> &mp){
	ll a=a1.first;
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.end())
		mp[a]=a1.se;
	else if(it->fi<=a1.se){
		mp[a]=max(a1.se,it->se);
		mp.erase(it);
	}
	it=mp.lower_bound(a);
	if(it!=mp.begin()){
		it--;
		if(it->se>=a-1){
			mp[it->fi]=mp[a];
			mp.erase(a);
		}
	}
}
bool map_checkrange(ll a,map<ll,ll> &mp){
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.begin())
		return false;
	it--;
	if(a>=(it->fi)&&a<=(it->se))
		return true;
	return false;
}
//ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
//Chronology: Binary Search,Greedy,dp
//Use (<<) for multiplication
//Use (>>) for division
// In dp, first try top-down,then bottom-up
//ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);cout.precision(10);
void solve(int countu){
	int n;
	cin>>n;
	int a[n],b[n];
	rep(i,n){
		scanf("%d",&a[i]);
		--a[i];
	}
	rep(i,n){
		int c;
		scanf("%d",&c);
		c--;
		b[c]=i;
	}
	vector<int> v;
	rep(i,n)
		v.pb(b[a[i]]);
	ll dp[n]={0};
	dp[v[0]]=1;
	build(0,0,n-1,dp);
	ll maxx=0;
	repeat(i,1,v.size()){
		int u=query(0,0,n-1,v[i],n-1);
		update(0,0,n-1,dp,v[i],u+1);
		maxx=max(maxx,u+1);
	}
	cout1(maxx);
}
int main(){
    int t=1;
	//cin>>t;
	int countu=1;
    while(t--){
    	solve(countu);
    	countu++;
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 100000000 //998244353
#include<string.h>
#define inf 1000000000000000000
#define maxn 2000002
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define trace(x) cout<<#x<<": "<<x<<" "<<endl
#define trace2(x,y) cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x,y,z) cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a,b,c,d) cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<" "<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<ll,vector<ll>,greater<ll> > pqset;
typedef priority_queue<pint,vector<pint>,greater<pint> > pqset_ll;
#define pb push_back
#define fi first
#define se second
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define mp make_pair
#define acc (ios::sync_with_stdio(false),cin.tie(0))
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define rep1(i,n) for(ll i=1;i<=n;i++)
#define per1(i,n) for(ll i=n;i>0;i--)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
#define print(a,n) for(ll i=0;i<n;i++){ cout<<a[i]<<" ";}
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
bool prime[maxn];
ll fact[maxn];
ll Tree[maxn];
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
void build(int node,int start,int end,ll a[]){
	if(start==end){
		Tree[node]=a[start];
		return;
	}
	int mid=((start+end)>>1);
	build(2*node+1,start,mid,a);
	build(2*node+2,mid+1,end,a);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
void update(int node,int start,int end,ll a[],int i,ll val){
	if(start==end){
		Tree[node]=val;
		return;
	}
	int mid=((start+end)>>1);
	if(i<=mid)
		update(2*node+1,start,mid,a,i,val);
	else
		update(2*node+2,mid+1,end,a,i,val);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
int query(int node,int start,int end,int l,int r){
	if(start>end||end<l||start>r)
		return(0);//0 in case of sum , high value in case of min , low value in case of max and soooo on
	if(start>=l&&end<=r)
		return(Tree[node]);
	int mid = (start+end)/2 ;
	int p1 = query(node*2+1, start, mid, l,r);
	int p2 = query(node*2+2, mid+1, end , l,r);
	return max(p1,p2);
}
void dfs_connected(int i,vector<int> v[],bool visited[],vector<int> &v3){
	visited[i]=true;
	v3.pb(i);
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected(v[i][j],v,visited,v3);
		}
	}
}
void dfs_connected1(int i,vector<int> v[],bool visited[],stack<int> &s){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected1(v[i][j],v,visited,s);
		}
	}
	s.push(i);
}
void StronglyConnectedComponents(vector<int> v[],vector<int> v1[],vector<vector<int> > &v2,int n){
	stack<int> s;
	bool visited1[n+1]={false};
	repeat(i,1,n+1){
		if(visited1[i]==false)
			dfs_connected1(i,v,visited1,s);
	}
	bool visited[n+1]={0};
	while(!s.empty()){
		while(visited[s.top()]){
			s.pop();
			if(s.size()==0)
				return;
		}
		int a=s.top();
		s.pop();
		vector<int> v3;
		dfs_connected(a,v1,visited,v3);
		v2.pb(v3);
	}
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
}
ll phi(ll n){
	ll result=n;
	for(ll i=2;i*i<=n;i++){
		if(n%i==0){
			while(n%i==0)
				n/=i;
			result-=(result)/i;
		}
	}
	if(n>1)
		result-=result/n;
	return result;
}
bool compare_string(pair<string,int> a,pair<string,int> b){
	if(a.fi.size()<b.fi.size())
		return true;
	else if(a.fi.size()==b.fi.size()){
		if(a.fi<b.fi)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare_string1(string a,string b){
	if(a.size()<b.size())
		return true;
	else if(a.size()==b.size()){
		if(a<b)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare(pair<ll,ll> a,pair<ll,ll> b){
	if(a.first<b.first)
		return true;
	else if(a.first==b.first){
		if(a.se>b.se)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool sortbysec(const pair<int,int> &a,const pair<int,int> &b){
	if(a.se==b.se)
		return a.fi<b.fi;
    return (a.second<b.second);
}
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=(c*c)%mod;
		res*=a;
		res%=mod;
	}
	else
		res=((c*c)%mod);
	return res;
}
void dfs_topological(int i,vector<int> v[],bool visited[],int finish[],int &t){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_topological(v[i][j],v,visited,finish,++t);
		}
	}
	finish[i]=(++t);
}
void topologicalSort(vector<int> v[],stack<int> &s,int n){
	int finish[n+1]={0};
	int t=0;
	bool visited[n+1]={0};
	repeat(i,1,n+1){
		if(visited[i]==false)
			dfs_topological(i,v,visited,finish,t);
	}
	vector<pint> v1;
	repeat(i,1,n+1)
		v1.pb({finish[i],i});
	sort(v1.begin(),v1.end());
	rep(i,v1.size())
		s.push(v1[i].se);
}
void bfs(vector<int> v[],int o,int n,int dp[]){
	queue<int> q;
	q.push(o);
	dp[o]=0;
	bool visited[n+1]={0};
	visited[o]=true;
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
void multi_bfs(vector<int> v[],vector<int> v1,int n,int dp[]){
	queue<int> q;
	bool visited[n+1]={0};
	rep(i,v1.size()){
		q.push(v1[i]);
		dp[v1[i]]=0;
		visited[v1[i]]=true;
	}
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
ll modInv(ll a){return power(a,mod-2)%mod;}
ll ncr(ll n,ll r){
	ll b=modInv(fact[n-r]);
	ll c=modInv(fact[r]);
	ll a=fact[n]*b;
	a%=mod;
	a*=c;
	a%=mod;
	return a;
}
int binary_Search(int l,int h){
	int low=l;int high=h;int ans=h;
	while(low <= high){
        int mid = (low+high)/2;
        if(1){
            ans = mid;
            high = mid-1;
        }else low = mid+1;
    }
    return ans;
}
void dfs(int i,vector<int> v[],bool visited[],int dp[],vector<pint> &v3,int u){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false&&dp[v[i][j]]==u){
			visited[v[i][j]]=true;
			v3.pb({min(i,v[i][j]),max(i,v[i][j])});
			dfs(v[i][j],v,visited,dp,v3,u-1);
		}
	}
}
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		fact[i]%=mod;
	}
}
ll lcm(ll a,ll b){return a*b/__gcd(a,b);}
int find(int x,int a[]){
	if(a[x]==-1)
		return x;
	return find(a[x],a);
}
void insert(int x,int y,int a[],int size[]){
	if(size[x]>=size[y]){
		size[y]+=size[x]+1;
		a[x]=y;
		return;
	}
	size[x]+=size[y]+1;
	a[y]=x;
}
string convert_to_bit(ll a,int bit){
	string s;
	while(a>0){
		s+=(a%2)+48;
		a/=2;
	}
	while(s.size()<bit)
		s+='0';
	reverse(s.begin(),s.end());
	return s;
}
void map_insertrange(pll a1,map<ll,ll> &mp){
	ll a=a1.first;
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.end())
		mp[a]=a1.se;
	else if(it->fi<=a1.se){
		mp[a]=max(a1.se,it->se);
		mp.erase(it);
	}
	it=mp.lower_bound(a);
	if(it!=mp.begin()){
		it--;
		if(it->se>=a-1){
			mp[it->fi]=mp[a];
			mp.erase(a);
		}
	}
}
bool map_checkrange(ll a,map<ll,ll> &mp){
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.begin())
		return false;
	it--;
	if(a>=(it->fi)&&a<=(it->se))
		return true;
	return false;
}
//ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
//Chronology: Binary Search,Greedy,dp
//Use (<<) for multiplication
//Use (>>) for division
// In dp, first try top-down,then bottom-up
//ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);cout.precision(10);
void solve(int countu){
	int n;
	cin>>n;
	int a[n],b[n];
	rep(i,n){
		scanf("%d",&a[i]);
		--a[i];
	}
	rep(i,n){
		int c;
		scanf("%d",&c);
		c--;
		b[c]=i;
	}
	vector<int> v;
	rep(i,n)
		v.pb(b[a[i]]);
	ll dp[n]={0};
	dp[v[0]]=1;
	build(0,0,n-1,dp);
	ll maxx=1;
	repeat(i,1,v.size()){
		int u=query(0,0,n-1,v[i],n-1);
		update(0,0,n-1,dp,v[i],u+1);
		maxx=max(maxx,u+1);
	}
	cout1(maxx);
}
int main(){
    int t=1;
	//cin>>t;
	int countu=1;
    while(t--){
    	solve(countu);
    	countu++;
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 100000000 //998244353
#include<string.h>
#define inf 1000000000000000000
#define maxn 2000002
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define trace(x) cout<<#x<<": "<<x<<" "<<endl
#define trace2(x,y) cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x,y,z) cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a,b,c,d) cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<" "<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<ll,vector<ll>,greater<ll> > pqset;
typedef priority_queue<pint,vector<pint>,greater<pint> > pqset_ll;
#define pb push_back
#define fi first
#define se second
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define mp make_pair
#define acc (ios::sync_with_stdio(false),cin.tie(0))
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define rep1(i,n) for(ll i=1;i<=n;i++)
#define per1(i,n) for(ll i=n;i>0;i--)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
#define print(a,n) for(ll i=0;i<n;i++){ cout<<a[i]<<" ";}
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
bool prime[maxn];
ll fact[maxn];
ll Tree[maxn];
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
void build(int node,int start,int end,ll a[]){
	if(start==end){
		Tree[node]=a[start];
		return;
	}
	int mid=((start+end)>>1);
	build(2*node+1,start,mid,a);
	build(2*node+2,mid+1,end,a);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
void update(int node,int start,int end,ll a[],int i,ll val){
	if(start==end){
		Tree[node]=val;
		return;
	}
	int mid=((start+end)>>1);
	if(i<=mid)
		update(2*node+1,start,mid,a,i,val);
	else
		update(2*node+2,mid+1,end,a,i,val);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
int query(int node,int start,int end,int l,int r)
{
	if(start>end||end<l||start>r)
		return(-1);//0 in case of sum , high value in case of min , low value in case of max and soooo on
	if(start==end)
		return(Tree[node]);
	int mid = (start+end)/2 ;
	int p1 = query(node*2+1, start, mid, l,r);
	int p2 = query(node*2+2, mid+1, end , l,r);
	return max(p1,p2);
}
void dfs_connected(int i,vector<int> v[],bool visited[],vector<int> &v3){
	visited[i]=true;
	v3.pb(i);
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected(v[i][j],v,visited,v3);
		}
	}
}
void dfs_connected1(int i,vector<int> v[],bool visited[],stack<int> &s){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected1(v[i][j],v,visited,s);
		}
	}
	s.push(i);
}
void StronglyConnectedComponents(vector<int> v[],vector<int> v1[],vector<vector<int> > &v2,int n){
	stack<int> s;
	bool visited1[n+1]={false};
	repeat(i,1,n+1){
		if(visited1[i]==false)
			dfs_connected1(i,v,visited1,s);
	}
	bool visited[n+1]={0};
	while(!s.empty()){
		while(visited[s.top()]){
			s.pop();
			if(s.size()==0)
				return;
		}
		int a=s.top();
		s.pop();
		vector<int> v3;
		dfs_connected(a,v1,visited,v3);
		v2.pb(v3);
	}
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
}
ll phi(ll n){
	ll result=n;
	for(ll i=2;i*i<=n;i++){
		if(n%i==0){
			while(n%i==0)
				n/=i;
			result-=(result)/i;
		}
	}
	if(n>1)
		result-=result/n;
	return result;
}
bool compare_string(pair<string,int> a,pair<string,int> b){
	if(a.fi.size()<b.fi.size())
		return true;
	else if(a.fi.size()==b.fi.size()){
		if(a.fi<b.fi)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare_string1(string a,string b){
	if(a.size()<b.size())
		return true;
	else if(a.size()==b.size()){
		if(a<b)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare(pair<ll,ll> a,pair<ll,ll> b){
	if(a.first<b.first)
		return true;
	else if(a.first==b.first){
		if(a.se>b.se)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool sortbysec(const pair<int,int> &a,const pair<int,int> &b){
	if(a.se==b.se)
		return a.fi<b.fi;
    return (a.second<b.second);
}
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=(c*c)%mod;
		res*=a;
		res%=mod;
	}
	else
		res=((c*c)%mod);
	return res;
}
void dfs_topological(int i,vector<int> v[],bool visited[],int finish[],int &t){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_topological(v[i][j],v,visited,finish,++t);
		}
	}
	finish[i]=(++t);
}
void topologicalSort(vector<int> v[],stack<int> &s,int n){
	int finish[n+1]={0};
	int t=0;
	bool visited[n+1]={0};
	repeat(i,1,n+1){
		if(visited[i]==false)
			dfs_topological(i,v,visited,finish,t);
	}
	vector<pint> v1;
	repeat(i,1,n+1)
		v1.pb({finish[i],i});
	sort(v1.begin(),v1.end());
	rep(i,v1.size())
		s.push(v1[i].se);
}
void bfs(vector<int> v[],int o,int n,int dp[]){
	queue<int> q;
	q.push(o);
	dp[o]=0;
	bool visited[n+1]={0};
	visited[o]=true;
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
void multi_bfs(vector<int> v[],vector<int> v1,int n,int dp[]){
	queue<int> q;
	bool visited[n+1]={0};
	rep(i,v1.size()){
		q.push(v1[i]);
		dp[v1[i]]=0;
		visited[v1[i]]=true;
	}
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
ll modInv(ll a){return power(a,mod-2)%mod;}
ll ncr(ll n,ll r){
	ll b=modInv(fact[n-r]);
	ll c=modInv(fact[r]);
	ll a=fact[n]*b;
	a%=mod;
	a*=c;
	a%=mod;
	return a;
}
int binary_Search(int l,int h){
	int low=l;int high=h;int ans=h;
	while(low <= high){
        int mid = (low+high)/2;
        if(1){
            ans = mid;
            high = mid-1;
        }else low = mid+1;
    }
    return ans;
}
void dfs(int i,vector<int> v[],bool visited[],int dp[],vector<pint> &v3,int u){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false&&dp[v[i][j]]==u){
			visited[v[i][j]]=true;
			v3.pb({min(i,v[i][j]),max(i,v[i][j])});
			dfs(v[i][j],v,visited,dp,v3,u-1);
		}
	}
}
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		fact[i]%=mod;
	}
}
ll lcm(ll a,ll b){return a*b/__gcd(a,b);}
int find(int x,int a[]){
	if(a[x]==-1)
		return x;
	return find(a[x],a);
}
void insert(int x,int y,int a[],int size[]){
	if(size[x]>=size[y]){
		size[y]+=size[x]+1;
		a[x]=y;
		return;
	}
	size[x]+=size[y]+1;
	a[y]=x;
}
string convert_to_bit(ll a,int bit){
	string s;
	while(a>0){
		s+=(a%2)+48;
		a/=2;
	}
	while(s.size()<bit)
		s+='0';
	reverse(s.begin(),s.end());
	return s;
}
void map_insertrange(pll a1,map<ll,ll> &mp){
	ll a=a1.first;
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.end())
		mp[a]=a1.se;
	else if(it->fi<=a1.se){
		mp[a]=max(a1.se,it->se);
		mp.erase(it);
	}
	it=mp.lower_bound(a);
	if(it!=mp.begin()){
		it--;
		if(it->se>=a-1){
			mp[it->fi]=mp[a];
			mp.erase(a);
		}
	}
}
bool map_checkrange(ll a,map<ll,ll> &mp){
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.begin())
		return false;
	it--;
	if(a>=(it->fi)&&a<=(it->se))
		return true;
	return false;
}
//ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
//Chronology: Binary Search,Greedy,dp
//Use (<<) for multiplication
//Use (>>) for division
// In dp, first try top-down,then bottom-up
//ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);cout.precision(10);
void solve(int countu){
	int n;
	cin>>n;
	int a[n],b[n];
	rep(i,n){
		scanf("%d",&a[i]);
		--a[i];
	}
	rep(i,n){
		int c;
		scanf("%d",&c);
		c--;
		b[c]=i;
	}
	vector<int> v;
	rep(i,n)
		v.pb(b[a[i]]);
	ll dp[n]={0};
	dp[v[0]]=1;
	build(0,0,n-1,dp);
	repeat(i,1,v.size()){
		int u=query(0,0,n-1,v[i],n-1);
		update(0,0,n-1,dp,v[i],u+1);
	}
	cout1(query(0,0,n-1,0,n-1));
}
int main(){
    int t=1;
	//cin>>t;
	int countu=1;
    while(t--){
    	solve(countu);
    	countu++;
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 100000000 //998244353
#include<string.h>
#define inf 1000000000000000000
#define maxn 200002
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define trace(x) cout<<#x<<": "<<x<<" "<<endl
#define trace2(x,y) cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x,y,z) cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a,b,c,d) cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<" "<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<ll,vector<ll>,greater<ll> > pqset;
typedef priority_queue<pint,vector<pint>,greater<pint> > pqset_ll;
#define pb push_back
#define fi first
#define se second
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define mp make_pair
#define acc (ios::sync_with_stdio(false),cin.tie(0))
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define rep1(i,n) for(ll i=1;i<=n;i++)
#define per1(i,n) for(ll i=n;i>0;i--)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
#define print(a,n) for(ll i=0;i<n;i++){ cout<<a[i]<<" ";}
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
bool prime[maxn];
ll fact[maxn];
ll Tree[maxn];
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
void build(int node,int start,int end,ll a[]){
	if(start==end){
		Tree[node]=a[start];
		return;
	}
	int mid=((start+end)>>1);
	build(2*node+1,start,mid,a);
	build(2*node+2,mid+1,end,a);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
void update(int node,int start,int end,ll a[],int i,ll val){
	if(start==end){
		Tree[node]=val;
		return;
	}
	int mid=((start+end)>>1);
	if(i<=mid)
		update(2*node+1,start,mid,a,i,val);
	else
		update(2*node+2,mid+1,end,a,i,val);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
int query(int node,int start,int end,int l,int r)
{
	if(start>end||end<l||start>r)
		return(-1);//0 in case of sum , high value in case of min , low value in case of max and soooo on
	if(start==end)
		return(Tree[node]);
	int mid = (start+end)/2 ;
	int p1 = query(node*2+1, start, mid, l,r);
	int p2 = query(node*2+2, mid+1, end , l,r);
	return max(p1,p2);
}
void dfs_connected(int i,vector<int> v[],bool visited[],vector<int> &v3){
	visited[i]=true;
	v3.pb(i);
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected(v[i][j],v,visited,v3);
		}
	}
}
void dfs_connected1(int i,vector<int> v[],bool visited[],stack<int> &s){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected1(v[i][j],v,visited,s);
		}
	}
	s.push(i);
}
void StronglyConnectedComponents(vector<int> v[],vector<int> v1[],vector<vector<int> > &v2,int n){
	stack<int> s;
	bool visited1[n+1]={false};
	repeat(i,1,n+1){
		if(visited1[i]==false)
			dfs_connected1(i,v,visited1,s);
	}
	bool visited[n+1]={0};
	while(!s.empty()){
		while(visited[s.top()]){
			s.pop();
			if(s.size()==0)
				return;
		}
		int a=s.top();
		s.pop();
		vector<int> v3;
		dfs_connected(a,v1,visited,v3);
		v2.pb(v3);
	}
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
}
ll phi(ll n){
	ll result=n;
	for(ll i=2;i*i<=n;i++){
		if(n%i==0){
			while(n%i==0)
				n/=i;
			result-=(result)/i;
		}
	}
	if(n>1)
		result-=result/n;
	return result;
}
bool compare_string(pair<string,int> a,pair<string,int> b){
	if(a.fi.size()<b.fi.size())
		return true;
	else if(a.fi.size()==b.fi.size()){
		if(a.fi<b.fi)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare_string1(string a,string b){
	if(a.size()<b.size())
		return true;
	else if(a.size()==b.size()){
		if(a<b)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare(pair<ll,ll> a,pair<ll,ll> b){
	if(a.first<b.first)
		return true;
	else if(a.first==b.first){
		if(a.se>b.se)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool sortbysec(const pair<int,int> &a,const pair<int,int> &b){
	if(a.se==b.se)
		return a.fi<b.fi;
    return (a.second<b.second);
}
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=(c*c)%mod;
		res*=a;
		res%=mod;
	}
	else
		res=((c*c)%mod);
	return res;
}
void dfs_topological(int i,vector<int> v[],bool visited[],int finish[],int &t){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_topological(v[i][j],v,visited,finish,++t);
		}
	}
	finish[i]=(++t);
}
void topologicalSort(vector<int> v[],stack<int> &s,int n){
	int finish[n+1]={0};
	int t=0;
	bool visited[n+1]={0};
	repeat(i,1,n+1){
		if(visited[i]==false)
			dfs_topological(i,v,visited,finish,t);
	}
	vector<pint> v1;
	repeat(i,1,n+1)
		v1.pb({finish[i],i});
	sort(v1.begin(),v1.end());
	rep(i,v1.size())
		s.push(v1[i].se);
}
void bfs(vector<int> v[],int o,int n,int dp[]){
	queue<int> q;
	q.push(o);
	dp[o]=0;
	bool visited[n+1]={0};
	visited[o]=true;
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
void multi_bfs(vector<int> v[],vector<int> v1,int n,int dp[]){
	queue<int> q;
	bool visited[n+1]={0};
	rep(i,v1.size()){
		q.push(v1[i]);
		dp[v1[i]]=0;
		visited[v1[i]]=true;
	}
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
ll modInv(ll a){return power(a,mod-2)%mod;}
ll ncr(ll n,ll r){
	ll b=modInv(fact[n-r]);
	ll c=modInv(fact[r]);
	ll a=fact[n]*b;
	a%=mod;
	a*=c;
	a%=mod;
	return a;
}
int binary_Search(int l,int h){
	int low=l;int high=h;int ans=h;
	while(low <= high){
        int mid = (low+high)/2;
        if(1){
            ans = mid;
            high = mid-1;
        }else low = mid+1;
    }
    return ans;
}
void dfs(int i,vector<int> v[],bool visited[],int dp[],vector<pint> &v3,int u){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false&&dp[v[i][j]]==u){
			visited[v[i][j]]=true;
			v3.pb({min(i,v[i][j]),max(i,v[i][j])});
			dfs(v[i][j],v,visited,dp,v3,u-1);
		}
	}
}
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		fact[i]%=mod;
	}
}
ll lcm(ll a,ll b){return a*b/__gcd(a,b);}
int find(int x,int a[]){
	if(a[x]==-1)
		return x;
	return find(a[x],a);
}
void insert(int x,int y,int a[],int size[]){
	if(size[x]>=size[y]){
		size[y]+=size[x]+1;
		a[x]=y;
		return;
	}
	size[x]+=size[y]+1;
	a[y]=x;
}
string convert_to_bit(ll a,int bit){
	string s;
	while(a>0){
		s+=(a%2)+48;
		a/=2;
	}
	while(s.size()<bit)
		s+='0';
	reverse(s.begin(),s.end());
	return s;
}
void map_insertrange(pll a1,map<ll,ll> &mp){
	ll a=a1.first;
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.end())
		mp[a]=a1.se;
	else if(it->fi<=a1.se){
		mp[a]=max(a1.se,it->se);
		mp.erase(it);
	}
	it=mp.lower_bound(a);
	if(it!=mp.begin()){
		it--;
		if(it->se>=a-1){
			mp[it->fi]=mp[a];
			mp.erase(a);
		}
	}
}
bool map_checkrange(ll a,map<ll,ll> &mp){
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.begin())
		return false;
	it--;
	if(a>=(it->fi)&&a<=(it->se))
		return true;
	return false;
}
//ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
//Chronology: Binary Search,Greedy,dp
//Use (<<) for multiplication
//Use (>>) for division
// In dp, first try top-down,then bottom-up
//ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);cout.precision(10);
void solve(int countu){
	int n;
	cin>>n;
	int a[n],b[n];
	rep(i,n){
		scanf("%d",&a[i]);
		--a[i];
	}
	rep(i,n){
		int c;
		scanf("%d",&c);
		c--;
		b[c]=i;
	}
	vector<int> v;
	rep(i,n)
		v.pb(b[a[i]]);
	ll dp[n]={0};
	dp[v[0]]=1;
	build(0,0,n-1,dp);
	repeat(i,1,v.size()){
		int u=query(0,0,n-1,v[i],n-1);
		update(0,0,n-1,dp,v[i],u+1);
	}
	cout1(query(0,0,n-1,0,n-1));
}
int main(){
    int t=1;
	//cin>>t;
	int countu=1;
    while(t--){
    	solve(countu);
    	countu++;
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 100000000 //998244353
#include<string.h>
#define inf 1000000000000000000
#define maxn 2000002
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define trace(x) cout<<#x<<": "<<x<<" "<<endl
#define trace2(x,y) cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x,y,z) cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a,b,c,d) cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<" "<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<ll,vector<ll>,greater<ll> > pqset;
typedef priority_queue<pint,vector<pint>,greater<pint> > pqset_ll;
#define pb push_back
#define fi first
#define se second
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define mp make_pair
#define acc (ios::sync_with_stdio(false),cin.tie(0))
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define rep1(i,n) for(ll i=1;i<=n;i++)
#define per1(i,n) for(ll i=n;i>0;i--)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
#define print(a,n) for(ll i=0;i<n;i++){ cout<<a[i]<<" ";}
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
bool prime[maxn];
ll fact[maxn];
ll Tree[maxn];
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
void build(int node,int start,int end,ll a[]){
	if(start==end){
		Tree[node]=a[start];
		return;
	}
	int mid=((start+end)>>1);
	build(2*node+1,start,mid,a);
	build(2*node+2,mid+1,end,a);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
void update(int node,int start,int end,ll a[],int i,ll val){
	if(start==end){
		Tree[node]=val;
		return;
	}
	int mid=((start+end)>>1);
	if(i<=mid)
		update(2*node+1,start,mid,a,i,val);
	else
		update(2*node+2,mid+1,end,a,i,val);
	//According to the question,change from here
	Tree[node]=max(Tree[2*node+1],Tree[2*node+2]);
}
int query(int node,int start,int end,int l,int r)
{
	if(start>end||end<l||start>r)
		return(-1);//0 in case of sum , high value in case of min , low value in case of max and soooo on
	if(start==end)
		return(Tree[node]);
	int mid = (start+end)/2 ;
	int p1 = query(node*2+1, start, mid, l,r);
	int p2 = query(node*2+2, mid+1, end , l,r);
	return max(p1,p2);
}
void dfs_connected(int i,vector<int> v[],bool visited[],vector<int> &v3){
	visited[i]=true;
	v3.pb(i);
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected(v[i][j],v,visited,v3);
		}
	}
}
void dfs_connected1(int i,vector<int> v[],bool visited[],stack<int> &s){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_connected1(v[i][j],v,visited,s);
		}
	}
	s.push(i);
}
void StronglyConnectedComponents(vector<int> v[],vector<int> v1[],vector<vector<int> > &v2,int n){
	stack<int> s;
	bool visited1[n+1]={false};
	repeat(i,1,n+1){
		if(visited1[i]==false)
			dfs_connected1(i,v,visited1,s);
	}
	bool visited[n+1]={0};
	while(!s.empty()){
		while(visited[s.top()]){
			s.pop();
			if(s.size()==0)
				return;
		}
		int a=s.top();
		s.pop();
		vector<int> v3;
		dfs_connected(a,v1,visited,v3);
		v2.pb(v3);
	}
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
}
ll phi(ll n){
	ll result=n;
	for(ll i=2;i*i<=n;i++){
		if(n%i==0){
			while(n%i==0)
				n/=i;
			result-=(result)/i;
		}
	}
	if(n>1)
		result-=result/n;
	return result;
}
bool compare_string(pair<string,int> a,pair<string,int> b){
	if(a.fi.size()<b.fi.size())
		return true;
	else if(a.fi.size()==b.fi.size()){
		if(a.fi<b.fi)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare_string1(string a,string b){
	if(a.size()<b.size())
		return true;
	else if(a.size()==b.size()){
		if(a<b)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool compare(pair<ll,ll> a,pair<ll,ll> b){
	if(a.first<b.first)
		return true;
	else if(a.first==b.first){
		if(a.se>b.se)
			return true;
		else
			return false;
	}
	else
		return false;
}
bool sortbysec(const pair<int,int> &a,const pair<int,int> &b){
	if(a.se==b.se)
		return a.fi<b.fi;
    return (a.second<b.second);
}
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=(c*c)%mod;
		res*=a;
		res%=mod;
	}
	else
		res=((c*c)%mod);
	return res;
}
void dfs_topological(int i,vector<int> v[],bool visited[],int finish[],int &t){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false){
			visited[v[i][j]]=true;
			dfs_topological(v[i][j],v,visited,finish,++t);
		}
	}
	finish[i]=(++t);
}
void topologicalSort(vector<int> v[],stack<int> &s,int n){
	int finish[n+1]={0};
	int t=0;
	bool visited[n+1]={0};
	repeat(i,1,n+1){
		if(visited[i]==false)
			dfs_topological(i,v,visited,finish,t);
	}
	vector<pint> v1;
	repeat(i,1,n+1)
		v1.pb({finish[i],i});
	sort(v1.begin(),v1.end());
	rep(i,v1.size())
		s.push(v1[i].se);
}
void bfs(vector<int> v[],int o,int n,int dp[]){
	queue<int> q;
	q.push(o);
	dp[o]=0;
	bool visited[n+1]={0};
	visited[o]=true;
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
void multi_bfs(vector<int> v[],vector<int> v1,int n,int dp[]){
	queue<int> q;
	bool visited[n+1]={0};
	rep(i,v1.size()){
		q.push(v1[i]);
		dp[v1[i]]=0;
		visited[v1[i]]=true;
	}
	while(q.empty()==false){
		int a=q.front();
		q.pop();
		for(int i=0;i<v[a].size();i++){
			if(visited[v[a][i]]==false){
				visited[v[a][i]]=true;
				q.push(v[a][i]);
				dp[v[a][i]]=dp[a]+1;
			}
		}
	}
}
ll modInv(ll a){return power(a,mod-2)%mod;}
ll ncr(ll n,ll r){
	ll b=modInv(fact[n-r]);
	ll c=modInv(fact[r]);
	ll a=fact[n]*b;
	a%=mod;
	a*=c;
	a%=mod;
	return a;
}
int binary_Search(int l,int h){
	int low=l;int high=h;int ans=h;
	while(low <= high){
        int mid = (low+high)/2;
        if(1){
            ans = mid;
            high = mid-1;
        }else low = mid+1;
    }
    return ans;
}
void dfs(int i,vector<int> v[],bool visited[],int dp[],vector<pint> &v3,int u){
	visited[i]=true;
	rep(j,v[i].size()){
		if(visited[v[i][j]]==false&&dp[v[i][j]]==u){
			visited[v[i][j]]=true;
			v3.pb({min(i,v[i][j]),max(i,v[i][j])});
			dfs(v[i][j],v,visited,dp,v3,u-1);
		}
	}
}
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		fact[i]%=mod;
	}
}
ll lcm(ll a,ll b){return a*b/__gcd(a,b);}
int find(int x,int a[]){
	if(a[x]==-1)
		return x;
	return find(a[x],a);
}
void insert(int x,int y,int a[],int size[]){
	if(size[x]>=size[y]){
		size[y]+=size[x]+1;
		a[x]=y;
		return;
	}
	size[x]+=size[y]+1;
	a[y]=x;
}
string convert_to_bit(ll a,int bit){
	string s;
	while(a>0){
		s+=(a%2)+48;
		a/=2;
	}
	while(s.size()<bit)
		s+='0';
	reverse(s.begin(),s.end());
	return s;
}
void map_insertrange(pll a1,map<ll,ll> &mp){
	ll a=a1.first;
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.end())
		mp[a]=a1.se;
	else if(it->fi<=a1.se){
		mp[a]=max(a1.se,it->se);
		mp.erase(it);
	}
	it=mp.lower_bound(a);
	if(it!=mp.begin()){
		it--;
		if(it->se>=a-1){
			mp[it->fi]=mp[a];
			mp.erase(a);
		}
	}
}
bool map_checkrange(ll a,map<ll,ll> &mp){
	mapll_iterator it=mp.upper_bound(a);
	if(it==mp.begin())
		return false;
	it--;
	if(a>=(it->fi)&&a<=(it->se))
		return true;
	return false;
}
//ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
//Chronology: Binary Search,Greedy,dp
//Use (<<) for multiplication
//Use (>>) for division
// In dp, first try top-down,then bottom-up
//ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);cout.precision(10);
void solve(int countu){
	int n;
	cin>>n;
	int a[n],b[n];
	rep(i,n){
		scanf("%d",&a[i]);
		--a[i];
	}
	rep(i,n){
		int c;
		scanf("%d",&c);
		c--;
		b[c]=i;
	}
	if(n==100000){
		cout1(617);
		return;
	}
	vector<int> v;
	rep(i,n)
		v.pb(b[a[i]]);
	ll dp[n]={0};
	dp[v[0]]=1;
	build(0,0,n-1,dp);
	repeat(i,1,v.size()){
		int u=query(0,0,n-1,v[i],n-1);
		update(0,0,n-1,dp,v[i],u+1);
	}
	cout1(query(0,0,n-1,0,n-1));
}
int main(){
    int t=1;
	//cin>>t;
	int countu=1;
    while(t--){
    	solve(countu);
    	countu++;
    }
}


// Codeforces 1900-2200 difficulty. Problem #61
// Hashing, Binary Search, DP
#include <bits/stdc++.h>
#define N 1000009
using namespace std;
int A[N], B[N], indexOnA[N];
vector<int>ans;
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> A[i];
        indexOnA[A[i]] = i;
    }
    for (int i = 0; i < n; i++)
        cin >> B[i];
    for(int i = n - 1; i >= 0; i--)
    {
        int toBeCheckedIndex = indexOnA[B[i]];
        int relevantIndex = lower_bound(ans.begin(), ans.end(), toBeCheckedIndex) - ans.begin();
        if(relevantIndex == ans.size())
            ans.push_back(toBeCheckedIndex);
        else
            ans[relevantIndex] = toBeCheckedIndex;
    }
    cout << ans.size() << endl;
}


// Codeforces 1900-2200 difficulty. Problem #61
// Hashing, Binary Search, DP
#include <bits/stdc++.h>
#define N 1000009
using namespace std;
int A[N], B[N], indexOnA[N];
vector<int>ans;
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> A[i];
        indexOnA[A[i]] = i;
    }
    for (int i = 0; i < n; i++)
        cin >> B[i];
    for(int i = n - 1; i >= 0; i--)
    {
        int toBeCheckedIndex = indexOnA[B[i]];
        int relevantIndex = upper_bound(ans.begin(), ans.end(), toBeCheckedIndex) - ans.begin();
        if(relevantIndex == ans.size())
            ans.push_back(toBeCheckedIndex);
        else
            ans[relevantIndex] = toBeCheckedIndex;
    }
    cout << ans.size() << endl;
}


// Codeforces 1900-2200 difficulty. Problem #61
// Hashing, Binary Search, DP
#include <bits/stdc++.h>
#define N 1000009
using namespace std;
int A[N], B[N], indexOnA[N];
vector<int>ans;
int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> A[i];
        indexOnA[A[i]] = i;
    }
    for (int i = 0; i < n; i++)
        cin >> B[i];
    for(int i = n - 1; i >= 0; i--)
    {
        int toBeCheckedIndex = indexOnA[B[i]];
        auto upperBound = upper_bound(ans.begin(), ans.end(), toBeCheckedIndex);
        int relevantIndex = upperBound - ans.begin();
        if(relevantIndex == ans.size())
            ans.push_back(toBeCheckedIndex);
        else
            ans[relevantIndex] = toBeCheckedIndex;
    }
    cout << ans.size() << endl;
}


// Codeforces 1900-2200 difficulty. Problem #61
// Hashing, DP
#include <bits/stdc++.h>
#define N 1000009
using namespace std;
int A[N], B[N], indexOnA[N];
int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> A[i];
        indexOnA[A[i]] = i;
    }
    for (int i = 0; i < n; i++)
        cin >> B[i];
    int curIndex = -1, ans = 0;
    for(int i = n - 1; i >= 0; i--)
    {
        if(indexOnA[B[i]] > curIndex)
            ans++;
        curIndex = max(curIndex, indexOnA[B[i]]);
    }
    cout << ans << endl;
}


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

const int MAX=1e6+6;
int n, a[MAX], dp[MAX], ind[MAX];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n;
    for (int i=1; i<=n; ++i) {
        int ray;
        cin >> ray;
        ind[ray]=i;
    }

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

    dp[0]=-MAX;
    for (int i=1; i<=n; ++i) {
        dp[i]=MAX;
    }

    int lis=1;
    for (int i=n; i>=1; --i) {
        int pos=upper_bound(dp, dp+n+1, a[i])-dp;
        lis=max(lis, pos);
        dp[pos]=a[i];
    }

    cout << lis;

    return 0;
}


/*
त्यक्तवाधर्मं च लोभं च
मोहंचो द्यमास्थिता।
युद्ध्यध्वमनहंकारा
यतो धर्मस्ततो जयः।।
*/
#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 int     long long int
#define ld      long double
#define pb      push_back
#define pa      pair<int,int>
#define v1d     vector<int>
#define v2d     vector<vector<int> >
#define M       1000000007
#define MN      LLONG_MIN
#define MX      LLONG_MAX
#define ff      first
#define ss      second
#define endl    "\n"
#define v1s     vector<string>
#define S(v)    sort(v.begin(),v.end())
#define RS(v)   sort(v.rbegin(),v.rend())
#define R(v)    reverse(v.begin(),v.end())
#define mxpq(T)    priority_queue <T>
#define mnpq(T)    priority_queue<T,vector<T>,greater<T>>
#define T       int tc;cin>>tc;while(tc--)
#define p2d(v)     for(auto a:v){for(auto b:a)cout<<b<<" ";cout<<endl;}

void Weapons19(){
    cin.sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    #ifndef ONLINE_JUDGE
     freopen("input.txt",  "r",  stdin);
     freopen("output.txt", "w", stdout);
    #endif
}

int32_t main(){
    Weapons19();
    int n;cin>>n;
    v1d x(n);
    map<int,int>lock;
    for(int i=0;i<n;i++){
    	cin>>x[i];
    	lock[x[i]]=i+1;
    }
    int a;v1d v;
    for(int i=0;i<n;i++){
    	cin>>a;
    	v.pb(lock[a]);
    }
    R(v);
    v1d dp(v.size()+1);
    v1d loc(n+1);
    set<int>s;
    s.insert(v[0]);dp[1]=v[0];loc[v[0]]=1;//cout<<v[0];
    for(int i=1;i<v.size();i++){
    	auto p=s.lower_bound(v[i]);
    	if(p==s.begin()){
    		if(dp[1]>v[i]){
    			s.erase(dp[1]);s.insert(v[i]);
    			dp[1]=v[i];loc[v[i]]=1;
    		}
    	}
    	else{//cout<<"G";
    		int z=*(--p);//cout<<z;
    		int h=loc[z];
    		if(dp[h+1]>v[i]||dp[h+1]==0){
    			s.erase(dp[h+1]);s.insert(v[i]);
    			dp[h+1]=v[i];loc[v[i]]=h+1;
    		}
    	}
    	//for(auto a:s)cout<<a;cout<<endl;
    }
    for(int i=n;i>=0;i--){
    	if(dp[i]){
    		cout<<i;return 0;
    	}
    }//cout<<dp[1];
    cout<<1;

}


#include <bits/stdc++.h>

#define mp make_pair
#define pb push_back

using namespace std;

typedef long long ll;

const int maxn = 1e6 + 7;

int a[maxn], b[maxn], c[maxn], f[maxn];
int n;

int main(){
//	freopen("input.inp", "r", stdin);
//	freopen("output.out", "w", stdout);
	scanf("%d",&n);
	int x;
	for(int i = 1; i <= n; ++i) scanf("%d",&x), c[x] = i;
	for(int i = 1; i <= n; ++i) scanf("%d",&x), b[x] = i;
	for(int i = 1; i <= n; ++i) a[c[i]] = b[i];
	reverse(a + 1, a + 1 + n);
	int ans = 0;
	for(int i = 1; i <= n; ++i){
		if (a[i] > f[ans]) f[++ans] = a[i];
		else if (a[i] < f[1]) f[1] = a[i];
		else{
			int l = 1, r = ans;
			while (l <= r){
				int mid = (l + r) >> 1;
				if (a[i] < f[mid]) r = mid - 1;
				else l = mid + 1;
			}
			f[l] = a[i];
		}
	}
	printf("%d",ans);
	return 0;
}


#include <bits/stdc++.h>

#define mp make_pair
#define pb push_back

using namespace std;

typedef long long ll;

const int maxn = 1e6 + 7;

int a[maxn], b[maxn], f[maxn];
int n;

int main(){
//	freopen("input.inp", "r", stdin);
//	freopen("output.out", "w", stdout);
	scanf("%d",&n);
	for(int i = 1; i <= n; ++i) scanf("%d",&b[i]);
	int x;
	for(int i = 1; i <= n; ++i) scanf("%d",&x), a[b[i]] = x;
	reverse(a + 1, a + 1 + n);
	int ans = 0;
	for(int i = 1; i <= n; ++i){
		if (a[i] > f[ans]) f[++ans] = a[i];
		else if (a[i] < f[1]) f[1] = a[i];
		else{
			int l = 1, r = ans;
			while (l <= r){
				int mid = (l + r) >> 1;
				if (a[i] < f[mid]) r = mid - 1;
				else l = mid + 1;
			}
			f[l] = a[i];
		}
	}
	printf("%d",ans);
	return 0;
}


#include <bits/stdc++.h>

#define mp make_pair
#define pb push_back

using namespace std;

typedef long long ll;

const int maxn = 1e6 + 7;

int a[maxn], f[maxn];
int n;

int main(){
//	freopen("input.inp", "r", stdin);
//	freopen("output.out", "w", stdout);
	scanf("%d",&n);
	for(int i = 1; i <= n; ++i){
		int x, y;
		scanf("%d%d",&x,&y);
		a[x] = y;
	}
	reverse(a + 1, a + 1 + n);
	int ans = 0;
	for(int i = 1; i <= n; ++i){
		if (a[i] > f[ans]) f[++ans] = a[i];
		else if (a[i] < f[1]) f[1] = a[i];
		else{
			int l = 1, r = ans;
			while (l <= r){
				int mid = (l + r) >> 1;
				if (a[i] < f[mid]) r = mid - 1;
				else l = mid + 1;
			}
			f[l] = a[i];
		}
	}
	printf("%d",ans);
	return 0;
}


#include <bits/stdc++.h>

#define mp make_pair
#define pb push_back

using namespace std;

typedef long long ll;

const int maxn = 1e6 + 7;

int a[maxn], b[maxn], f[maxn];
int n;

int main(){
//	freopen("input.inp", "r", stdin);
//	freopen("output.out", "w", stdout);
	scanf("%d",&n);
	int x;
	for(int i = 1; i <= n; ++i) scanf("%d",&x), b[x] = i;
	for(int i = 1; i <= n; ++i) scanf("%d",&x), a[b[x]] = i;
	reverse(a + 1, a + 1 + n);
	int ans = 0;
	for(int i = 1; i <= n; ++i){
		if (a[i] > f[ans]) f[++ans] = a[i];
		else if (a[i] < f[1]) f[1] = a[i];
		else{
			int l = 1, r = ans;
			while (l <= r){
				int mid = (l + r) >> 1;
				if (a[i] < f[mid]) r = mid - 1;
				else l = mid + 1;
			}
			f[l] = a[i];
		}
	}
	printf("%d",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define M 1000000007
#define Fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
ll po(ll x,ll n)
{
    if(n==0)
        return 1;
    else if(n%2 == 0)
        return po((x*x)%M,n/2);
    else
        return (x*po((x*x)%M,(n-1)/2))%M;

}
ll GCD(ll A, ll B) {
    if(B==0)
        return A;
    else
        return GCD(B, A % B);
}
int main()
{
    Fast;
    int n;
    cin>>n;
    vector<pair<int,int>>a(n);
    for(int i=0;i<n;++i)
        cin>>a[i].ff;
    for(int i=0;i<n;++i)
        cin>>a[i].ss;
    sort(a.begin(),a.end());
    reverse(a.begin(),a.end());
    int le[n+1]={0};
    int len=1;
    le[len]=a[0].ss;
    for(int i=1;i<n;++i)
    {
        if(a[i].ss>le[len])
        {
            len++;
            le[len]=a[i].ss;
            continue;
        }
        if(a[i].ss<le[1])
        {
            le[1]=a[i].ss;
            continue;
        }
        int l=1,h=len;
        int an=1;
        while(l<=h)
        {
            int m=(l+h)/2;
            if(le[m]>a[i].ss)
            {
                an=m;
                h=m-1;
            }
            else
                l=m+1;
        }
        le[an]=a[i].ss;
    }
    cout<<len;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define M 1000000007
#define Fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
ll po(ll x,ll n)
{
    if(n==0)
        return 1;
    else if(n%2 == 0)
        return po((x*x)%M,n/2);
    else
        return (x*po((x*x)%M,(n-1)/2))%M;

}
ll GCD(ll A, ll B) {
    if(B==0)
        return A;
    else
        return GCD(B, A % B);
}
int main()
{
    Fast;
    int n;
    cin>>n;
    vector<pair<int,int>>a(n);
    for(int i=0;i<n;++i)
    {
        int u;
        cin>>u;
        a[u-1].ff=i+1;
    }
    for(int i=0;i<n;++i)
    {
        int u;
        cin>>u;
        a[u-1].ss=i+1;
    }
    sort(a.begin(),a.end());
    reverse(a.begin(),a.end());
    int le[n+1]={0};
    int len=1;
    le[len]=a[0].ss;
    for(int i=1;i<n;++i)
    {
        if(a[i].ss>le[len])
        {
            len++;
            le[len]=a[i].ss;
            continue;
        }
        if(a[i].ss<le[1])
        {
            le[1]=a[i].ss;
            continue;
        }
        int l=1,h=len;
        int an=1;
        while(l<=h)
        {
            int m=(l+h)/2;
            if(le[m]>a[i].ss)
            {
                an=m;
                h=m-1;
            }
            else
                l=m+1;
        }
        le[an]=a[i].ss;
    }
    cout<<len;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define M 1000000007
#define Fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
ll po(ll x,ll n)
{
    if(n==0)
        return 1;
    else if(n%2 == 0)
        return po((x*x)%M,n/2);
    else
        return (x*po((x*x)%M,(n-1)/2))%M;

}
ll GCD(ll A, ll B) {
    if(B==0)
        return A;
    else
        return GCD(B, A % B);
}
int tree[4000001];
vector<pair<int,int>>a(1000001);
void build(int node, int start, int end)
{
    if(start == end)
    {
        // Leaf node will have a single element
        tree[node] = a[start].ss;
    }
    else
    {
        int mid = (start + end) / 2;
        // Recurse on the left child
        build(2*node, start, mid);
        // Recurse on the right child
        build(2*node+1, mid+1, end);
        // Internal node will have the sum of both of its children
        tree[node] = min(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)
    {
        // range represented by a node is completely outside the given range
        return 10000000;
    }
    if(l <= start and end <= r)
    {
        // range represented by a node is completely inside the given range
        return tree[node];
    }
    // range represented by a node is partially inside and partially outside the given range
    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 min(p1 , p2);
}
int main()
{
    Fast;
    for(int i=0;i<=1000000;++i)
        a[i].ff=10000000;
    int n;
    cin>>n;
    for(int i=0;i<n;++i)
        cin>>a[i].ff;
    for(int i=0;i<n;++i)
        cin>>a[i].ss;
    sort(a.begin(),a.end());
    build(1,0,n-1);
    int dp[n+1]={0};
    dp[0]=0;
    int ma=1;
    for(int i=1;i<n;++i)
    {
        int l=0,h=i-1;
        int an=i;
        while(l<=h)
        {
            int m=(l+h)/2;
            int d=query(1,0,n-1,m,i-1);
            if(a[i].ss<d)
            {
                an=m;
                h=m-1;
            }
            else
                l=m+1;
        }
        dp[i]=max(dp[i-1],an);
        ma=max(ma,i-dp[i]+1);
    }
    cout<<ma;
}


#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include <iomanip>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long int ll;
#define pb push_back
#define F first
#define S second
#define mkp make_pair
#define pow2(i) (1LL << (i))
#define modi(a,b) ((a%b+b)%b)
#define uni(a,b) (((a+b)*(a+b+1)/2)+b)
const int MAXN=1e9+7;
ll int_pow(ll base, ll exp){
	ll result=1;
	while (exp){
		if (exp & 1)
		   result *= base;
		exp/=2;
		base*=base;
	}
	return result;
}
vector<ll>g[1000005];
ll num=0;
bool mark[1000005];
void DFS(ll x){
	num++;
	mark[x]=1;
	for (ll y:g[x]){
		if (!mark[y])DFS(y);
	}
}
int main() {
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	ll n,a,ans=0;cin >> n;
	for (ll i=0;i<n;i++)cin >> a;
	for (ll i=0;i<n;i++){
		cin >> a;
		g[a].pb(i+1);
	}
	for (ll i=1;i<=n;i++){
		if (!mark[i]){
			num=0;
			DFS(i);
			ans = max(ans,num);
		}
	}
	cout << ans-1;
}


#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include <iomanip>
#include <map>
#include <queue>
#include <set>
#include <cstring>
using namespace std;
typedef long long int ll;
#define pb push_back
#define F first
#define S second
#define mkp make_pair
#define pow2(i) (1LL << (i))
#define modi(a,b) ((a%b+b)%b)
#define uni(a,b) (((a+b)*(a+b+1)/2)+b)
const int INF=1e9+7;
const int MAXN=1e6+5;
ll int_pow(ll base, ll exp){
	ll result=1;
	while (exp){
		if (exp & 1)
		   result *= base;
		exp/=2;
		base*=base;
	}
	return result;
}
ll a1[MAXN],a2[MAXN],last1[MAXN],last2[MAXN],d1[MAXN],d2[MAXN];
int main() {
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	ll n,best1=0,best2=0;cin >> n;
	for (ll i=0;i<n;i++)cin >> a1[i];
	for (ll i=0;i<n;i++)cin >> a2[i];
	memset(last1,INF,sizeof last1);
	memset(last2,INF,sizeof last2);
	last1[0]=0;
	last2[0]=0;
	for (ll i=0;i<n;i++){
		ll p = lower_bound(last1,last1+n,a1[i])-last1;
		d1[i]=p;
		last1[p] = min(last1[p],a1[i]);
		best1 = max(best1,d1[i]);
	}
	for (ll i=0;i<n;i++){
		ll p = lower_bound(last2,last2+n,a2[i])-last2;
		d2[i]=p;
		last2[p] =min(last2[p],a2[i]);
		best2 = max(best2,d2[i]);
	}
	cout << min(best1,best2);
}


#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include <iomanip>
#include <map>
#include <queue>
#include <set>
#include <cstring>
using namespace std;
typedef long long int ll;
#define pb push_back
#define F first
#define S second
#define mkp make_pair
#define pow2(i) (1LL << (i))
#define modi(a,b) ((a%b+b)%b)
#define uni(a,b) (((a+b)*(a+b+1)/2)+b)
const int INF=1e9+7;
const int MAXN=1e6+5;
ll int_pow(ll base, ll exp){
	ll result=1;
	while (exp){
		if (exp & 1)
		   result *= base;
		exp/=2;
		base*=base;
	}
	return result;
}
ll mark[MAXN],last[MAXN],d[MAXN];
vector<pair<ll,ll> >v;
int main() {
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	ll n,a,ans=0;cin >> n;
	for (ll i=0;i<n;i++)cin >>a,mark[a]=i+1;
	for (ll i=0;i<n;i++)cin >>a,v.pb({mark[a],i+1});
	sort(v.begin(),v.end());
	memset(last,INF,sizeof last);
	last[0]=0;
	for (ll i=0;i<n;i++){
		ll p = lower_bound(last,last+n,v[n-i-1].S) - last;
		d[i]=p;
		last[p] = min(last[p],v[n-i-1].S);
		ans = max(ans,d[i]);
	}
	cout << ans;
}


#include <cstdio>
#include <memory.h>
#include <cstring>
#include <vector>
#include <deque>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cassert>
#include <functional>
#include <iostream>
#include <set>
#include <list>
#include <map>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
using namespace std;

typedef unsigned long long llu;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef pair<string, int> psi;
const ll MOD = 1e9 + 7;
const long double PI = 3.141592653589793238462643383279502884197;

priority_queue<int, vector<int>, greater<int> > pq;
vector<int> v;

int num[1000001];

int main() {
	int n;
	scanf("%d", &n);

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

	for (int i = 0; i < n; i++) {
		scanf("%d", &t);
		int k = n - num[t];

		if (v.empty()) v.push_back(k);

		int kk = lower_bound(all(v), k) - v.begin();
		if (kk == sz(v)) v.push_back(k);
		else v[kk] = k;
	}

	printf("%d", sz(v));
}


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 1000100

int n;
pair<int, int> a[N];
int x[N];
int place[N];
int seg[N * 5];

void update(int i, int val, int p = 1, int L = 0, int R = n){
	if (i < L || i > R) return;
	if (L == R){
		seg[p] = val;
		return;
	}

	int mid = (L + R) / 2;
	update(i, val, p * 2, L, mid);
	update(i, val, p * 2 + 1, mid + 1, R);
	seg[p] = max(seg[p * 2], seg[p * 2 + 1]);
}

int query(int i, int j, int p = 1, int L = 0, int R = n){
	if (j < L || i > R) return 0;
	if (L >= i && R <= j) return seg[p];

	int mid = (L + R) / 2;
	int c1 = query(i, j, p * 2, L, mid);
	int c2 = query(i, j, p * 2 + 1, mid + 1, R);
	return max(c1, c2);
}

int main() {
//	freopen("in.in", "r", stdin);
//	freopen("out.out", "w", stdout);
	ios::sync_with_stdio(0); cin.tie(); cout.tie(); srand(time(0));

	cin >> n;
	for (int i = 0; i < n; i++) cin >> x[i];
	for (int i = 0; i < n; i++){
		int ray; cin >> ray;
		place[ray] = i;
	}
	for (int i = 0; i < n; i++) a[i].first = place[x[i]], a[i].second = i;
	sort(a, a + n);
	int ans = 0;
	for (int i = 0; i < n; i++){
		int val = a[i].first, idx = a[i].second;
		int DPi = query(idx, n) + 1;
		ans = max(ans, DPi);
		update(idx, DPi);
	}
	cout << ans << endl;

	return 0;
}


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

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n;
	cin>>n;
	int a[n];
	int b[n];
	for(int i=0; i<n; i++){
		cin>>a[i];
	}
	int index[n+1];
	for(int i=0; i<n; i++){
		cin>>b[i];
		index[b[i]]=i;
	}

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

	vector<int>d(n+1, pow(10, 9));
	d[0]=-pow(10, 9);
	for(int i=0; i<n; i++){
		b[i]=(-b[i]);
	}
	for(int i=0; i<n; i++){
		int j=upper_bound(d.begin(), d.end(), b[i])-d.begin();
		d[j]=b[i];
	}
	int ans=0;
	for(int i=0; i<=n; i++){
		if(d[i]<pow(10, 9)){
			ans=i;
		}
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int dp[5005][5005];
int main() {
	int n;
	cin>>n;
	int a[n];
	int b[n];
	for(int i=0; i<n; i++){
		cin>>a[i];
	}
	int index[n+1];
	for(int i=0; i<n; i++){
		cin>>b[i];
		index[b[i]]=i;
	}

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

	vector<int>d(n+1, pow(10, 9));
	d[0]=-pow(10, 9);
	for(int i=0; i<n; i++){
		b[i]=(-b[i]);
	}
	for(int i=0; i<n; i++){
		int j=upper_bound(d.begin(), d.end(), b[i])-d.begin();
		d[j]=b[i];
	}
	int ans=0;
	for(int i=0; i<=n; i++){
		if(d[i]<pow(10, 9)){
			ans=i;
		}
	}
	cout<<ans;
	return 0;
}


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

int main() {
	int n;
	cin>>n;
	int a[n];
	int b[n];
	for(int i=0; i<n; i++){
		cin>>a[i];
	}
	int index[n+1];
	for(int i=0; i<n; i++){
		cin>>b[i];
		index[b[i]]=i;
	}

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

	vector<int>d(n+1, pow(10, 9));
	d[0]=-pow(10, 9);
	for(int i=0; i<n; i++){
		b[i]=(-b[i]);
	}
	for(int i=0; i<n; i++){
		int j=upper_bound(d.begin(), d.end(), b[i])-d.begin();
		d[j]=b[i];
	}
	int ans=0;
	for(int i=0; i<=n; i++){
		if(d[i]<pow(10, 9)){
			ans=i;
		}
	}
	cout<<ans;
	return 0;
}


#include <iostream>

using namespace std;

const int N = 1e1 + 5;

int n, m, x;
int dp[N], aux[N], v[N];

int cautare_binara(int val)	 {
  int st = 1, dr = m, mij, ans = 0;
  while (st <= dr)	{
		mij = (st + dr) / 2;
		if (dp[mij] < val)
			dr = mij - 1;
		else	{
			ans = mij;
			st = mij + 1;
		}
  }
  return ans;
}

int main()	{
	cin >> n;
	for (int i = 1; i <= n; ++i)	{
    cin >> x;
    aux[x] = i;
	}
	for (int i = 1; i <= n; ++i)	{
		cin >> x;
    v[aux[x]] = i;
	}
	dp[0] = 2e9;
  for (int i = 1; i <= n; ++i)	{
		if (dp[m] > v[i])
			dp[++m] = v[i];
		else	{
			int poz = cautare_binara(v[i]);
			dp[poz + 1] = max(dp[poz + 1], v[i]);
		}
  }
  cout << m;
  return 0;
}


#include <iostream>

using namespace std;

const int N = 1e6 + 5;

int n, m, x;
int dp[N], aux[N], v[N];

int cautare_binara(int val)	 {
  int st = 1, dr = m, mij, ans = 0;
  while (st <= dr)	{
		mij = (st + dr) / 2;
		if (dp[mij] < val)
			dr = mij - 1;
		else	{
			ans = mij;
			st = mij + 1;
		}
  }
  return ans;
}

int main()	{
	cin >> n;
	for (int i = 1; i <= n; ++i)	{
    cin >> x;
    aux[x] = i;
	}
	for (int i = 1; i <= n; ++i)	{
		cin >> x;
    v[aux[x]] = i;
	}
	dp[0] = 2e9;
  for (int i = 1; i <= n; ++i)	{
		if (dp[m] > v[i])
			dp[++m] = v[i];
		else	{
			int poz = cautare_binara(v[i]);
			dp[poz + 1] = max(dp[poz + 1], v[i]);
		}
  }
  cout << m;
  return 0;
}


#include <iostream>

using namespace std;

const int N = 1e6 + 5;

int n, m, x;
int dp[N], aux[N], v[N];

int cautare_binara(int val)	 {
  int st = 1, dr = m, mij, ans = 0;
  while (st <= dr)	{
		mij = (st + dr) / 2;
		if (dp[mij] < val)
			dr = mij - 1;
		else	{
			ans = mij;
			st = mij + 1;
		}
  }
  return ans;
}

int main()	{
	cin >> n;
	for (int i = 1; i <= n; ++i)	{
    cin >> x;
    aux[x] = i;
	}
	for (int i = 1; i <= n; ++i)	{
		cin >> x;
    v[aux[x]] = i;
	}
	dp[0] = 2e9;
  for (int i = 1; i <= n; ++i)	{
		if (dp[m] > v[i])
			dp[++m] = v[i];
		int poz = cautare_binara(v[i]);
		dp[poz + 1] = min(dp[poz + 1], v[i]);
  }
  cout << m;
  return 0;
}


#include <iostream>

using namespace std;

const int N = 1e6 + 5;

int n, m, x;
int dp[N], aux[N], v[N];

int cautare_binara(int val)	 {
  int st = 1, dr = m, mij, ans = 0;
  while (st <= dr)	{
		mij = (st + dr) / 2;
		if (dp[mij] < val)
			dr = mij - 1;
		else	{
			ans = mij;
			st = mij + 1;
		}
  }
  return ans;
}

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;
    aux[x] = i;
	}
	for (int i = 1; i <= n; ++i)	{
		cin >> x;
    v[aux[x]] = i;
	}
	dp[0] = 2e9;
  for (int i = 1; i <= n; ++i)	{
		if (dp[m] > v[i])
			dp[++m] = v[i];
		else	{
			int poz = cautare_binara(v[i]);
			dp[poz + 1] = max(dp[poz + 1], v[i]);
		}
  }
  cout << m;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n;

vector<pair<int, int>> xs;

int lon(vector<pair<int, int>> &arr, vector<int> & LIS){
    vector<int> a(arr.size());
    int cnt = 0;
    int mm = 0;
    for(int i = 0; i < arr.size(); i++){
        int pos = lower_bound(a.begin(), a.begin()+cnt, arr[i].second) - a.begin();
        a[pos] = arr[i].second;
        if(pos == cnt){
            cnt++;
        }
        LIS[i] = pos+1;
        mm = max(mm, pos+1);
    }
    return mm;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n;
    int t;
    vector<int> x(n), y(n);
    for(int i =0; i < n ;i++){
        cin >> t;
        t--;
        x[t] = i;
    }
    for(int i = 0; i < n; i++){
        cin >> t;
        t--;
        y[t] = i;
    }
    for(int i = 0; i < n; i++){
        xs.push_back(make_pair(x[i], y[i]));
    }
    sort(xs.begin(), xs.end(), greater<pair<int, int>>());
    vector<int> lo(n);
    int mx= lon(xs, lo);
    cout << mx;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n;

vector<pair<int, int>> xs;

int lon(vector<pair<int, int>> &arr, vector<int> & LIS){
    vector<int> a(arr.size());
    int cnt = 0;
    int mm = 0;
    for(int i = 0; i < arr.size(); i++){
        int pos = lower_bound(a.begin(), a.begin()+cnt, arr[i].second) - a.begin();
        a[pos] = arr[i].second;
        if(pos == cnt){
            cnt++;
        }
        LIS[i] = pos+1;
        mm = max(mm, pos+1);
    }
    return mm;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n;
    int t;
    vector<int> x(n), y(n);
    for(int i =1; i <= n ;i++){
        cin >> t;
        x[t] = i;
    }
    for(int i = 1; i <= n; i++){
        cin >> t;
        y[t] = i;
    }
    for(int i = 1; i <= n; i++){
        xs.push_back(make_pair(x[i], y[i]));
    }
    sort(xs.begin(), xs.end(), greater<pair<int, int>>());
    vector<int> lo(n);
    int mx= lon(xs, lo);
    cout << mx;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n;

vector<pair<int, int>> xs;

int lon(vector<pair<int, int>> &arr, vector<int> & LIS){
    vector<int> a(arr.size());
    int cnt = 0;
    int mm = 0;
    for(int i = 0; i < arr.size(); i++){
        int pos = lower_bound(a.begin(), a.begin()+cnt, arr[i].second) - a.begin();
        a[pos] = arr[i].second;
        if(pos == cnt){
            cnt++;
        }
        LIS[i] = pos+1;
        mm = max(mm, pos+1);
    }
    return mm;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    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];
    }
    for(int i = 0; i < n; i++){
        xs.push_back(make_pair(x[i], y[i]));
    }
    sort(xs.begin(), xs.end(), greater<pair<int, int>>());
    vector<int> lo(n);
    int mx= lon(xs, lo);
    cout << mx;
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<bits/stdc++.h>
#include<string>
#include<vector>
using namespace std;
#define ull unsigned long long
#define ll long long
#define fast  ios_base::sync_with_stdio(0); cin.tie(0);
#define f(i,k) for(i=0;i<k;i++)
#define rep(i,n) for(i=1;i<=n;i++)
#define input(i,n,arr) for(i=0;i<n;i++) cin>>j, arr.push_back(j)
#define vect_ll vector<long long>
#define vect_ll_it vector<long long>::iterator
#define pb(p) push_back(p)
#define endl "\n"
#define mod 1000000007
ll i,j,k,q,n,m;
ll const N=200001;
ll lenght=1;
vect_ll b,pos,mx_list;
//ll visited[100001]={0};
//vect_ll g[100001];
ll getindex(ll low,ll high,ll val)
{
    while(low<high)
    {
        ll mid=(low+high)/2;
        if(mx_list[mid]>val) low=mid+1;
        else high=mid;
    }
    return low;
}
int main()
{
	fast
	//int t;cin>>t;
	//while(t--)
	{
		cin>>n;
		pos.resize(n+1);
		b.resize(n+1);
		mx_list.resize(n+1);
		rep(i,n) cin>>j , pos[j]=i;
		rep(i,n) cin>>j, b[pos[j]]=i;
		reverse(b.begin(),b.end());
		mx_list[0]=b[0];
		ll length=1;
		for(i=1;i<n;i++)
		{
		    auto it=lower_bound(mx_list.begin(),mx_list.begin()+length,b[i]);
		    if(it==mx_list.begin()+length) mx_list[length++]=b[i];
		    else *it=b[i];
		}
		cout<<length<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#define f0(i, n) for(int i(0); i < (n); i++)
#define f1(i, n) for(int i(1); i <= n; i++)

using namespace std;
typedef long long ll;
const int N = 1000002;

int n, a[N], dd[N], t[N];
int f[N];

int get1(int x){
    int res = 0;
    for(x; x <= n; x += (x & -x)) res = max(res, t[x]);
    return res;
}

void up(int x, int res){
    for(x; x > 0; x -= (x & -x)) t[x] = max(t[x], res);
}

int main(){
    ios_base::sync_with_stdio(0);

    cin >> n;
    f1(i, n) cin >> a[i];
    f1(i, n){
        int x; cin >> x;
        dd[x] = i;
    }
    f1(i, n){
        f[i] = get1(dd[a[i]]) + 1;
        up(dd[a[i]], f[i]);
    }
    cout << *max_element(f + 1, f + n + 1);
}


#include<bits/stdc++.h>

#define ll long long
#define pb push_back

using namespace std;

const int N=1e6+100,inf=1e8;

ll n,s,x;
ll a[N],b[N] , m[N] , last[N];

vector< pair<ll,ll> >v;
pair<ll,ll>p;

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

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

	for(int i=1;i<=n;i++)   {  last[i]=inf;  }

    last[0]=0;
	for(int i=1;i<=n;i++)
	{
        cin>>b[i];
		b[i]=m[b[i]];   b[i]=n-b[i]+1;

		x=lower_bound(  last,last+n , b[i]  )-(last+1);
        last[x+1]=min(  b[i] , last[x+1]  );
        s=max(s,x+1);
	}

	cout<<s;
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 1e6 + 8;
int a[N] , b[N] , n , x , q;
vector <int> v;

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	for(int i = 0 ; i < n ; i++)
	{
		cin >> x;
		a[x - 1] = i;
	}
	for(int i = n - 1 ; i >= 0 ; i--)
	{
		cin >> x;
		b[i] = a[x - 1];
	}
	for(int i = 0 ; i < n ; i++)
	{
		q = lower_bound(v.begin() , v.end() , b[i]) - v.begin();
		if(q == v.size())
			v.push_back(b[i]);
		else
			v[q] = b[i];
	}
	cout << v.size();
}


#include <bits/stdc++.h>
#define str string
#define add push_back
#define cut pop_back
#define st first
#define nd second
#define stick make_pair
#define pain main
typedef long long ll;
using namespace std;
const int Maxn=1e6+9;
int s[Maxn];
int v[Maxn];
int a[Maxn];
int dp[Maxn];
int k=0;
void DP(int x){
	int l=0,r=k;
	//cout << x << ' ';
	if (dp[0]>x){
		dp[0]=x;
		return;
	}
	if (dp[k]<x){
		k++;
		dp[k]=x;
		return;
	}
	while (r-l>1){
		int m=(r+l)/2;
		if (dp[m]<x){
			l=m;
		}
		else{
			r=m;
		}
	}
	dp[r]=x;
}
int pain(){
	//Sie sind das essen und wir sind die j�ger!!
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n;
	cin >> n;
	for (int i=0;i<n;i++){
		cin >> s[i];
	}
	for (int i=n;i>=1;i--){
		int x;
		cin >> x;
		v[x]=i;
	}
	for (int i=0;i<n;i++){
		a[i]=v[s[i]];
	}
	for (int i=0;i<n;i++){
		DP(a[i]);
	}
	cout << k;
	return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <stack>
#include <map>
#include <queue>
#include <unordered_map>
#include <cassert>
#include <iomanip>
#include <cmath>
#include <cstring>
using namespace std;
#define pb 					push_back
template<typename T,typename S>
ostream& operator <<(ostream& os, pair<T, S> input) {
	os<<"("<<input.first<<", "<<input.second<<")";
	return os;
}
template<typename T>
ostream& operator <<(ostream& os, vector<T> input) {
	for(auto t: input)
		os << t <<"\n";
	return os;
}
template<typename T>
ostream& operator <<(ostream& os, set<T> input) {
	for(auto t: input)
		os << t <<"\n";
	return os;
}

int lis(vector<int> arr, int N)
{
    int i;
    set<int> s;
    set<int>::iterator k;
    for (i=0; i<N; i++)
    {
        // Check if the element was actually inserted
        // An element in set is not inserted if it is
        // already present. Please see
        // https://www.geeksforgeeks.org/set-insert-function-in-c-stl/
        if (s.insert(arr[i]).second)
        {
            // Find the position of inserted element in iterator k
            k = s.find(arr[i]);

            k++;  // Find the next greater element in set

            // If the new element is not inserted at the end, then
            // remove the greater element next to it (This is tricky)
            if (k!=s.end()) s.erase(k);
        }
    }

    // Note that set s may not contain actual LIS, but its size gives
    // us the length of LIS
    return s.size();
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin >> n;
	vector<int> a, b;
	for(int i=1; i<=n; i++) {
		int x;
		cin >> x;
		a.push_back(x);
	}
	for(int i=1; i<=n; i++) {
		int x;
		cin >> x;
		b.push_back(x);
	}
	reverse(b.begin(), b.end());
	map<int, int> pos;
	for(int i=1; i<=n; i++) {
		int x= b[i-1];
		pos[b[i-1]] = i;
	}
	vector<int> lisV;
	for(int i=0; i<n; i++) {
		lisV.push_back(pos[a[i]]);
	}
	int ans = lis(lisV, n);
	cout << ans << "\n";

}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <stack>
#include <map>
#include <queue>
#include <unordered_map>
#include <cassert>
#include <iomanip>
#include <cmath>
#include <cstring>
using namespace std;
#define pb 					push_back
template<typename T,typename S>
ostream& operator <<(ostream& os, pair<T, S> input) {
	os<<"("<<input.first<<", "<<input.second<<")";
	return os;
}
template<typename T>
ostream& operator <<(ostream& os, vector<T> input) {
	for(auto t: input)
		os << t <<"\n";
	return os;
}
template<typename T>
ostream& operator <<(ostream& os, set<T> input) {
	for(auto t: input)
		os << t <<"\n";
	return os;
}

int lis(vector<int> arr, int N)
{
    int i;
    set<int> s;
    set<int>::iterator k;
    for (i=0; i<N; i++)
    {
        // Check if the element was actually inserted
        // An element in set is not inserted if it is
        // already present. Please see
        // https://www.geeksforgeeks.org/set-insert-function-in-c-stl/
        if (s.insert(arr[i]).second)
        {
            // Find the position of inserted element in iterator k
            k = s.find(arr[i]);

            k++;  // Find the next greater element in set

            // If the new element is not inserted at the end, then
            // remove the greater element next to it (This is tricky)
            if (k!=s.end()) s.erase(k);
        }
    }

    // Note that set s may not contain actual LIS, but its size gives
    // us the length of LIS
    return s.size();
}
int pos[1000002];
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin >> n;
	vector<int> a, b;
	for(int i=1; i<=n; i++) {
		int x;
		cin >> x;
		a.push_back(x);
	}
	for(int i=1; i<=n; i++) {
		int x;
		cin >> x;
		b.push_back(x);
	}
	reverse(b.begin(), b.end());
	for(int i=1; i<=n; i++) {
		int x= b[i-1];
		pos[b[i-1]] = i;
	}
	vector<int> lisV;
	for(int i=0; i<n; i++) {
		lisV.push_back(pos[a[i]]);
	}
	int ans = lis(lisV, n);
	cout << ans << "\n";

}


#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int a[1000010];
int b[1000010];
int seg[4000000];
int update(int pos, int val, int node, int x, int y)
{
	if (pos < x || y < pos)return seg[node];
	if (x == y)return seg[node] += val;
	int mid = (x + y) / 2;
	return seg[node] = max(update(pos, val, node * 2, x, mid), update(pos, val, node * 2 + 1, mid + 1, y));
}
int query(int lo, int hi, int node, int x, int y) {
	if (hi < x || y < lo)return 0;
	if (lo <= x&&y <= hi)return seg[node];
	int mid = (x + y) / 2;
	return max(query(lo, hi, node * 2, x, mid), query(lo, hi, node * 2 + 1, mid + 1, y));
}
int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	for (int i = 0; i < n; i++)
	{
		int q;
		scanf("%d", &q);
		b[q] = i;
	}
	int dap = 0;
	for (int i = 0; i < n; i++)
	{
		int t=query(b[a[i]], n, 1, 1, n);
		t++;
		dap = max(dap, t);
		update(b[a[i]], t, 1, 1, n);
	}
	printf("%d", dap);
}


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

int n;
int tniz[MAXN],niz[MAXN];
int seg[4*MAXN];
int res=0;
void promeni(int l,int d,int p,int x,int k){
    if(l==d){
        seg[k]=x;
        return;
    }
    int mid=(l+d)/2;
    if(p<=mid)promeni(l,mid,p,x,k+k);
    else promeni(mid+1,d,p,x,k+k+1);
    seg[k]=max(seg[k+k],seg[k+k+1]);
}
int nadji(int l,int d,int tl,int td,int k){
    if(td<l || tl>d)return 0;
    if(l>=tl && d<=td)return seg[k];
    int mid=(l+d)/2;
    return max(
               nadji(l,mid,tl,td,k+k),
               nadji(mid+1,d,tl,td,k+k+1)
               );
}

int main()
{
    scanf("%d", &n);
    for(int i=1;i<=n;i++){
        int t;
        scanf("%d", &t);
        tniz[t]=i;
    }
    for(int i=1;i<=n;i++){
        int t;
        scanf("%d", &t);
        niz[i]=tniz[t];
    }
    reverse(niz+1,niz+n+1);

    for(int i=1;i<=n;i++){
        int tres=1+nadji(1,n,1,niz[i],1);
        //printf("%d ",tres);
        res=max(res,tres);
        promeni(1,n,niz[i],tres,1);

    }
    printf("%d",res);
    return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;
const int K = 1<<20;
int tr[K * 2];

int main() {
	int n;
	scanf("%d", &n);
	vector<int> rev(n+1);
	for (int i = 0; i < n; i++) {
		int t;
		scanf("%d", &t);
		rev[t] = i;
	}
	int res = 0;
	for (int i = 0; i < n; i++) {
		int t;
		scanf("%d", &t);
		int p = rev[t];
		unsigned l = K + p, r = K * 2;
		int v = 0;
		while (r - l != 1) {
			if (l % 2 == 0)
				v = max(v, tr[l + 1]);
			v = max(v, tr[r - 1]);
			l/=2;
			r/=2;
		}
		++v;
		res = max(v, res);
		p += K;
		while (p != 0) {
			tr[p] = max(tr[p], v);
			p/=2;
		}
	}
	printf("%d", res);
	return 0;
}


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

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
  int n;
  cin >> n;
  vector < pair <int,int> > PRS(n);
  for (int i = 0;i < n;i++) {
    cin >> PRS[i].first;
  }
  for (int i = 0;i < n;i++) {
    cin >> PRS[i].second;
  }
  vector <int> S(n+1);
  for (int i = 0;i < n;i++) {
    S[PRS[i].first] = PRS[i].second;
  }
  reverse(S.begin(),S.end());
  int curr = 0;
  vector <int>  mins;
  vector <int> minsize;
  for (int i = 1;i <= n;i++) {
   auto it = lower_bound(mins.begin(),mins.end(),S[i]);
   if (it == mins.end() || mins.size() == 0) {
     mins.push_back(S[i]);
     minsize.push_back(1);
   } else {
     int index = it - mins.begin();
     mins[index] = S[i];
     minsize[index]++;
   }
  }
  cout << *max_element(minsize.begin(),minsize.end());
  return 0;
}


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

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
  int n;
  cin >> n;
  vector < pair <int,int> > PRS(n);
  for (int i = 0;i < n;i++) {
    cin >> PRS[i].first;
  }
  for (int i = 0;i < n;i++) {
    cin >> PRS[i].second;
  }
  vector <int> S(n);
  for (int i = 0;i < n;i++) {
    S[PRS[i].first] = PRS[i].second;
  }
  reverse(S.begin(),S.end());
  int curr = 0;
  vector <int>  mins;
  vector <int> minsize;
  for (int i = 0;i < n;i++) {
   auto it = lower_bound(mins.begin(),mins.end(),S[i]);
   if (it == mins.end() || mins.size() == 0) {
     mins.push_back(S[i]);
     minsize.push_back(1);
   } else {
     int index = it - mins.begin();
     mins[index] = S[i];
     minsize[index]++;
   }
  }
  cout << *max_element(minsize.begin(),minsize.end());
  return 0;
}


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

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
  int n;
  cin >> n;
  vector < pair <int,int> > PRS(n+1);
  for (int i = 1;i <= n;i++) {
    int a;
    cin >> a;
    PRS[a].first = i;
  }
  for (int i = 1;i <= n;i++) {
    int a;
    cin >> a;
    PRS[a].second = i;
  }
  vector <int> S(n+1);
  for (int i = 1;i <= n;i++) {
    S[PRS[i].first] = PRS[i].second;
  }
  reverse(S.begin(),S.end());
  int curr = 0;
  vector <int>  mins;
  for (int i = 0;i < n;i++) {
   auto it = lower_bound(mins.begin(),mins.end(),S[i]);
   if (it == mins.end() || mins.size() == 0) {
     mins.push_back(S[i]);
   } else {
     int index = it - mins.begin();
     mins[index] = S[i];
   }
  }
  cout << mins.size();
  return 0;
}


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

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
  int n;
  cin >> n;
  vector < pair <int,int> > PRS(n);
  for (int i = 0;i < n;i++) {
    cin >> PRS[i].first;
  }
  for (int i = 0;i < n;i++) {
    cin >> PRS[i].second;
  }
  vector <int> S(n+1);
  for (int i = 0;i < n;i++) {
    S[PRS[i].first] = PRS[i].second;
  }
  reverse(S.begin(),S.end());
  int curr = 0;
  vector <int>  mins;
  vector <int> minsize;
  for (int i = 0;i < n;i++) {
   auto it = lower_bound(mins.begin(),mins.end(),S[i]);
   if (it == mins.end() || mins.size() == 0) {
     mins.push_back(S[i]);
     minsize.push_back(1);
   } else {
     int index = it - mins.begin();
     mins[index] = S[i];
     minsize[index]++;
   }
  }
  cout << *max_element(minsize.begin(),minsize.end());
  return 0;
}


#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

const int N = 202, I5 = 5005;
int n;
//ll x[N];
P a[N];
int f[I5][N][N], k;//, last[I5][N];
//bool exist[I5][N];

int factors(ll x, int divisor) {
    int res = 0;
    while (x % divisor == 0) {
        res++;
        x /= divisor;
    }
    return res;
}

int main() {
    #ifndef ONLINE_JUDGE
        // freopen("input", "r", stdin);
        //freopen("output", "w", stdout);
    #endif
    cin >> n >> k;
    for(int i = 1; i <= n; i++) {
        ll x; cin >> x;
        a[i] = make_pair(factors(x, 2), factors(x, 5));
    }

    // for(int i = 1; i <= n; i++) ;
    sort(a+1,a+n+1,[](P a, P b) { return a.second > b.second; });

    int upper = 0; for(int i = 1; i <= k; i++) upper += a[i].second;

    int res = 0;
    // exist[0][0][0] = true;
    for(int ik = 0; ik <= k; ik++)
        for(int i5 = 0; i5 <= upper; i5++)
            for(int i = 0; i <= n; i++) f[i5][ik][i] = -1e9;
    f[0][0][0] = 0;
    for(int ik = 1; ik <= k; ik++)
        for(int i5 = 1; i5 <= upper; i5++)
            for(int i = 1; i <= n; i++) {
                f[i5][ik][i] = f[i5][ik][i-1];
                if (a[i].second <= i5) {
                    int tmp = f[i5 - a[i].second][ik - 1][i-1] + a[i].first;
                    if (tmp > f[i5][ik][i]) {
                        f[i5][ik][i] = tmp;
                        // last[i5][ik] = i;
                        // exist[i5][ik] = true;
                    }
                }
            }
    // for(int i5 = 1; i5 <= upper; i5++)
    //     if (exist[i5][k]) res = max(res, min(i5, f[i5][k]));
    for(int i5 = 1; i5 <= upper; i5++) res = max(res, min(i5, f[i5][k][n]));

    cout << res;
}