CodeEff/ECCO huggingface dataset:
# Original solution


class SegmentTree:

    def __init__(self, array, aggregator):
        self.array = array
        self.aggregator = aggregator
        N = 1
        while N < len(array):
            N *= 2
        self.tree = [0]*(2*N-1)
        self.construct_tree(0, len(array)-1, 0)

    def construct_tree(self, low, high, pos):
        if low == high:
            self.tree[pos] = self.array[low]
        else:
            mid = (low+high)//2
            self.construct_tree(low, mid, 2*pos+1)
            self.construct_tree(mid+1, high, 2*pos+2)
            self.tree[pos] = self.aggregator(self.tree[2*pos+1],
                                             self.tree[2*pos+2])

    def query(self, qlow, qhigh):
        return self._query(qlow, qhigh, 0, len(self.array)-1, 0)

    def _query(self, qlow, qhigh, low, high, pos):
        if qlow <= low and high <= qhigh:
            return self.tree[pos]
        if qlow > high or qhigh < low:
            return 0
        mid = (low+high)//2
        return self.aggregator(self._query(qlow, qhigh, low, mid, 2*pos+1),
                               self._query(qlow, qhigh, mid+1, high, 2*pos+2))


    def update(self, index, value):
        self._update(index, value, 0, len(self.array)-1, 0)

    def _update(self, index, value, low, high, pos):
        if index < low or index > high:
            return
        if low == high:
            self.tree[pos] = value
        else:
            mid = (low+high)//2
            self._update(index, value, low, mid, 2*pos+1)
            self._update(index, value, mid+1, high, 2*pos+2)
            self.tree[pos] = self.aggregator(self.tree[2*pos+1], self.tree[2*pos+2])

    def __str__(self):
        start, end = 0, 1
        levels = []
        while end-1 <= len(self.tree):
            levels.append(self.tree[start:end])
            start, end = end, end+(end-start)*2
        return '\n'.join(map(str, levels))


def read_int():
    return int(input().strip())


def read_ints():
    return list(map(int, input().strip().split(' ')))


def solve():
    N = read_int()
    h = read_ints()
    a = read_ints()
    segment_tree = SegmentTree([0]*(N+1), max)
    max_beauty = 0
    for i in range(N):
        beauty = segment_tree.query(0, h[i]-1)+a[i]
        segment_tree.update(h[i], beauty)
        max_beauty = max(max_beauty, beauty)
    return max_beauty


if __name__ == '__main__':
    print((solve()))


# Optimized solution



def update(tree, index, value):
    while index < len(tree):
        tree[index] = max(tree[index], value)
        index += index & -index


def read(tree, index):
    value = 0
    while index > 0:
        value = max(value, tree[index])
        index -= index & -index
    return value


def read_int():
    return int(input().strip())


def read_ints():
    return list(map(int, input().strip().split(' ')))


def solve():
    N = read_int()
    h = read_ints()
    a = read_ints()
    tree = [0]*(N+1)
    max_beauty = 0
    for i in range(N):
        beauty = read(tree, h[i])+a[i]
        update(tree, h[i], beauty)
        max_beauty = max(max_beauty, beauty)
    return max_beauty


if __name__ == '__main__':
    print((solve()))
# Original solution
mod = 10**9+7
class RMQ:
    def __init__(self, N):
        self.N0 = 2**(N-1).bit_length()
        self.INF = float('inf')
        self.data = [self.INF]*(2*self.N0)
    def update(self, k, x):
        k+=self.N0-1
        self.data[k] = x
        while k>=0:
            k = (k-1)//2
            self.data[k] = min(self.data[2*k+1], self.data[2*k+2])
    def query(self, l, r):
        L = l+self.N0; R = r+self.N0
        s = self.INF
        while L<R:
            if R&1:
                R-=1
                s = min(s, self.data[R-1])
            if L&1:
                s = min(s, self.data[L-1])
                L+=1

            L >>= 1; R>>=1
        return s
N = int(eval(input()))
h = list(map(int, input().split()))
a = list(map(int, input().split()))
R = RMQ(N+1)
dp = [0]*N
dp[0] = a[0]
R.update(h[0], -dp[0])
for i in range(1, N):
    m = -R.query(0, h[i])
    if m == -float('inf'):
        m = 0
    dp[i] = m+a[i]
    R.update(h[i], -dp[i])
print((max(dp)))




    








# Optimized solution
mod = 10**9+7
class SegmentTree:
    def __init__(self, N, id, fun):
        self.N0 = 2**(N-1).bit_length()
        self.id = id
        self.data = [self.id]*(2*self.N0)
        self.fun = fun
    def update(self, k, x):
        k+=self.N0-1
        self.data[k] = x
        while k>=0:
            k = (k-1)//2
            self.data[k] = self.fun(self.data[2*k+1], self.data[2*k+2])
    def query(self, l, r):
        L = l+self.N0; R = r+self.N0
        s = self.id
        while L<R:
            if R&1:
                R-=1
                s = self.fun(s, self.data[R-1])
            if L&1:
                s = self.fun(s, self.data[L-1])
                L+=1
            L >>= 1; R>>=1
        return s
N = int(eval(input()))
h = list(map(int, input().split()))
a = list(map(int, input().split()))
R = SegmentTree(N+1, 0, max)
dp = [0]*N
dp[0] = a[0]
R.update(h[0], dp[0])
for i in range(1, N):
    m = R.query(0, h[i])
    dp[i] = m+a[i]
    R.update(h[i], dp[i])
print((max(dp)))
# Original solution
# coding: utf-8

import sys
input = sys.stdin.readline

def f3(n, h, a):
    dp = [0] * (n + 1)
    for i in range(1, n + 1):
        hi = h[i]
        temp = dp[hi - 1] + a[i]
        dp[hi:] = [x if x > temp else temp for x in dp[hi:]]
    return(dp[-1])

n = int(eval(input())) # 1 <= n <= 2 x 10^5
h = [0] + list(map(int, input().split()))
a = [0] + list(map(int, input().split()))

print((f3(n, h, a)))


# Optimized solution
# coding: utf-8

import sys
input = sys.stdin.readline

def f4(n, h, a):
    bit = [0] * (n + 1)

    def getmax(h):
        x = h - 1
        m = 0
        while x != 0:
            if m < bit[x]:
                m = bit[x]
            x -= x & -x
        return(m)

    def update(h, v):
        x = h
        while x <= n:
            if bit[x] < v:
                bit[x] = v
            x += x & -x

    for i in range(1, n + 1):
        m = getmax(h[i])
        update(h[i], m + a[i])
    return(max(bit))

n = int(eval(input())) # 1 <= n <= 2 x 10^5
h = [0] + list(map(int, input().split()))
a = [0] + list(map(int, input().split()))

print((f4(n, h, a)))
# Original solution
def solve(n, hhh, aaa):
    n2 = 1 << n.bit_length()
    offset = n2 - 1
    data = [0] * ((n2 << 1) - 1)

    def update(k, x):
        i = k + offset
        data[i] = max(data[i], x)
        while i:
            i = (i - 1) // 2
            data[i] = max(data[i], x)

    def get_max(a, b, i=0, l=0, r=n2):
        if b <= l or r <= a:
            return 0

        if a <= l and r <= b:
            return data[i]

        m = (l + r) // 2
        li = (i << 1) + 1
        return max(get_max(a, b, li, l, m), get_max(a, b, li + 1, m, r))

    srt = sorted((h, i) for i, h in enumerate(hhh))
    for h, i in srt:
        update(i, get_max(0, i) + aaa[i])

    return get_max(0, n2)


n = int(eval(input()))
hhh = list(map(int, input().split()))
aaa = list(map(int, input().split()))
print((solve(n, hhh, aaa)))


# Optimized solution
def solve(n, hhh, aaa):
    n2 = 1 << n.bit_length()
    offset = n2 - 1
    data = [0] * ((n2 << 1) - 1)

    def update(k, x):
        i = k + offset
        data[i] = max(data[i], x)
        while i:
            i = (i - 1) // 2
            data[i] = max(data[i], x)

    def get_max(k):
        i = k + offset
        ret = data[i]
        while i:
            if i % 2 == 0:
                ret = max(ret, data[i - 1])
            i = (i - 1) // 2
        return ret

    srt = sorted((h, i) for i, h in enumerate(hhh))
    for h, i in srt:
        update(i, get_max(i) + aaa[i])

    return data[0]


n = int(eval(input()))
hhh = list(map(int, input().split()))
aaa = list(map(int, input().split()))
print((solve(n, hhh, aaa)))
# Original solution
def f(n, hs, a_s):
    sum_a = [0] * n
    sum_a[0] = a_s[0]
    for ai, a in enumerate(a_s[1:]):
        mx = 0
        h = hs[ai + 1]
        for i in range(ai + 1):
            if h > hs[i]:
                if sum_a[i] > mx:
                    mx = sum_a[i]
        sum_a[ai + 1] = a + mx
    return sum_a[-1]


n = int(eval(input()))
hs = list(map(int, input().split()))
a_s = list(map(int, input().split()))
print((f(n, hs, a_s)))


# Optimized solution
def get(i):
    mx = 0
    while i > 0:
        if bit[i] > mx:
            mx = bit[i]
        i -= i & -i
    return mx


def update(i, x):
    while i < n + 1:
        if x > bit[i]:
            bit[i] = x
        i += i & -i


n = int(eval(input()))
hs = list(map(int, input().split()))
a_s = list(map(int, input().split()))

bit = [0] * (n + 1)
for h, a in zip(hs, a_s):
    update(h, get(h - 1) + a)
print((max(bit)))
# Original solution
def get(i):
    mx = 0
    while i > 0:
        if bit[i] > mx:
            mx = bit[i]
        i -= i & -i
    return mx


def update(i, x):
    while i < n + 1:
        if x > bit[i]:
            bit[i] = x
        i += i & -i


def f(n, hs, a_s):
    for h, a in zip(hs, a_s):
        update(h, get(h - 1) + a)
    print((max(bit)))


n = int(eval(input()))
hs = list(map(int, input().split()))
a_s = list(map(int, input().split()))
bit = [0] * (n + 1)
f(n, hs, a_s)


# Optimized solution
def get(i):
    mx = 0
    while i > 0:
        if bit[i] > mx:
            mx = bit[i]
        i -= i & -i
    return mx


def update(i, x):
    while i < n + 1:
        if x > bit[i]:
            bit[i] = x
        i += i & -i


def f(hs, a_s):
    for h, a in zip(hs, a_s):
        update(h, get(h - 1) + a)
    print((max(bit)))


n = int(eval(input()))
hs = list(map(int, input().split()))
a_s = list(map(int, input().split()))
bit = [0] * (n + 1)
f(hs, a_s)
# Original solution
import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]

class BitMax:
    def __init__(self, n):
        self.n = n + 3
        self.table = [0] * (self.n + 1)

    def update(self, i, x):
        i += 1
        while i <= self.n:
            self.table[i] = max(self.table[i], x)
            i += i & -i

    def max(self, i):
        i += 1
        res = 0
        while i > 0:
            res = max(res, self.table[i])
            i -= i & -i
        return res

def main():
    n=int(input())
    hh=LI()
    aa=LI()
    dp=BitMax(n+1)
    for h,a in zip(hh,aa):
        dp.update(h,dp.max(h-1)+a)
    print(dp.max(n))

main()


# Optimized solution
import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]

class BitMax:
    def __init__(self, n):
        self.n = n + 3
        self.table = [0] * (self.n + 1)

    def update(self, i, x):
        i += 1
        while i <= self.n:
            if x > self.table[i]: self.table[i] = x
            i += i & -i

    def max(self, i):
        i += 1
        res = 0
        while i > 0:
            if self.table[i] > res: res = self.table[i]
            i -= i & -i
        return res

def main():
    n = int(input())
    hh = LI()
    aa = LI()
    dp = BitMax(n + 1)
    for h, a in zip(hh, aa):
        dp.update(h, dp.max(h - 1) + a)
    print(dp.max(n))

main()
# Original solution
class SegTree:
    
    def __init__(self, A, intv, initialize = True):
        self.N = len(A)
        self.N0 = 2**(self.N-1).bit_length()
        self.dep = self.N0.bit_length()
        if initialize:
            self.data = [intv]*(self.N0-1) + A + [intv]*(self.N0 - self.N + 1)
            for i in range(self.N0-2, -1, -1):
                self.data[i] = max(self.data[2*i+1], self.data[2*i+2]) 
        else:
            self.data = [intv]*(2*self.N0)
    
    def segf(self, a, b):
        return max(a, b)
    
    def update(self, k, x):
        k += self.N0-1
        self.data[k] = x
        for _ in range(self.dep - 1):
            k = (k-1)//2
            self.data[k] = max(self.data[2*k+1], self.data[2*k+2])
    
    def query(self, l, r):
        L, R = l+self.N0, r+self.N0
        s = 0
        while L < R:
            if R & 1:
                R -= 1
                s = max(s, self.data[R-1])
            if L & 1:
                
                s = max(s, self.data[L-1])
                L += 1
            L >>= 1
            R >>= 1
        return s

N = int(eval(input()))
H = list(map(int, input().split()))
A = list(map(int, input().split()))

dp = SegTree([0]*(max(H)+1), 0, False)

for h, a in zip(H, A):
    dp.update(h, a+dp.query(0, h))
print((dp.data[0]))


# Optimized solution
class Segtree:
    def __init__(self, A, intv, initialize = True, segf = max):
        self.N = len(A)
        self.N0 = 2**(self.N-1).bit_length()
        self.intv = intv
        self.segf = segf
        if initialize:
            self.data = [intv]*self.N0 + A + [intv]*(self.N0 - self.N)
            for i in range(self.N0-1, 0, -1):
                self.data[i] = self.segf(self.data[2*i], self.data[2*i]) 
        else:
            self.data = [intv]*(2*self.N0)
        
    def update(self, k, x):
        k += self.N0
        self.data[k] = x
        while k > 0 :
            k = k >> 1
            self.data[k] = self.segf(self.data[2*k], self.data[2*k+1])
    
    def query(self, l, r):
        L, R = l+self.N0, r+self.N0
        s = self.intv
        while L < R:
            if R & 1:
                R -= 1
                s = self.segf(s, self.data[R])
            if L & 1:
                s = self.segf(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s

N = int(eval(input()))
H = list(map(int, input().split()))
A = list(map(int, input().split()))

dp = Segtree([0]*(max(H)+1), 0, False)

for h, a in zip(H, A):
    dp.update(h, a+dp.query(0, h))
print((dp.data[1]))
# Original solution
def solve(n, h, a):
    size = 1 << ((n + 1) - 1).bit_length()  # 元の配列サイズ以上の最小の二冪 == 最下段
    # 高さに対する美しさの最大値なので、高さ[0,n]の(n+1)要素に対して、segを考える
    seg = [0] * (size * 2 - 1)

    def update(seg, k, x):
        k += size - 1
        seg[k] = x  # 値を更新する
        while k > 0:
            k = (k - 1) // 2  # 親のindex
            seg[k] = max(seg[k * 2 + 1], seg[k * 2 + 2])

    def get(seg, a, b, k=0, l=0, r=-1):
        # [a,b)区間の処理結果を返す
        # 注目区間[l,r)
        if r < 0:
            r = size

        if r <= a or b <= l:
            return 0
        # 区間が重ならない

        if a <= l and r <= b:
            return seg[k]
        # 完全被覆

        m = (l + r) // 2
        vl = get(seg, a, b, k * 2 + 1, l, m)
        vr = get(seg, a, b, k * 2 + 2, m, r)
        return max(vl, vr)
        # 部分被覆

    for h_, a_ in zip(h, a):
        update(seg, h_, get(seg, 0, h_) + a_)
        # 1回あたり更新するのは1箇所だから、iを状態にもつ必要はなくて、配列を使い回すことができる
        # 区間maxが高速に計算できればいいから、セグメント木を使えばできる
    return get(seg, 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


# Optimized solution
def solve(n, h, a):
    size = 1 << ((n + 1) - 1).bit_length()  # 元の配列サイズ以上の最小の二冪 == 最下段
    # 高さに対する美しさの最大値なので、高さ[0,n]の(n+1)要素に対して、segを考える
    seg = [0] * (size * 2 - 1)

    def update(seg, k, x):
        k += size - 1
        seg[k] = x  # 値を更新する
        while k > 0:
            k = (k - 1) // 2  # 親のindex
            seg[k] = max(seg[k * 2 + 1], seg[k * 2 + 2])

    def get(seg, a, b, k=0, l=0, r=-1):
        # [a,b)区間の処理結果を返す
        # 注目区間[l,r)
        if r < 0:
            r = size

        if r <= a or b <= l:
            return 0
        # 区間が重ならない

        if a <= l and r <= b:
            return seg[k]
        # 完全被覆

        m = (l + r) // 2
        return max(get(seg, a, b, k * 2 + 1, l, m), get(seg, a, b, k * 2 + 2, m, r))
        # 部分被覆

    for h_, a_ in zip(h, a):
        update(seg, h_, get(seg, 0, h_) + a_)
        # 1回あたり更新するのは1箇所だから、iを状態にもつ必要はなくて、配列を使い回すことができる
        # 区間maxが高速に計算できればいいから、セグメント木を使えばできる
    return get(seg, 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
# Original solution
n = int(eval(input()))
h = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]


class Bucket:
    def __init__(self, a, k, func=max, one=-10**18):
        self.n = len(a)
        self.k = k
        self.func = func
        self.one = one

        self.a = a[:]
        self.b = []
        for i in range(self.n // self.k):
            s = self.one
            for j in range(i * self.k, i * self.k + self.k):
                s = func(s, self.a[j])
            self.b.append(s)
        s = self.one
        for i in range(self.n // self.k * self.k, self.n):
            s = self.func(s, self.a[i])
        self.b.append(s)

    def get(self, index):
        s = self.one
        j = index // self.k
        for i in range(j):
            s = self.func(s, self.b[i])
        for i in range(j * self.k, index + 1):
            s = self.func(s, self.a[i])
        return s

    def update(self, index, x):
        self.a[index] = self.func(x, self.a[index])
        self.b[index//self.k] = self.func(self.b[index//self.k], x)


buc = Bucket([0] * (n+1), 400)

for i in range(n):
    j = buc.get(h[i])
    buc.update(h[i], j + a[i])

print((buc.get(n)))


# Optimized solution
n = int(eval(input()))
h = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]


class Bucket:
    def __init__(self, a, k, func=max, one=-10**18):
        self.n = len(a)
        self.k = k
        self.func = func
        self.one = one

        self.a = a[:]
        self.b = []
        for i in range(self.n // self.k):
            s = self.one
            for j in range(i * self.k, i * self.k + self.k):
                s = func(s, self.a[j])
            self.b.append(s)
        s = self.one
        for i in range(self.n // self.k * self.k, self.n):
            s = self.func(s, self.a[i])
        self.b.append(s)

    def get(self, index):
        s = self.one
        j = index // self.k
        for i in range(j):
            s = self.func(s, self.b[i])
        for i in range(j * self.k, index + 1):
            s = self.func(s, self.a[i])
        return s

    def update(self, index, x):
        self.a[index] = self.func(x, self.a[index])
        self.b[index//self.k] = self.func(self.b[index//self.k], x)


buc = Bucket([0] * (n+1), max(10, int(n**0.5)))

for i in range(n):
    j = buc.get(h[i])
    buc.update(h[i], j + a[i])

print((buc.get(n)))
# Original solution
# -*- coding: utf-8 -*-

def main():
    import sys

    def input(): return sys.stdin.readline().strip()
    def list2d(a, b, c): return [[c] * b for i in range(a)]
    def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
    def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
    def ceil(x, y=1): return int(-(-x // y))
    def INT(): return int(eval(input()))
    def MAP(): return list(map(int, input().split()))
    def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
    def Yes(): print('Yes')
    def No(): print('No')
    def YES(): print('YES')
    def NO(): print('NO')
    sys.setrecursionlimit(10 ** 9)
    INF = 10 ** 18
    MOD = 10 ** 9 + 7

    class BIT:
        """ BIT汎用版 """

        def __init__(self, n, func, init):
            # 0-indexed
            n += 1
            nv = 1
            while nv < n:
                nv *= 2
            self.size = nv
            self.func = func
            self.init = init
            self.tree = [init] * nv

        def query(self, i):
            """ [0, i]の値を取得 """
            s = self.init
            i += 1
            while i > 0:
                s = self.func(s, self.tree[i-1])
                i -= i & -i
            return s

        def update(self, i, x):
            """ 値の更新：添字i, 値x """
            i += 1
            while i <= self.size:
                self.tree[i-1] = self.func(self.tree[i-1], x)
                i += i & -i

    N = INT()
    H = LIST()
    A = LIST()

    bit = BIT(N+1, max, 0)
    for h, a in zip(H, A):
        # ここより手前で出現した自分より低い花から、一番いいところを取る
        mx = bit.query(h)
        # 自身の最善の値を更新
        bit.update(h, mx + a)
    ans = bit.query(N)
    print(ans)
main()


# Optimized solution
# -*- coding: utf-8 -*-

def main():
    import sys

    def input(): return sys.stdin.readline().strip()
    def INT(): return int(eval(input()))
    def MAP(): return list(map(int, input().split()))
    def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
    
    def query(i):
        s = intv
        i += 1
        while i > 0:
            s = max(s, tree[i-1])
            i -= i & -i
        return s
    
    def update(i, x):
        i += 1
        while i <= size:
            tree[i-1] = max(tree[i-1], x)
            i += i & -i

    n = INT()
    H = LIST()
    A = LIST()

    n += 2
    nv = 1
    while nv < n:
        nv *= 2
    size = nv
    intv = 0
    tree = [intv] * nv

    for h, a in zip(H, A):
        mx = query(h)
        update(h, mx + a)
    ans = query(n)
    print(ans)
main()
# Original solution
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10**9)

def main():
    N = int(eval(input()))
    
    h = list(map(int,input().split()))
    a = list(map(int,input().split()))
    
    def segfunc(x,y):
        return max(x,y)
    
    def update(k,x):
        k += num-1
        seg[k] = x
        while k:
            k = (k-1)//2
            seg[k] = segfunc(seg[2*k+1],seg[2*k+2])
            
    def query(p,q):
        if q <= p:
            return ide_ele
        p += num-1
        q += num-2
        ret = ide_ele
        while q-p>1:
            if p&1 == 0:
                ret = segfunc(ret,seg[p])
            if q&1 == 1:
                ret = segfunc(ret,seg[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        ret = segfunc(segfunc(ret,seg[p]),seg[q])
        return ret
        
    ide_ele = 0
    num = 2**N.bit_length()
    seg = [ide_ele]*2*num

    
    dp = [0]*(N+1)
    
    for he,be in zip(h,a):
        tmp = query(0,he)+be
        if tmp > dp[he]:
            dp[he] = tmp
            update(he,tmp)
    
    print((max(dp)))

if __name__ == "__main__":
    main()


# Optimized solution
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10**9)

def main():
    N = int(eval(input()))
    
    h = list(map(int,input().split()))
    a = list(map(int,input().split()))
    
    def segfunc(x,y):
        return max(x,y)
    
    def update(k,x):
        k += num-1
        seg[k] = x
        while k:
            k = (k-1)//2
            seg[k] = segfunc(seg[2*k+1],seg[2*k+2])
            
    def query(p,q):
        if q <= p:
            return ide_ele
        p += num-1
        q += num-2
        ret = ide_ele
        while q-p>1:
            if p&1 == 0:
                ret = segfunc(ret,seg[p])
            if q&1 == 1:
                ret = segfunc(ret,seg[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        ret = segfunc(segfunc(ret,seg[p]),seg[q])
        return ret
        
    ide_ele = 0
    num = 2**N.bit_length()
    seg = [ide_ele]*2*num

    
    dp = [0]*(N+1)
    
    for he,be in zip(h,a):
        tmp = query(0,he)+be
        if tmp > dp[he]:
            dp[he] = tmp
            update(he,tmp)
    
    print((query(0,N+1)))

if __name__ == "__main__":
    main()