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

// MY TOOLS
#define let long long int
#define async ios_base::sync_with_stdio(false);cin.tie(NULL);
#define i_upto( n ) for( int i = 0 ; i < n ; i++ )
#define ij_upto( n, m ) for( int i = 0 ; i < n ; i++ ) for( int j = 0 ; j < m ; j++ )
template<class T>
T ** array2D( let R , let C ){
	T ** t = new T * [R] ;
	for( int i = 0 ; i < R ; i++ ){
		t[i] = new T[C] ;
	}
	return t ;
}
template<class T>
T ** array2D( let R , let C, T value ){
	T ** t = new T * [R] ;
	for( int i = 0 ; i < R ; i++ ){
		t[i] = new T[C] ;
	}
    ij_upto( R, C ) t[i][j] = value ;
	return t ;
}
template<class T>
T * array1D( let N, T value ){
    T * t = new T[N] ;
    i_upto(N) t[i] = value ;
    return t ;
}
template<class T>
T * array1D( let N ){
    T * t = new T[N] ;
    return t ;
}
template<class T>
vector<vector<T>> vector2D( let N, let M ){
	return vector<vector<T>>(N,vector<T>(M)) ;
}
template<class T>
vector<vector<T>> vector2D( let N, let M, T Value ){
	return vector<vector<T>>(N,vector<T>(M,Value)) ;
}
#define then ;
#define vector2D( t ) vector<vector<t>>
template<class T>
class matrix{
	T ** v ;
	let rows, cols ;
	public :
		matrix( let n, let m ){
			v = array2D<T>( n, m ) ;
			rows = n ;
			cols = m ;
		}
		void input(){
			ij_upto( rows, cols ) cin >> v[i][j] ;
		}
		T& at( let i, let j ){
			return v[i][j] ;
		}
		T* at( let i ){
			return v[i] ;
		}
		void set( let i, let j, T value ){
			v[i][j] = value ;
		}
		void output(){
			for( let i = 0 ; i < rows ; i++ ){
				for( let j = 0 ; j < cols ; j++ ){
					cout << v[i][j] << " " ;
				}
				cout << endl ;
			}
		}
		void fill( T value ){
			ij_upto( rows, cols ) v[i][j] = value ;
		}
		T ** begin(){
			return v ;
		}
		T ** end(){
			return v + rows ;
		}
};
//
class SegmentedTree{
    public :
    let * st ;
    let * arr ;
    let size ;
    let st_size ;
    SegmentedTree( let * Arr , let n ){
        arr = new let [n] ;
        for( int i = 0 ; i < n ; i++ ) arr[i] = Arr[i] ;
        size = n ;
        let temp = int(ceil(log2( n ))) ;
        st_size = 2*int(pow( 2, temp )) - 1 ;
        st = new let[ st_size ] ; 
        build( 0, size-1, 0 ) ;
    }
    let getMid( let ss, let se ){
        return ss + ( se - ss ) / 2 ;
    }
    let build( let ss, let se, let cp ){
        if( ss == se ){
            st[cp] = arr[ ss ] ;
            return st[ cp ] ;
        }
        let mid = getMid( ss, se ) ;
        st[cp] = max(
                        build( ss, mid, 2*cp+1 ),
                        build( mid+1, se, 2*cp+2 )
                    ) ;
        return st[cp] ;
    }
    let getMax( let qs, let qe ){
        return getMaxUtil( qs, qe, 0, size-1, 0 ) ;
    }
    bool outside( let qs, let qe, let ss, let se ){
        if( qs > se || qe < ss ) return true ;
        return false ;
    }
    bool totallyInside( let qs, let qe, let ss, let se ){
        if( qs <= ss && qe >= se ) return true ;
        return false ;
    }
    bool partiallyInside( let qs, let qe, let ss, let se ){
        return ! outside( qs, qe, ss, se ) && ! partiallyInside( qs, qe, ss, se ) ;
    }
    let getMaxUtil( let qs, let qe, let ss, let se, let cp ){
        if( totallyInside(qs, qe, ss, se ) ) return st[cp] ;
        if( outside(qs, qe, ss, se ) ) return 0 ;
        let mid = getMid( ss, se ) ;
        return max( getMaxUtil(qs, qe, ss, mid, 2*cp+1), getMaxUtil(qs, qe, mid+1, se, 2*cp+2) ) ;
    }
    void updateUtil( let ss, let se, let cp, let new_value, let pos  ){
        if( pos < ss || pos > se  ){
            return ;
        }
        if( ss == se ){
            st[cp] = new_value ;
            arr[pos] = new_value ;
            return ;
        }
        let mid = getMid( ss, se ) ;
        if( pos >= ss && pos <= mid )
        updateUtil( ss, mid, 2*cp+1, new_value, pos ) ;
        else
        updateUtil( mid+1, se, 2*cp+2, new_value, pos ) ;
        st[cp] = max( st[2*cp+1], st[2*cp+2] ) ;
        return ;
    }
    void update( let pos, let new_value ){
        arr[pos] = new_value ;
        updateUtil( 0, size-1, 0, new_value, pos ) ;
    }
    
};
// 0 -> height, 1 -> value, 2 -> orignal_index 
// main
// write your code here
int main(){
	async ;
	let N then cin >> N ;
	matrix<let> flowers( N, 3 ) ;
	for( int i = 0 ; i < N ; i++ ) cin >> flowers.at( i, 0 ) ;
	for( int i = 0 ; i < N ; i++ ) {
		cin >> flowers.at( i, 1 ) ;
		flowers.at( i, 2 ) = i ;
	}
	sort( flowers.begin(), flowers.end(),
	 			[]( let * a , let * b ) {
					 return a[0] < b[0] ; 
				 } 
		) ;
	let * arr = new let[N] ;
	for( int i = 0 ; i < N ; i++ ) arr[i] = 0 ;
	SegmentedTree dp( arr, N ) ;
	for( int i = 0 ; i < N ; i++ ){
		auto pick = flowers.at( i ) ;
		let value = pick[1] ;
		let index = pick[2] ;
		let max_value_before_me = dp.getMax(0, index-1) ;
		dp.update( index, max_value_before_me + value ) ;
	}
	cout << dp.getMax( 0, N-1 ) ;
    return 0 ;
}

Measured memory_bytes: 19116