#include <bits/stdc++.h>

using namespace std;


#define uniq(x)  x.erase(unique(x.begin(),x.end()), x.end()) //Unique value find from vector
#define upper(arr,n,fixed) upper_bound(arr,arr+n,fixed)-arr  //Upper value search  >
#define lower(arr,n,fixed) lower_bound(arr,arr+n,fixed)-arr  //Lower value search  >=
#define FOR(i,a,n) for(int i=a; i<(int)n; i++)
#define FORI(i,a,n) for(int i=a; i>=(int)n; i--)
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define sz(a) int((a).size())
#define fastIO() ios_base::sync_with_stdio(0); cin.tie(0)
#define endl "\n"
#define all(a) a.begin(), a.end()
#define MEMSET(p,i) memset(p,i,sizeof(p))

/* a=target variable, b=bit number to act upon 0-n */
#define BIT_SET(a,b) ((a) |= (1<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1<<(b)))
#define BIT_CHECK(a,b) ((a) & (1<<(b)))
#define BIT_COUNT(a) (__builtin_popcount(a))

 
/* x=target variable, y=mask */
#define BITMASK_SET(x,y) ((x) |= (y))
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
#define BITMASK_FLIP(x,y) ((x) ^= (y))
#define BITMASK_CHECK(x,y) (((x) & (y)) == (y))

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,LL> pii;
typedef vector<pii> vpii; 


class Tree
{
public:
	LL M;
	Tree(){
		M = 0;
	}
	Tree(int x){
		x = M;
	}
};



int sizeOfSegmentTree(int n)
{
	int x = (int)(ceil(log2(n))); 
	return (2*(int)pow(2,x) - 1);  // 2*(next power of two)-1
}


void build(int node, int start, int end, Tree *T, int A[])
{
	if(start == end)
		T[node].M = A[start];
	else
	{
		int leftChild = 2*node+1;
		int rightChild = 2*node+2;
		int mid = (start+end)/2;
		//compute the values in the left and right subtrees
		build(leftChild, start, mid, T, A);
		build(rightChild, mid+1, end, T, A);
		//search for the Prodimum value in the first and 
		//second half of the interval
		T[node].M = max(T[leftChild].M, T[rightChild].M);
	}
} 

void updateRange(int node, int start, int end, int l, int r, LL val, Tree *T)
{
	if(start > end || start > r || end < l) // Current segment is not within range [l, r]
		return;



	int leftChild  = 2*node+1;
	int rightChild = 2*node+2; 
	
	
	if(start >= l && end <= r)
	{
		// Segment is fully within range
		T[node].M += val;
		return;
	}

	int mid = (start+end)/2;
	updateRange(leftChild, start, mid, l, r, val, T);        // Updating left child
	updateRange(rightChild, mid+1, end, l, r, val, T);   // Updating right child

	
	T[node].M = max(T[leftChild].M, T[rightChild].M);
}

LL queryRange(int node, int start, int end, int l, int r, Tree *T)
{
	int leftChild  = 2*node+1;
	int rightChild = 2*node+2; 
	if(start > end || start > r || end < l) // Out of range
		return 0;   
   
	
	if(start >= l && end <= r)             // Current segment is totally within range [l, r]
		return T[node].M;

	int mid = (start + end) / 2;
	LL p1 = queryRange(leftChild, start, mid, l, r, T);         // Query left child
	LL p2 = queryRange(rightChild, mid + 1, end, l, r, T); // Query right child
	return max(p1,p2);
}


int main(void)
{
	fastIO();

	int n;
	cin >> n;

	pii v[n];

	FOR(i,0,n) cin >> v[i].fi; // altura
	FOR(i,0,n) cin >> v[i].se; // poder

	Tree T[sizeOfSegmentTree(n+1)]; // alturas


	FOR(i,0,n){
		int h = v[i].fi;
		LL x = queryRange(0,0,n,1,h-1,T);
		updateRange(0,0,n,h,h,x+v[i].se,T);
	}

	cout << queryRange(0,0,n,1,n,T) << endl;


	
}

Measured memory_bytes: 7424