CodeEff/ECCO huggingface dataset:
# Original solution
N = int(eval(input()))
H = list(map(int,input().split()))
A = list(map(int,input().split()))

class SegTreeMax:
    def __init__(self,arr):
        n = 1
        while n < len(arr):
            n *= 2
        self.n = n
        nodes = [0]*(2*n-1)
        nodes[n-1:n-1+len(arr)] = arr
        for i in range(n-2,-1,-1):
            nodes[i] = max(nodes[2*i+1],nodes[2*i+2])
        self.nodes = nodes

    def update(self,i,val):
        i += self.n-1
        self.nodes[i] = val
        while i:
            i = (i-1)//2
            self.nodes[i] = max(self.nodes[2*i+1:2*i+3])

    def query(self,a,b,k=0,l=0,r=-1):
        if r < 0: r = self.n
        if r <= a or b <= l: return 0
        if a <= l and r <= b: return self.nodes[k]
        return max(self.query(a,b,2*k+1,l,(l+r)//2), self.query(a,b,2*k+2,(l+r)//2,r))

segt = SegTreeMax([0]*N)
ans = 0
for h,a in zip(H,A):
    v = segt.query(0,h) + a
    segt.update(h-1,v)
    ans = max(ans, v)
print(ans)

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

class SegTreeMax:
    def __init__(self,arr):
        n = 1
        while n < len(arr):
            n *= 2
        self.n = n
        nodes = [0]*(2*n-1)
        nodes[n-1:n-1+len(arr)] = arr
        for i in range(n-2,-1,-1):
            nodes[i] = max(nodes[2*i+1],nodes[2*i+2])
        self.nodes = nodes

    def update(self,i,val):
        i += self.n-1
        self.nodes[i] = val
        while i:
            i = (i-1)//2
            self.nodes[i] = max(self.nodes[2*i+1],self.nodes[2*i+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 0
        if a <= l and r <= b: return self.nodes[k]
        return max(self.query(a,b,2*k+1,l,(l+r)//2), self.query(a,b,2*k+2,(l+r)//2,r))

segt = SegTreeMax([0]*N)
ans = 0
for h,a in zip(H,A):
    v = segt.query(0,h) + a
    segt.update(h-1,v)
    ans = max(ans, v)
print(ans)
# Original solution
import operator


class SegmentTree:
    def __init__(self, seq, op=operator.add):
        self.n = len(seq)
        self.op = op
        self.tree = [-1] * self.n + seq
        for i in reversed(list(range(1, self.n))):
            self.tree[i] = op(self.tree[2*i], self.tree[2*i+1])

    def modify(self, pos, val):
        assert pos < self.n
        pos += self.n
        self.tree[pos] = val
        while pos > 1:
            self.tree[pos//2] = self.op(self.tree[pos], self.tree[pos ^ 1])
            pos //= 2

    def query(self, L, R):
        assert L <= R and L >= 0 and R <= self.n
        res = 0
        L += self.n
        R += self.n
        while L < R:
            if L % 2 == 1:
                res = self.op(res, self.tree[L])
                L += 1
            if R % 2 == 1:
                R -= 1
                res = self.op(res, self.tree[R])

            L //= 2
            R //= 2

        return res


def solve(n, heights, beauty):
    st = SegmentTree([0] * (n+1), op = lambda x, y: max(x, y))

    for flower in range(n):
        st.modify(heights[flower], st.query(0, heights[flower] + 1) + beauty[flower])

    return st.tree[1]


def main():
    n = int(eval(input()))
    heights = [int(c) for c in input().split()]
    beauty = [int(c) for c in input().split()]
    ans = solve(n, heights, beauty)
    print(ans)


if __name__ == "__main__":
    main()


# Optimized solution
import operator


class SegmentTree:
    def __init__(self, seq, op=operator.add):
        self.n = len(seq)
        self.op = op
        self.tree = [-1] * self.n + seq
        for i in reversed(list(range(1, self.n))):
            self.tree[i] = op(self.tree[2*i], self.tree[2*i+1])

    def modify(self, pos, val):
        assert pos < self.n
        pos += self.n
        self.tree[pos] = val
        while pos > 1:
            self.tree[pos//2] = self.op(self.tree[pos], self.tree[pos ^ 1])
            pos //= 2

    def query(self, L, R):
        assert L <= R and L >= 0 and R <= self.n
        res = 0
        L += self.n
        R += self.n
        while L < R:
            if L % 2 == 1:
                res = self.op(res, self.tree[L])
                L += 1
            if R % 2 == 1:
                R -= 1
                res = self.op(res, self.tree[R])

            L //= 2
            R //= 2

        return res


def solve(n, heights, beauty):
    dp = [0] * (n+1)
    st = SegmentTree(dp, op=max)

    for flower in range(n):
        pos = heights[flower]
        val = st.query(0, heights[flower]) + beauty[flower]
        st.modify(pos, val)

    return st.tree[1]


def main():
    n = int(eval(input()))
    heights = [int(c) for c in input().split()]
    beauty = [int(c) for c in input().split()]
    ans = solve(n, heights, beauty)
    print(ans)


if __name__ == "__main__":
    main()
# Original solution
import operator


class SegmentTree:
    def __init__(self, seq, op=operator.add):
        self.n = len(seq)
        self.op = op
        self.tree = [-1] * self.n + seq
        for i in reversed(list(range(1, self.n))):
            self.tree[i] = op(self.tree[2*i], self.tree[2*i+1])

    def modify(self, pos, val):
        assert pos < self.n
        pos += self.n
        self.tree[pos] = val
        while pos > 1:
            self.tree[pos//2] = self.op(self.tree[pos], self.tree[pos ^ 1])
            pos //= 2

    def query(self, L, R):
        assert L <= R and L >= 0 and R <= self.n
        res = 0
        L += self.n
        R += self.n
        while L < R:
            if L % 2 == 1:
                res = self.op(res, self.tree[L])
                L += 1
            if R % 2 == 1:
                R -= 1
                res = self.op(res, self.tree[R])

            L //= 2
            R //= 2

        return res


def solve(n, heights, beauty):
    dp = [0] * (n+1)
    st = SegmentTree(dp, op=max)

    for flower in range(n):
        pos = heights[flower]
        val = st.query(0, heights[flower]) + beauty[flower]
        st.modify(pos, val)

    return st.tree[1]


def main():
    n = int(eval(input()))
    heights = [int(c) for c in input().split()]
    beauty = [int(c) for c in input().split()]
    ans = solve(n, heights, beauty)
    print(ans)


if __name__ == "__main__":
    main()


# Optimized solution
import operator


class SegmentTree:
    __slots__ = ('n', 'op', 'tree')

    def __init__(self, seq, op=operator.add):
        self.n = len(seq)
        self.op = op
        self.tree = [-1] * self.n + seq
        for i in reversed(list(range(1, self.n))):
            self.tree[i] = op(self.tree[2*i], self.tree[2*i+1])

    def modify(self, pos, val):
        assert pos < self.n
        pos += self.n
        self.tree[pos] = val
        while pos > 1:
            self.tree[pos//2] = self.op(self.tree[pos], self.tree[pos ^ 1])
            pos //= 2

    def query(self, L, R):
        assert L <= R and L >= 0 and R <= self.n
        res = 0
        L += self.n
        R += self.n
        while L < R:
            if L % 2 == 1:
                res = self.op(res, self.tree[L])
                L += 1
            if R % 2 == 1:
                R -= 1
                res = self.op(res, self.tree[R])

            L //= 2
            R //= 2

        return res


def solve(n, heights, beauty):
    dp = [0] * (n+1)
    st = SegmentTree(dp, op=max)

    for flower in range(n):
        pos = heights[flower]
        val = st.query(0, heights[flower]) + beauty[flower]
        st.modify(pos, val)

    return st.tree[1]


def main():
    n = int(eval(input()))
    heights = [int(c) for c in input().split()]
    beauty = [int(c) for c in input().split()]
    ans = solve(n, heights, beauty)
    print(ans)


if __name__ == "__main__":
    main()
# Original solution
class SegmentTree:
    __slots__ = ('n', 'op', 'tree')

    def __init__(self, seq, op=max):
        self.n = len(seq)
        self.op = op
        self.tree = [-1] * self.n + seq
        for i in reversed(list(range(1, self.n))):
            self.tree[i] = op(self.tree[2*i], self.tree[2*i+1])

    def modify(self, pos, val):
        assert pos < self.n
        pos += self.n
        self.tree[pos] = val
        while pos > 1:
            self.tree[pos//2] = self.op(self.tree[pos], self.tree[pos ^ 1])
            pos //= 2

    def query(self, L, R):
        assert L <= R and L >= 0 and R <= self.n
        res = 0
        L += self.n
        R += self.n
        while L < R:
            if L % 2 == 1:
                res = self.op(res, self.tree[L])
                L += 1
            if R % 2 == 1:
                R -= 1
                res = self.op(res, self.tree[R])

            L //= 2
            R //= 2

        return res


def solve(n, heights, beauty):
    dp = SegmentTree([0] * (n+1), op=max)
    query = dp.query
    modify = dp.modify

    for flower in range(n):
        pos = heights[flower]
        best = query(0, pos)
        modify(pos, best + beauty[flower])

    return dp.tree[1]


def main():
    n = int(eval(input()))
    heights = [int(c) for c in input().split()]
    beauty = [int(c) for c in input().split()]
    ans = solve(n, heights, beauty)
    print(ans)


if __name__ == "__main__":
    main()


# Optimized solution
class SegmentTree:
    __slots__ = ('n', 'op', 'tree')

    def __init__(self, seq, op=max):
        self.n = len(seq)
        self.op = op
        self.tree = [-1] * (2 * self.n)

        for i in range(self.n):
            self.tree[i+self.n] = seq[i]

        for i in reversed(list(range(1, self.n))):
            self.tree[i] = op(self.tree[2*i], self.tree[2*i+1])

    def modify(self, pos, val):
        assert pos < self.n
        pos += self.n
        self.tree[pos] = val
        while pos > 1:
            self.tree[pos//2] = self.op(self.tree[pos], self.tree[pos ^ 1])
            pos //= 2

    def query(self, L, R):
        assert L <= R and L >= 0 and R <= self.n
        res = 0
        L += self.n
        R += self.n
        while L < R:
            if L % 2 == 1:
                res = self.op(res, self.tree[L])
                L += 1
            if R % 2 == 1:
                R -= 1
                res = self.op(res, self.tree[R])

            L //= 2
            R //= 2

        return res


def solve(n, heights, beauty):
    dp = SegmentTree([0] * (n+1), op=max)

    for pos, b in zip(heights, beauty):
        best = dp.query(0, pos)
        dp.modify(pos, best + b)

    return dp.query(0, n+1)


def main():
    n = int(eval(input()))
    heights = [int(c) for c in input().split()]
    beauty = [int(c) for c in input().split()]
    ans = solve(n, heights, beauty)
    print(ans)


if __name__ == "__main__":
    main()
# Original solution
class SegmentTree:
    __slots__ = ('n', 'op', 'tree')

    def __init__(self, seq, op=max):
        self.n = len(seq)
        self.op = op
        self.tree = [-1] * (2 * self.n)

        for i in range(self.n):
            self.tree[i+self.n] = seq[i]

        for i in reversed(list(range(1, self.n))):
            self.tree[i] = op(self.tree[2*i], self.tree[2*i+1])

    def modify(self, pos, val):
        assert pos < self.n
        pos += self.n
        self.tree[pos] = val
        while pos > 1:
            self.tree[pos//2] = self.op(self.tree[pos], self.tree[pos ^ 1])
            pos //= 2

    def query(self, L, R):
        assert L <= R and L >= 0 and R <= self.n
        res = 0
        L += self.n
        R += self.n
        while L < R:
            if L % 2 == 1:
                res = self.op(res, self.tree[L])
                L += 1
            if R % 2 == 1:
                R -= 1
                res = self.op(res, self.tree[R])

            L //= 2
            R //= 2

        return res


def solve(n, heights, beauty):
    dp = SegmentTree([0] * (n+1), op=max)

    for pos, b in zip(heights, beauty):
        best = dp.query(0, pos)
        dp.modify(pos, best + b)

    return dp.query(0, n+1)


def main():
    n = int(eval(input()))
    heights = [int(c) for c in input().split()]
    beauty = [int(c) for c in input().split()]
    ans = solve(n, heights, beauty)
    print(ans)


if __name__ == "__main__":
    main()


# Optimized solution
class SegmentTree:
    def __init__(self, n):
        self.tree = [0] * (2 * n)
        self.n = n

    def modify(self, pos, val):
        tree = self.tree
        pos += self.n
        tree[pos] = val
        while pos > 1:
            tree[pos//2] = max(tree[pos], tree[pos ^ 1])
            pos //= 2

    def query(self, L, R):
        res = 0
        L += self.n
        R += self.n
        while L < R:
            if L % 2 == 1:
                res = max(res, self.tree[L])
                L += 1
            if R % 2 == 1:
                R -= 1
                res = max(res, self.tree[R])

            L //= 2
            R //= 2

        return res


def solve(n, heights, beauty):
    dp = SegmentTree(n+1)
    for h, b in zip(heights, beauty):
        _max = dp.query(0, h)
        dp.modify(h, _max + b)

    return dp.query(0, n+1)


def main():
    n = int(eval(input()))
    heights = [int(c) for c in input().split()]
    beauty = [int(c) for c in input().split()]
    ans = solve(n, heights, beauty)
    print(ans)


if __name__ == "__main__":
    main()
# Original solution
N = int(eval(input()))
h = list(map(int, input().split()))
a = list(map(int, input().split()))

def base10to(n, b):
    if b <= n:
        return base10to(n//b, b) + str(n%b)
    return str(n%b)

num = 2**(len(base10to(N+1,2))+1)
seg = [0]*(2*num-1)

#update(i,x):Aiをxに更新する
def update(i,x):
    k = i + num - 1
    while k >= 0:
        seg[k] = max(x,seg[k])
        k = (k-1)//2

#query(a,b,0,0,num):[a,b)の最大値
def query(a,b,k,l,r):
    if r <= a or b <= l:
        return -1
    elif a <= l and r <= b:
        return seg[k]
    else:
        return max(query(a,b,2*k+1,l,(l+r)//2),query(a,b,2*k+2,(l+r)//2,r))


for i in range(N):
    update(h[i], query(0,h[i],0,0,num) + a[i])

print((query(0,N+2,0,0,num)))

# Optimized solution
N = int(eval(input()))
h = list(map(int, input().split()))
a = list(map(int, input().split()))

num = 2
while num <= N+1:
    num *= 2

seg = [0]*(2*num-1)

#update(i,x):Aiをxに更新する
def update(i,x):
    k = i + num - 1
    while k >= 0:
        seg[k] = max(x,seg[k])
        k = (k-1)//2

#query(a,b,0,0,num):[a,b)の最大値
def query(a,b,k,l,r):
    if r <= a or b <= l:
        return -1
    elif a <= l and r <= b:
        return seg[k]
    else:
        return max(query(a,b,2*k+1,l,(l+r)//2),query(a,b,2*k+2,(l+r)//2,r))


for i in range(N):
    update(h[i], query(0,h[i],0,0,num) + a[i])

print((max(seg)))
# Original solution
def init(init_val):
    for i in range(n):
        MI[i+num-1] = init_val[i]
        MA[i+num-1] = init_val[i]
    for i in range(num-2, -1, -1):
        MI[i] = min(MI[2*i+1], MI[2*i+2])
        MA[i] = max(MA[2*i+1], MA[2*i+2])


def update(k, x):
    k += num-1
    MI[k] = x
    MA[k] = x
    while k+1:
        k = (k-1)//2
        MI[k] = min(MI[k*2+1], MI[k*2+2])
        MA[k] = max(MA[k*2+1], MA[k*2+2])


def rangemin(p, q):
    if q <= p:
        return 1 << 100
    p += num-1
    q += num-2
    res = 1 << 100
    while q-p > 1:
        if p & 1 == 0:
            res = min(res, MI[p])
        if q & 1 == 1:
            res = min(res, MI[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = min(res, MI[p])
    else:
        res = min(min(res, MI[p]), MI[q])
    return res


def rangemax(p, q):
    if q <= p:
        return -1
    p += num-1
    q += num-2
    res = -1
    while q-p > 1:
        if p & 1 == 0:
            res = max(res, MA[p])
        if q & 1 == 1:
            res = max(res, MA[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = max(res, MA[p])
    else:
        res = max(max(res, MA[p]), MA[q])
    return res


n = int(eval(input()))
h = [int(x) for x in input().split()]
a = [int(x) for x in input().split()]

dp = [0 for _ in range(n+1)]

num = 2**(n).bit_length()
MI = [1 << 100]*2*num
MA = [-1]*2*num
init(dp)

for i in range(n):
    update(h[i], a[i] + rangemax(0, h[i]))

print((rangemax(0, n+1)))


# Optimized solution
class SegmentTree:  # 0-indexed
    def __init__(self, array, operation=min, identity=10**30):
        self.identity = identity
        self.n = len(array)
        self.N = 1 << (self.n - 1).bit_length()
        self.tree = [self.identity] * 2 * self.N
        self.opr = operation
        for i in range(self.n):
            self.tree[i+self.N-1] = array[i]
        for i in range(self.N-2, -1, -1):
            self.tree[i] = self.opr(self.tree[2*i+1], self.tree[2*i+2])

    def value(self, k):
        return self.tree[k+self.N-1]

    def update(self, k, x):
        k += self.N-1
        self.tree[k] = x
        while k+1:
            k = (k-1)//2
            self.tree[k] = self.opr(self.tree[k*2+1], self.tree[k*2+2])

    def query(self, p, q):  # [p,q)
        if q <= p:
            print("Oops!  That was no valid number.  Try again...")
            exit()
        p += self.N-1
        q += self.N-2
        res = self.identity
        while q-p > 1:
            if p & 1 == 0:
                res = self.opr(res, self.tree[p])
            if q & 1 == 1:
                res = self.opr(res, self.tree[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p == q:
            res = self.opr(res, self.tree[p])
        else:
            res = self.opr(self.opr(res, self.tree[p]), self.tree[q])
        return res


n = int(eval(input()))
h = [int(x) for x in input().split()]
a = [int(x) for x in input().split()]

dp = [0 for _ in range(n+1)]

ST = SegmentTree(dp, max, -1)

for i in range(n):
    ST.update(h[i], a[i] + ST.query(0, h[i]))

print((ST.query(0, n+1)))
# Original solution
while True:
    n,k = list(map(int, input().split()))
    if n == k == 0:
        break
    s = [int(x) for x in input().split()]
    for _ in range(n):
        b = [int(x) for x in input().split()]
        for i in range(k):
            s[i] -= b[i]
    print(("Yes" if min(s) >= 0 else "No"))

# Optimized solution
while True:
    n,k = list(map(int, input().split()))
    if n == k == 0:
        break
    s = list(map(int, input().split()))
    for _ in range(n):
        b = list(map(int, input().split()))
        for i in range(k):
            s[i] -= b[i]
    print(("Yes" if min(s) >= 0 else "No"))
# Original solution
import sys
def input(): return sys.stdin.readline().strip()
def mapint(): return list(map(int, input().split()))
sys.setrecursionlimit(10**9)

N = int(eval(input()))
As = list(mapint())
Bs = list(mapint())

if sum(As)<sum(Bs):
    print((-1))
else:
    diff = [a-b for a, b in zip(As, Bs)]
    diff.sort()
    cnt = 0
    need = 0
    for d in diff:
        if d>=0:
            break
        need += d
        cnt += 1
    for d in diff[::-1]:
        if need>=0:
            break
        need += d
        cnt += 1
    print(cnt)

# Optimized solution
import sys
def input(): return sys.stdin.readline().strip()
def mapint(): return list(map(int, input().split()))
sys.setrecursionlimit(10**9)

N = int(eval(input()))
As = list(mapint())
Bs = list(mapint())

if sum(As)<sum(Bs):
    print((-1))
else:
    minus = 0
    cnt = 0
    lis = []
    for a, b in zip(As, Bs):
        if a<b:
            minus += (b-a)
            cnt += 1
        else:
            lis.append(a-b)
    lis.sort(reverse=True)
    if minus==0:
        print((0))
    else:
        for l in lis:
            minus -= l
            cnt += 1
            if minus<=0:
                break
        print(cnt)
# Original solution
n = int(eval(input()))
a = list(map(int, input().split()))
b = list(map(int, input().split()))
res = 0

if sum(a) < sum(b):
    res = -1
else:
    c = [a[i] - b[i] for i in range(n)]
    c1 = [i if i > 0 else 0 for i in c]
    c2 = sum([i if i < 0 else 0 for i in c])
    c3 = sum([1 if i < 0 else 0 for i in c])
    if c2 < 0:
        c1.sort(reverse=True)
        for i in range(n):
            if sum(c1[0:i]) + c2 > 0:
                res = c3 + i
                break

print(res)


# Optimized solution
n = int(eval(input()))
a = list(map(int, input().split()))
b = list(map(int, input().split()))
res = 0
d = 0

if sum(a) < sum(b):
    res = -1
else:
    c = [a[i] - b[i] for i in range(n)]
    c1 = [i if i > 0 else 0 for i in c]
    c2 = sum([i if i < 0 else 0 for i in c])
    c3 = sum([1 if i < 0 else 0 for i in c])
    if c2 < 0:
        c4 = sorted(c1, reverse=True)
        for i in range(n):
            d = d + c4[i]
            if d + c2 > 0:
                res = c3 + i + 1
                break

print(res)
# Original solution
N = int(eval(input()))
A = list(map(int, input().split()))
B = list(map(int, input().split()))

A_origin = A[:]

if sum(A) < sum(B):
    print((-1))
    exit()

diff = [[i, a - b] for i, a, b in zip(list(range(N)), A, B)]

order = sorted([[i, x] for i, x in diff if x > 0], key=lambda d: d[1])
C = []

charge = order.pop()
for i in range(N):
    while A[i] - B[i] < 0:
        if charge[1] > B[i] - A[i]:
            A[charge[0]] -= (B[i] - A[i])
            charge[1] -= (B[i] - A[i])
            A[i] = B[i]
        else:
            A[charge[0]] = B[charge[0]]
            A[i] += charge[1]
            charge = order.pop()

ans = 0
for a, ao in zip(A, A_origin):
    if a != ao:
        ans += 1

print(ans)


# Optimized solution
N = int(eval(input()))
A = list(map(int, input().split()))
B = list(map(int, input().split()))


# 各テストの余裕を小さい順に
margins = [[i, a - b] for i, (a, b) in enumerate(zip(A, B)) if (a - b) > 0]
margins.sort(key=lambda m: m[1])

# 調整済みA
X = A[:]

# 余裕が大きい方から使っていく
for i in range(N):
    while (A[i] < B[i]) and margins:
        cost = B[i] - A[i]
        mi, margin = margins[-1]

        if margin > cost:
            margins[-1][1] -= cost
            A[mi] -= cost
            A[i] += cost

        else:
            margins.pop()
            A[mi] -= margin
            A[i] += margin


ans = 0
for a, b, x in zip(A, B, X):
    if b - a > 0:
        print((-1))
        break

    if a != x:
        ans += 1
else:
    print(ans)
# Original solution
from itertools import accumulate
N = int(eval(input()))
A = list(map(int, input().split()))
B = list(map(int, input().split()))


surplus = [(a - b) for a, b in zip(A, B) if (a - b) > 0]
surplus.sort(reverse=True)
surplus_acc = [0] + list(accumulate(surplus))

short = [(b - a) for a, b in zip(A, B) if (b - a) > 0]
need = sum(short)
short_num = len(short)


if need > sum(surplus):
    print((-1))
    exit()
else:
    for i in range(len(surplus_acc)):
        if surplus_acc[i] >= need:
            print((i + short_num))
            exit()


# Optimized solution
N = int(eval(input()))
A = list(map(int, input().split()))
B = list(map(int, input().split()))


if sum(A) < sum(B):
    print((-1))
    exit()


surpluses = sorted([a - b for a, b in zip(A, B) if a - b > 0])
need = [b - a for a, b in zip(A, B) if b - a > 0]
need_sum = sum(need)

ans = len(need)
tmp = 0
while tmp < need_sum:
    ans += 1
    tmp += surpluses.pop()


print(ans)
# Original solution
# keyence2019C - Exam and Wizard
def main():
    N = int(eval(input()))
    A = tuple(map(int, input().split()))
    B = tuple(map(int, input().split()))
    dif = sorted(i - j for i, j in zip(A, B))
    ans, shortage = 0, 0
    for i in dif:
        if i < 0:
            ans += 1
            shortage += i
        else:
            break
    for i in dif[::-1]:
        if shortage >= 0:
            print(ans)
            return
        ans += 1
        shortage += i
    print((-1))


if __name__ == "__main__":
    main()

# Optimized solution
# keyence2019C - Exam and Wizard
def main():
    N = int(eval(input()))
    A = tuple(map(int, input().split()))
    B = tuple(map(int, input().split()))
    pos, neg = [], []
    for i, j in zip(A, B):
        x = i - j
        if x >= 0:
            pos += [x]
        else:
            neg += [x]
    ans, shortage = len(neg), sum(neg)
    for i in sorted(pos, reverse=1):
        if shortage >= 0:
            print(ans)
            return
        ans += 1
        shortage += i
    print((ans if shortage >= 0 else -1))


if __name__ == "__main__":
    main()