#include <bits/stdc++.h>
using namespace std; 
using ll = long long;
#define int ll
#define MOD ll(1e9+7)
vector<ll> memo(2e6+1e5, -1);
#define int ll

struct MaxSegmentTree {
    private:
    vector<int> v; // vettore che contiene l'albero
    vector<int> u; // vettore di update
    int n; //numero nodi interni
    const int NULL_VALUE = 0; //zero dell'operazione
    public:
    MaxSegmentTree(int num) {
        v.resize((1 << (int)(ceil(log2(num))+1))-1, NULL_VALUE);//completo bilanciato
        u.resize(v.size(), NULL_VALUE);
        n = v.size() / 2;
    }

    MaxSegmentTree(vector<int> &source) {
        v.resize((1 << (int)(ceil(log2(source.size()))+1))-1, NULL_VALUE);//completo bilanciato
        u.resize(v.size(), NULL_VALUE);
        n = v.size() / 2;
        for (int i = 0; i < source.size(); i++) {
            v[i + n] = source[i];
        }
        for (int i = n - 1; i >= 0; i--) {
            updateNode(i);
        }
    }
    private:
    int left(int i) {
        return i*2+1;
    }

    int right(int i) {
        return i*2+2;
    }

    int parent(int i) {
        return (i - 1) / 2;
    }

    int mergeValues(int v1, int v2) {
        return max(v1,v2);
    }

    void updateNode(int i) {
        v[i] = mergeValues(v[left(i)], v[right(i)]);
    }

    void lazyUpdate(int i) {
        if (u[i] != 0) {
            v[i] += u[i];
            if (i < v.size() / 2) {
                u[left(i)] += u[i] / 2;
                u[right(i)] += u[i] / 2;
            }
            u[i] = 0;
        }
    }

    int rangeQuery(int i, int l, int r, int a, int b) {
        lazyUpdate(i); //Aggiornamento in lettura

        if (l >= a && r <= b) {
            return v[i];
        }
        if (r < a || l > b) {
            return NULL_VALUE;
        }
        int m = (l + r) / 2;
        return mergeValues(rangeQuery(left(i), l, m, a, b), rangeQuery(right(i), m + 1, r, a, b));
    }

    void updateToRoot(int i) {
        updateNode(i);
        if (i != 0) {
            updateToRoot(parent(i));
        }
    }

    void rangeAdd(int i, int a, int b, int l, int r, int off) {
        lazyUpdate(i);

        if (l >= a && r <= b) {
            u[i] += off * (r - l + 1);
            lazyUpdate(i);

        } else if (!(r < a || l > b)) { //overlap parziale
            int m = (l + r) / 2;
            rangeAdd(left(i), a, b, l , m, off);
            rangeAdd(right(i), a, b, m + 1, r, off);
            updateNode(i);
        }
    }

    public:

    int rangeSum(int a, int b) {
        return rangeQuery(0, 0, n, a, b);
    }

    void update(int index, int value) {
        int i = n + index;
        v[i] = value;
        updateToRoot(parent(i));
    }

    void rangeUpdate(int a, int b, int offset) {
        rangeAdd(0, a, b, 0, n, offset);
    }

    int search(int i, int x){
    	if(i >= v.size()/2)
    		return v[i];
    	if(v[i] < x)
    		return -1;
    	if(v[left(i)] >= x){
    		search(left(i), x);
    	}else{
    		search(right(i), x);
    	}
    }

    void print() {
        int i = 0;
        int livNum = 1;
        while (i < v.size()) {
            for (int j = 0; j < livNum; j++) {
                cout << v[i] << "(" << u[i] << ")" << " ";
                i++;
            }
            livNum *= 2;
            cout << "\n";
        }
    }
};


signed main() { 
	cin.tie(0);
	cin.sync_with_stdio();
	int n; 
	cin>>n;
	vector<int> v(n);
	vector<int> a(n);
	vector<int> g(n);
	for(int &i : v)
		cin>>i;
	for(int &i : a)
		cin>>i;
	vector<int> c = v;
	map<int, int> m;
	map<int, int> b;
	sort(c.begin(), c.end());
	vector<int> e(n), ee(n);
	MaxSegmentTree sst(ee);
	int nxt = 0;
	for(int i : c){
		m[i] = nxt;
		b[nxt] = i;
		nxt++;
	}
	ll ma = 0;
	for(int i = 0; i < n; i++){
		int prev = sst.rangeSum(0, m[v[i]]);
		sst.update(m[v[i]], a[i]+prev);
		ma = max(ma, a[i]+prev);
	}
	cout<<ma;
}


Measured memory_bytes: 59264