#include <bits/stdc++.h>
#ifdef __LOCAL
    #define DBG(X) cout << #X << " = " << (X) << endl;
    #define SAY(X) cout << (X) << endl;
#else
    #define DBG(X)
    #define SAY(X)
#endif

#ifdef __LOCAL
    #include <filesystem>
    namespace fs = std::filesystem;
#endif

using namespace std;

using ll = long long int;
inline void fast_io() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); };

struct flower{
  int h;
  int i;
  ll a;
  flower(int h=0, ll a=0, int i=0):h(h),a(a),i(i){}
};

int N;
vector<flower> F;
void input(){
  fast_io();
  #ifdef __LOCAL
      fs::path p = __FILE__;
      fs::path input,output;
      input = output = p.parent_path();
      input += string("/input/") + string(p.stem()) + string(".txt");
      output += string("/output/") + string(p.stem()) + string(".txt");
      freopen(input.c_str(), "r", stdin);
      freopen(output.c_str(), "w", stdout);
  #endif
  cin >> N;
  F.resize(N);
  for (int i = 0; i < N; i++){
    cin >> F[i].h;
    F[i].i = i;
  }
  for (int i = 0; i < N; i++){
    cin >> F[i].a;
  }
}

// vector<vector<ll>> dp;
vector<unordered_map<ll,ll>> dp;
vector<vector<bool>> used;

ll dfs(int i, int H){
  if(dp[i][H]) return dp[i][H];
  // used[i][H] = true;
  if(i>=N) return dp[i][H] = 0;
  ll ret = 0;
  if(F[i].h<H){
    // 高さが単調増加になるように花を抜き去る
    ret = dfs(i+1,H);
  }
  else{
    // 花を抜き去る場合と抜き去らない場合で、残りの花の美しさの大きい方をとる。
    ret = max(F[i].a+dfs(i+1,F[i].h),dfs(i+1,H));
  }
  return dp[i][H] = ret;
}

int TLE_solve(){
  // dp.assign(N+1,vector<ll>(N+1,0));
  dp.assign(N+1,unordered_map<ll,ll>());
  // used.assign(N+1,vector<bool>(N+1,0));
  // cout << dfs(0,0) << endl;
  dp[0][0] = 0;
  for (int i = 0; i < N; i++)
  {
    for(auto d:dp[i]){
      int h = d.first;
      dp[i+1][h] = d.second;
      if(F[i].h<h) continue;
      dp[i+1][F[i].h] = max(dp[i+1][F[i].h],F[i].a+dp[i][h]);
    }
  }
  ll ans=0;
  for (int i = 0; i <= N; i++)
  {
    ans = max(ans,dp[N][i]);
  }
  cout << ans << endl;
  return 0;
}

template< typename Monoid >
struct SegmentTree {
  using F = function< Monoid(Monoid, Monoid) >;

  int sz;
  vector< Monoid > seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) {
    seg[k + sz] = x;
  }

  void build() {
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) L = f(L, seg[a++]);
      if(b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const {
    return seg[k + sz];
  }

  template< typename C >
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while(a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if(check(nxt)) a = 2 * a + type;
      else M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }


  template< typename C >
  int find_first(int a, const C &check) {
    Monoid L = M1;
    if(a <= 0) {
      if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) {
        Monoid nxt = f(L, seg[a]);
        if(check(nxt)) return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template< typename C >
  int find_last(int b, const C &check) {
    Monoid R = M1;
    if(b >= sz) {
      if(check(f(seg[1], R))) return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for(b += sz; a < b; a >>= 1, b >>= 1) {
      if(b & 1) {
        Monoid nxt = f(seg[--b], R);
        if(check(nxt)) return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};


int solve(){
  sort(F.begin(),F.end(),[](flower a, flower b){return a.h < b.h;});
  SegmentTree<ll> seg(N+1, [](ll a, ll b) { return max(a, b); }, 0LL);
  for (int i = 0; i < N; i++)
  {
    int idx = F[i].i;
    ll va = F[i].a;
    ll ma = seg.query(0,idx+1);
    seg.update(idx,ma+va);
  }
  cout << seg.query(0,N) << endl;
  return 0;
}

int main()
{
  // maketestcase(400);
  input();
  solve();
  return 0;
}


Measured memory_bytes: 7552