#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define ranger(i, a, b) for (int i = (a)-1; i >= (b); i--)
#define repr(i, b) for (int i = (b)-1; i >= 0; i--)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
#define int long long
using namespace std;

template <typename X, typename T>
auto vectors(X x, T a) {
	return vector<T>(x, a);
}
template <typename X, typename Y, typename Z, typename... Zs>
auto vectors(X x, Y y, Z z, Zs... zs) {
	auto cont = vectors(y, z, zs...);
	return vector<decltype(cont)>(x, cont);
}

template <typename T>
ostream& operator<<(ostream& os, vector<T>& v) {
	rep(i, v.size()) { os << v[i] << (i == v.size() - 1 ? "" : " "); }
	return os;
}
template <typename T, typename S>
ostream& operator<<(ostream& os, pair<T, S>& p) {
	os << '(' << p.first << ',' << p.second << ')';
	return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	for (T& x : v) { is >> x; }
	return is;
}

struct RMQ {
	using T = int;
	T operator()(const T& a, const T& b) { return max(a, b); };
	static constexpr T identity() { return 0; }
};

template <class Monoid>
class rangeUpdateQuery {
  private:
	using T = typename Monoid::T;
	Monoid op;
	const int n;
	vector<T> dat, lazy;
	T query(int a, int b, int k, int l, int r) {
		evaluate(k);

		if (b <= l || r <= a)
			return op.identity();
		else if (a <= l && r <= b)
			return dat[k];
		else {
			int vl = query(a, b, k * 2, l, (l + r) / 2);
			int vr = query(a, b, k * 2 + 1, (l + r) / 2, r);
			return op(vl, vr);
		}
	}
	inline void evaluate(int k) {
		if (lazy[k] == op.identity()) return;
		dat[k] = lazy[k];
		if (k < n) {
			lazy[2 * k] = lazy[k];
			lazy[2 * k + 1] = lazy[k];
		}
		lazy[k] = op.identity();
	}
	inline void propTo(int k) { dat[k] = op(dat[2 * k], dat[2 * k + 1]); }
	void update(int a, int b, int k, int l, int r, T x) {
		evaluate(k);
		if (r <= a || b <= l) return;
		if (a <= l && r <= b) {
			lazy[k] = x;
			evaluate(k);
		} else if (l < b && a < r) {
			update(a, b, k * 2, l, (l + r) / 2, x);
			update(a, b, k * 2 + 1, (l + r) / 2, r, x);
			propTo(k);
			evaluate(k);
		}
	}
	int power(int n) {
		int res = 1;
		while (n >= res) res *= 2;
		return res;
	}

  public:
	rangeUpdateQuery(int n)
		: n(power(n)), dat(4 * n, op.identity()), lazy(4 * n, op.identity()) {}
	rangeUpdateQuery(const vector<T>& v)
		: n(power(v.size())), dat(4 * n), lazy(4 * n, op.identity()) {
		copy(begin(v), end(v), begin(dat) + n);
		for (int i = n - 1; i > 0; i--) propTo(i);
	}
	T query(int a, int b) { return query(a, b, 1, 0, n); }
	void update(int s, int t, int x) { update(s, t, 1, 0, n, x); }
	T get(int a) { return query(a, a + 1); };
	void out(int n) {
		rep(i, n + 1) { cout << get(i) << ' '; }
		cout << endl;
		// rep(i,n){ range(j,i,n){ cout << i << ' ' << j + 1 << ' ' << query(i +
		// 0,j + 1) << endl; } }
	}
	void out() {
		rep(i, n * 2) { cout << i << " " << dat[i + 1] << endl; }
	}
};

signed main() {
	int n;
	cin >> n;

	vector<int> h(n), a(n);
	cin >> h >> a;

	rangeUpdateQuery<RMQ> s(n);
	rep(i, n) {
		int res = s.query(0, h[i]) + a[i];
		s.update(h[i], h[i] + 1, res);
	}

	cout << s.query(0,n + 1) << endl;
}


Measured memory_bytes: 15872