//   //  /////       ///      
//  //   //  //     // //     
// //    //   //   //   //    
////     //   //  //     //   
// //    //   //  /////////    
//  //   //  //   //     //    
//   //  /////    //     //    

#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define iter(it,a,b) for(a::iterator it=b.begin(); it!=b.end();++it)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (binary me 1 kitne hai) (if longlong popcount ll)
#define ln "\n"
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define dbg2(x,y) cerr<<#x<<" = "<<x<<" & "<<#y<<" = "<<y<<endl;
#define dbgstl32(v) cerr<<#v<<" = \n"; { int c=0; forstl(it,v) \
cerr<<"    Term "<< ++c <<" = "<<it<<ln;} cerr<<endl
#define dbgstlp32(v) cerr<<#v<<" = \n"; { int c=0; forstl(it,v) \
cerr<<"    Term "<< ++c <<" = "<<it.fi<<" , "<<it.se<<ln;} cerr<<endl
#define dbgarr(v,s,e) cerr<<#v<<" = "; forsn(i,s,e) cerr<<v[i]<<", "; cerr<<endl
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(n) n.begin() , n.end() 
#define tfi first.first
#define tse first.second
#define tth second
typedef long long ll;
typedef long double ld;
typedef pair<int,int> p32; 
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef pair< pair<int,int> , int> tri;
typedef vector<bool> vbool;
typedef priority_queue<p32> pq32;
typedef priority_queue<p32, vector<p32>, greater<p32> > pq32l;

#pragma GCC optimize ("-O2")
const ll LIM = 2e5+5;
const ll MOD = 1e9+7;
const ll inf = 1e10;

void segment_tree(v64& a, v64& t, int v, int tl, int tr){

	// RESIZE t to 4*n
	// a is the array and t is the segment tree made from array
	// initialise v = 1
	// tl and tr are bounds
	// initially tl = 0 and tr = n-1

	if(tl==tr) t[v] = a[tl];
	else{
		int tm = (tl+tr)/2;

		segment_tree(a, t, 2*v, tl, tm);             // left child
		segment_tree(a, t, 2*v + 1, tm+1, tr);       // right child

		t[v] = max(t[2*v], t[2*v + 1]);                  // the function we want 
	}
}

void update(v64& t, int pos, ll new_val, int v, int tl, int tr){

	// pos is the position that is to be updated

	if(tl==tr) t[v] = new_val;
	else{
		int tm = (tl+tr)/2;

		if(pos <= tm) update(t, pos, new_val, 2*v, tl, tm);
		else update(t, pos, new_val, 2*v + 1, tm+1, tr);

		t[v] = max(t[2*v], t[2*v + 1]);                  // the function we want
	}
}

ll query(v64& t, int v, int tl, int tr, int l, int r){

	// tl and tr are our intervals we get while processing
	// l and r are the intervals we require
	// tl = 0 and tr = n-1 and v = 1 at start

	if(l>r) return 0;                                // thing you want to return in this case like 0 for sum

	if(l==tl && r==tr) return t[v];
	else{
		int tm = (tl+tr)/2;
		return max(query(t, 2*v, tl, tm, l, min(r,tm)), query(t, 2*v + 1, tm+1, tr, max(l,tm+1), r));
	}
}

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

	int n;
	cin >> n;

	int h[n];
	forn(i,n){ cin >> h[i]; h[i]--; }

	ll a[n];
	forn(i,n) cin >> a[i];

	v64 init(n,0);
	v64 t(4*n);

	segment_tree(init, t, 1, 0, n-1);

	ll maxval = 0;

	forn(i,n){
		ll x = query(t, 1, 0, n-1, 0, h[i]);
		x = x + a[i];
		maxval = max(maxval, x);
		update(t, h[i], x, 1, 0, n-1);
	}

	cout << maxval;

}


Measured memory_bytes: 10368