#include <bits/stdc++.h>

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>

using namespace std;
// using namespace __gnu_pbds;
typedef long double ld;
typedef long long ll;
#define int ll
#define endl "\n"
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define all(c) c.begin(), c.end()
#define vi vector<int>
#define pii pair<int,int>
#define For(i,s,e) for (ll i=(s); i<(e); i++)
#define initialize(arr,elem) memset(arr,elem,sizeof(arr))
#define sz size
const int MOD = 1e9+7;
const int MAX_SZ = 2e5+9;
const int INF = 1e18+9;

int n;
//int seg_tree[4*MAX_SZ];
int tree[4*MAX_SZ],A[MAX_SZ];

// // typedef tree< int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// void build(){
// 	for (int i= n-1;i>0;--i) seg_tree[i] = max(seg_tree[i<<1], seg_tree[i<<1|1]);
// }

// void point_update(int p, int value){
// 	for (seg_tree[p+=n] = value;p>1; p>>=1) seg_tree[p>>1] = max(seg_tree[p],seg_tree[p^1]);
// }

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

void build(int node, int start, int end)
{
    if(start == end)
    {
        // Leaf node will have a single element
        tree[node] = A[start];
    }
    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] = max(tree[2*node], tree[2*node+1]);
    }
}
void update(int node, int start, int end, int idx, int val)
{
    if(start == end)
    {
        // Leaf node
        A[idx] = val;
        tree[node] = val;
    }
    else
    {
        int mid = (start + end) / 2;
        if(start <= idx and idx <= mid)
        {
            // If idx is in the left child, recurse on the left child
            update(2*node, start, mid, idx, val);
        }
        else
        {
            // if idx is in the right child, recurse on the right child
            update(2*node+1, mid+1, end, idx, val);
        }
        // Internal node will have the sum of both of its children
        tree[node] = max(tree[2*node], tree[2*node+1]);
    }
}

int query(int node, int start, int end, int l, int r)
{
    if(r < start or end < l)
    {
        // range represented by a node is completely outside the given range
        return 0;
    }
    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 (max(p1,p2));
}
void rand_shuff(vi &arr){
	random_device rd;
	mt19937 g(rd());
	shuffle(all(arr),g);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	
	cin>>n;
	int height[n],val[n];
	For(i,0,n) cin>>height[i];
	For(i,0,n) cin>>val[i];

	//int arr[n+1];
	initialize(A,0);
	A[height[0]-1] = val[0];
	build(1,0,n);
	int res = val[0];
	For(i,1,n){
		int cur = query(1,0,n,0,height[i]-2);
		update(1,0,n,height[i]-1,cur+val[i]);
		res = max(res,cur+val[i]);
	}

	cout<<res<<endl;
	return 0;
}


Measured memory_bytes: 9472