class SegmentTree:

    def __init__(self, a: list, e: 'default', f: 'function'):

        n = len(a)

        size = 1 << (n - 1).bit_length()  # 元の配列サイズ以上の最小の二冪 == 最下段

        v = [e] * (size * 2 - 1)

        for i in range(n):

            # size-1個の上段の次、size個目からn個が元の配列の代入位置

            v[size - 1 + i] = a[i]

        for i in range(size - 2, -1, -1):

            v[i] = f(v[i * 2 + 1], v[i * 2 + 2])



        self.n = n  # 元の配列の長さ

        self.size = size  # 元の配列サイズ以上の最小の二冪 == 最下段の要素数

        self.v = v  # Segtreeの配列

        self.e = e  # 初期値

        self.f = f  # 比較関数



    def update(self, k: 'index', x: 'val'):

        k += self.size - 1  # 最下段のindexに変更する

        self.v[k] = x  # 値を更新する

        while k > 0:

            k = (k - 1) // 2  # 親のindex

            self.v[k] = self.f(self.v[k * 2 + 1], self.v[k * 2 + 2])



    def get(self, a, b, k=0, l=0, r=-1):

        # [a,b)区間の処理結果を返す

        # 注目区間[l,r)

        if r < 0:

            r = self.size



        if r <= a or b <= l:

            return self.e

        # 区間が重ならない



        if a <= l and r <= b:

            return self.v[k]

        # 完全被覆



        m = (l + r) // 2

        return self.f(self.get(a, b, k * 2 + 1, l, m), self.get(a, b, k * 2 + 2, m, r))

        # 部分被覆





def solve(n, h, a):

    seg = SegmentTree([0] * (n + 1), 0, max)

    for i in range(n):

        seg.update(h[i], seg.get(0, h[i]) + a[i])

        # 1回あたり更新するのは1箇所だから、iを状態にもつ必要はなくて、配列を使い回すことができる

        # 区間maxが高速に計算できればいいから、セグメント木を使えばできる

    return seg.get(0, n + 1)





if __name__ == '__main__':

    import sys



    input = sys.stdin.readline



    n = int(eval(input()))

    h = tuple(map(int, input().split()))

    a = tuple(map(int, input().split()))

    print((solve(n, h, a)))



# https://kyopro-friends.hatenablog.com/entry/2019/01/12/231035

# classやめた方が遅かった

# 比較関数minがグローバルにあるから、遅くなっていた？



class SegmentTree:

    def __init__(self, a: list, e: 'default' = 0, f: 'function' = max):

        size = len(a)

        n = 1 << (size - 1).bit_length()

        seg = [e] * (n * 2 - 1)

        for i, a_ in enumerate(a, n - 1):

            seg[i] = a_

        for i in range(n - 2, -1, -1):

            seg[i] = f(seg[i * 2 + 1], seg[i * 2 + 2])

        self.size = size

        self.n = n

        self.seg = seg

        self.a = a

        self.e = e

        self.f = f



    def update(self, k, x):

        n = self.n

        seg = self.seg

        f = self.f



        k += n - 1

        seg[k] = x

        while k > 0:

            k = (k - 1) // 2

            seg[k] = f(seg[k * 2 + 1], seg[k * 2 + 2])



    def query(self, a, b, k=0, l=0, r=-1):

        if r < 0:

            r = self.n

        if r <= a or b <= l:

            return self.e

        if a <= l and r <= b:

            return self.seg[k]

        m = (l + r) // 2

        vl = self.query(a, b, k * 2 + 1, l, m)

        vr = self.query(a, b, k * 2 + 2, m, r)

        return self.f(vl, vr)





n = int(eval(input()))

h = tuple(map(int, input().split()))

a = tuple(map(int, input().split()))



dp = [0] * (n + 1)

# dp[j] := 末尾jの単調増加列の美しさの総和の最大値



seg = SegmentTree(a=dp, e=0, f=max)



for h_, a_ in zip(h, a):

    # i本目を取って末尾にするとき

    max_ = seg.query(0, h_) + a_

    seg.update(h_, max_)

print((seg.query(0, n + 1)))
class SegmentTree:
    def __init__(self, a: list, e: "default", f: "function"):
        n = len(a)
        size = 1 << (n - 1).bit_length()  # 元の配列サイズ以上の最小の二冪 == 最下段
        v = [e] * (size * 2 - 1)
        for i in range(n):
            # size-1個の上段の次、size個目からn個が元の配列の代入位置
            v[size - 1 + i] = a[i]
        for i in range(size - 2, -1, -1):
            v[i] = f(v[i * 2 + 1], v[i * 2 + 2])
        self.n = n  # 元の配列の長さ
        self.size = size  # 元の配列サイズ以上の最小の二冪 == 最下段の要素数
        self.v = v  # Segtreeの配列
        self.e = e  # 初期値
        self.f = f  # 比較関数

    def update(self, k: "index", x: "val"):
        k += self.size - 1  # 最下段のindexに変更する
        self.v[k] = x  # 値を更新する
        while k > 0:
            k = (k - 1) // 2  # 親のindex
            self.v[k] = self.f(self.v[k * 2 + 1], self.v[k * 2 + 2])

    def get(self, a, b, k=0, l=0, r=-1):
        # [a,b)区間の処理結果を返す
        # 注目区間[l,r)
        if r < 0:
            r = self.size
        if r <= a or b <= l:
            return self.e
        # 区間が重ならない
        if a <= l and r <= b:
            return self.v[k]
        # 完全被覆
        m = (l + r) // 2
        return self.f(self.get(a, b, k * 2 + 1, l, m), self.get(a, b, k * 2 + 2, m, r))
        # 部分被覆


def solve(n, h, a):
    seg = SegmentTree([0] * (n + 1), 0, max)
    for i in range(n):
        seg.update(h[i], seg.get(0, h[i]) + a[i])
        # 1回あたり更新するのは1箇所だから、iを状態にもつ必要はなくて、配列を使い回すことができる
        # 区間maxが高速に計算できればいいから、セグメント木を使えばできる
    return seg.get(0, n + 1)


if __name__ == "__main__":
    import sys

    input = sys.stdin.readline
    n = int(eval(input()))
    h = tuple(map(int, input().split()))
    a = tuple(map(int, input().split()))
    print((solve(n, h, a)))
# https://kyopro-friends.hatenablog.com/entry/2019/01/12/231035
# classやめた方が遅かった
# 比較関数minがグローバルにあるから、遅くなっていた？

class SegmentTree:
    def __init__(self, a: list, e: "default" = 0, f: "function" = max):
        size = len(a)
        n = 1 << (size - 1).bit_length()
        seg = [e] * (n * 2 - 1)
        for i, a_ in enumerate(a, n - 1):
            seg[i] = a_
        for i in range(n - 2, -1, -1):
            seg[i] = f(seg[i * 2 + 1], seg[i * 2 + 2])
        self.size = size
        self.n = n
        self.seg = seg
        self.a = a
        self.e = e
        self.f = f

    def update(self, k, x):
        n = self.n
        seg = self.seg
        f = self.f
        k += n - 1
        seg[k] = x
        while k > 0:
            k = (k - 1) // 2
            seg[k] = f(seg[k * 2 + 1], seg[k * 2 + 2])

    def query(self, a, b, k=0, l=0, r=-1):
        if r < 0:
            r = self.n
        if r <= a or b <= l:
            return self.e
        if a <= l and r <= b:
            return self.seg[k]
        m = (l + r) // 2
        vl = self.query(a, b, k * 2 + 1, l, m)
        vr = self.query(a, b, k * 2 + 2, m, r)
        return self.f(vl, vr)


n = int(eval(input()))
h = tuple(map(int, input().split()))
a = tuple(map(int, input().split()))
dp = [0] * (n + 1)
# dp[j] := 末尾jの単調増加列の美しさの総和の最大値
seg = SegmentTree(a=dp, e=0, f=max)
for h_, a_ in zip(h, a):
    # i本目を取って末尾にするとき
    max_ = seg.query(0, h_) + a_
    seg.update(h_, max_)
print((seg.query(0, n + 1)))

-    def __init__(self, a: list, e: "default", f: "function"): -        n = len(a) -        size = 1 << (n - 1).bit_length()  # 元の配列サイズ以上の最小の二冪 == 最下段 -        v = [e] * (size * 2 - 1) -        for i in range(n): -            # size-1個の上段の次、size個目からn個が元の配列の代入位置 -            v[size - 1 + i] = a[i] -        for i in range(size - 2, -1, -1): -            v[i] = f(v[i * 2 + 1], v[i * 2 + 2]) -        self.n = n  # 元の配列の長さ -        self.size = size  # 元の配列サイズ以上の最小の二冪 == 最下段の要素数 -        self.v = v  # Segtreeの配列 -        self.e = e  # 初期値 -        self.f = f  # 比較関数 +    def __init__(self, a: list, e: "default" = 0, f: "function" = max): +        size = len(a) +        n = 1 << (size - 1).bit_length() +        seg = [e] * (n * 2 - 1) +        for i, a_ in enumerate(a, n - 1): +            seg[i] = a_ +        for i in range(n - 2, -1, -1): +            seg[i] = f(seg[i * 2 + 1], seg[i * 2 + 2]) +        self.size = size +        self.n = n +        self.seg = seg +        self.a = a +        self.e = e +        self.f = f -    def update(self, k: "index", x: "val"): -        k += self.size - 1  # 最下段のindexに変更する -        self.v[k] = x  # 値を更新する +    def update(self, k, x): +        n = self.n +        seg = self.seg +        f = self.f +        k += n - 1 +        seg[k] = x -            k = (k - 1) // 2  # 親のindex -            self.v[k] = self.f(self.v[k * 2 + 1], self.v[k * 2 + 2]) +            k = (k - 1) // 2 +            seg[k] = f(seg[k * 2 + 1], seg[k * 2 + 2]) -    def get(self, a, b, k=0, l=0, r=-1): -        # [a,b)区間の処理結果を返す -        # 注目区間[l,r) +    def query(self, a, b, k=0, l=0, r=-1): -            r = self.size +            r = self.n -        # 区間が重ならない -            return self.v[k] -        # 完全被覆 +            return self.seg[k] -        return self.f(self.get(a, b, k * 2 + 1, l, m), self.get(a, b, k * 2 + 2, m, r)) -        # 部分被覆 +        vl = self.query(a, b, k * 2 + 1, l, m) +        vr = self.query(a, b, k * 2 + 2, m, r) +        return self.f(vl, vr) -def solve(n, h, a): -    seg = SegmentTree([0] * (n + 1), 0, max) -    for i in range(n): -        seg.update(h[i], seg.get(0, h[i]) + a[i]) -        # 1回あたり更新するのは1箇所だから、iを状態にもつ必要はなくて、配列を使い回すことができる -        # 区間maxが高速に計算できればいいから、セグメント木を使えばできる -    return seg.get(0, n + 1) - - -if __name__ == "__main__": -    import sys - -    input = sys.stdin.readline -    n = int(eval(input())) -    h = tuple(map(int, input().split())) -    a = tuple(map(int, input().split())) -    print((solve(n, h, a))) -# https://kyopro-friends.hatenablog.com/entry/2019/01/12/231035 -# classやめた方が遅かった -# 比較関数minがグローバルにあるから、遅くなっていた？ +n = int(eval(input())) +h = tuple(map(int, input().split())) +a = tuple(map(int, input().split())) +dp = [0] * (n + 1) +# dp[j] := 末尾jの単調増加列の美しさの総和の最大値 +seg = SegmentTree(a=dp, e=0, f=max) +for h_, a_ in zip(h, a): +    # i本目を取って末尾にするとき +    max_ = seg.query(0, h_) + a_ +    seg.update(h_, max_) +print((seg.query(0, n + 1)))