CodeEff/ECCO huggingface dataset:
# Original solution
n,k=list(map(int,input().split()))

a=list(map(int,input().split()))
f=list(map(int,input().split()))
cnt=[]
a.sort()
f.sort(reverse=True)
for i in range(n):
    cv=a[i]*f[i]
    cnt.append(cv)

def judge(s):
    tmp=k
    for i in range(n):
        if cnt[i]>s:
            if (cnt[i]-s)%f[i]==0:
                vv=(cnt[i]-s)//f[i]
            else:
                vv=1+(cnt[i]-s)//f[i]
            tmp-=vv
    if tmp<0:
        return False
    return True

left=-1
right=10**18

while left+1<right:
    mid=(left+right)//2
    if judge(mid):
        right=mid
    else:
        left=mid

print(right)

# Optimized solution
n,k=list(map(int,input().split()))

a=list(map(int,input().split()))
f=list(map(int,input().split()))
cnt=[0]*n
a.sort()
f.sort(reverse=True)
for i in range(n):
    cnt[i]=a[i]*f[i]
def judge(s):
    tmp=k
    for i in range(n):
        if cnt[i]>s:
            if (cnt[i]-s)%f[i]==0:
                vv=(cnt[i]-s)//f[i]
            else:
                vv=1+(cnt[i]-s)//f[i]
            tmp-=vv
    if tmp<0:
        return False
    return True

left=-1
right=10**18

while left+1<right:
    mid=(left+right)//2
    if judge(mid):
        right=mid
    else:
        left=mid

print(right)
# Original solution
N,K = list(map(int, input().strip().split(' ')))
A = sorted(list(map(int, input().strip().split(' '))), reverse=True)
F = sorted(list(map(int, input().strip().split(' '))))
if sum(A) <= K:
  print((0))
  exit()

ng = 0
ok = max([a*f for a,f in zip(A,F)])
while True:
  if ok-ng < 2: break
  k = int((ng+ok)/2)
  now_cost = 0
  for a,f in zip(A,F):
    while a*f > k:
      a -= 1
      now_cost += 1
    if now_cost > K: break
  if now_cost > K:
    ng = k
  else:
    ok = k
    
print(ok)


# Optimized solution
N,K = list(map(int, input().strip().split(' ')))
A = sorted(list(map(int, input().strip().split(' '))), reverse=True)
F = sorted(list(map(int, input().strip().split(' '))))
if sum(A) <= K:
  print((0))
  exit()

ng = 0
ok = max([a*f for a,f in zip(A,F)])
while True:
  if ok-ng == 1: break
  m = int((ng+ok)/2)
  now_cost = 0
  for a,f in zip(A,F):
    now_cost += max(a-(m//f), 0)
  if now_cost <= K:
    ok = m
  else:
    ng = m
    
print(ok)
# Original solution
#E
import math
N,K = list(map(int,input().split()))
A = list(map(int,input().split()))
F = list(map(int,input().split()))

A.sort(reverse=True)
F.sort()

left = 0
right = 10**12
while True:
    mid = (left+right)//2
    if right - left <= 1:
        count = 0
        for i in range(N):
            a = left//F[i]
            count+=max(0,A[i]-a)
        if count <= K:
            ans = left
        else:
            ans = right
        break
    
    
    count = 0
    for i in range(N):
        a = mid//F[i]
        count+=max(0,A[i]-a)
    #print(right,left,count)
    if count <= K:
        right = mid
    else:
        left = mid
        
        

print(ans)
        
            



# Optimized solution
#E
N,K = list(map(int,input().split()))
A = list(map(int,input().split()))
F = list(map(int,input().split()))

A.sort(reverse=True)
F.sort()

left = 0
right = 10**12
while True:
    mid = (left+right)//2
    if right - left <= 1:
        count = 0
        for i in range(N):
            a = left//F[i]
            count+=max(0,A[i]-a)
        if count <= K:
            ans = left
        else:
            ans = right
        break
    
    
    count = 0
    for i in range(N):
        a = mid//F[i]
        count+=max(0,A[i]-a)
    if count <= K:
        right = mid
    else:
        left = mid
        
        

print(ans)
# Original solution
from math import ceil
n, k = list(map(int, input().split()))
A = sorted(map(int, input().split()))
F = sorted(map(int, input().split()))
A.reverse()
ok = max(a * f for a, f in zip(A, F))
ng = -1
while ok - ng != 1:
    x = (ok + ng) // 2
    cnt = 0
    for a, f in zip(A, F):
        if a * f > x:
            cnt += ceil(a - x / f)
        if cnt > k:
            ng = x
            break
    else:
        ok = x

print(ok)


# Optimized solution
def main():
    from math import ceil
    n, k = list(map(int, input().split()))
    A = sorted(map(int, input().split()))
    F = sorted(map(int, input().split()))
    A.reverse()
    ok = max(a * f for a, f in zip(A, F))
    ng = -1
    while ok - ng != 1:
        x = (ok + ng) // 2
        cnt = 0
        for a, f in zip(A, F):
            if a * f > x:
                cnt += ceil(a - x / f)
            if cnt > k:
                ng = x
                break
        else:
            ok = x

    print(ok)

if __name__ == "__main__":
    main()
# Original solution
n,k=list(map(int,input().split()))
a=list(map(int,input().split()))
f=list(map(int,input().split()))
a=sorted(a)
f=sorted(f,reverse=True)


def is_lessthanK(X):
  ans=0
  for i in range(n):
    ans+=max(0,a[i]-X//f[i])
    if ans > k:
      return False
  return True


ng=-1
ok=10**13
while ok-ng>1:
  mid=(ok+ng)//2
  if is_lessthanK(mid):
    ok=mid
  else:
    ng=mid
print(ok)



# Optimized solution
n,k=list(map(int,input().split()))
a=list(map(int,input().split()))
f=list(map(int,input().split()))
a=sorted(a)
f=sorted(f,reverse=True)


def is_lessthanK(X):
  ans=0
  for A,F in zip(a,f):
    if A*F>X:
      ans+=A-X//F
    if ans > k:
      return False
  return True


ng=-1
ok=a[-1]*f[0]
while ok-ng>1:
  mid=(ok+ng)//2
  if is_lessthanK(mid):
    ok=mid
  else:
    ng=mid
print(ok)
# Original solution
import sys
from collections import Counter, deque, defaultdict
from math import factorial
from fractions import Fraction
import heapq, bisect
import math
import itertools
sys.setrecursionlimit(10 ** 5 + 10)
INF = 10**15 +5
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))

n, k = MAP()
a = LIST()
f = LIST()
a = sorted(a, reverse = True)
f = sorted(f)
heap = []
heapq.heapify(heap)
for i in range(n):
    heapq.heappush(heap, (-1*f[i]*a[i], f[i]))

for i in range(k):
    if len(heap) > 0:
        dot, ff = heapq.heappop(heap)
        dot += ff
        if dot != 0:
            heapq.heappush(heap, (dot, ff))

if len(heap) > 0:
    print((heapq.heappop(heap)[0] * -1))
else:
    print((0))

# Optimized solution
import sys
from collections import Counter, deque, defaultdict
from math import factorial
from fractions import Fraction
import heapq, bisect
import math
import itertools
sys.setrecursionlimit(10 ** 5 + 10)
INF = 10**15 +5
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))

n, k = MAP()
a = LIST()
f = LIST()
a = sorted(a, reverse = True)
f = sorted(f)

def ok(x):
    res = 0
    for i in range(n):
        res += max(a[i] - x//f[i], 0)
    return res <= k

l = -1
r = INF
while l+1 < r:
    mid = (l+r)//2
    if ok(mid):
        r = mid
    else:
        l = mid
print(r)
# Original solution
import sys
input = sys.stdin.readline

n,k = list(map(int,input().split()))
a = list(map(int,input().split()))
f = list(map(int,input().split()))
a.sort(reverse=True)
f.sort()
z = list(zip(a,f))
ok = max(x*y for x,y in z)
ng = -1
while ok-ng>1:
  mid = (ok+ng)//2
  if sum(x-mid//y for x,y in z if x*y > mid) <= k:
    ok = mid
  else:
    ng = mid
print(ok)

# Optimized solution
n,k = list(map(int,input().split()))
a = list(map(int,input().split()))
f = list(map(int,input().split()))
a.sort(reverse=True)
f.sort()
z = list(zip(a,f))
ok = max(x*y for x,y in z)
ng = -1
while ok-ng>1:
  mid = (ok+ng)//2
  if sum(x-mid//y for x,y in z if x*y > mid) <= k:
    ok = mid
  else:
    ng = mid
print(ok)
# Original solution
N, K  = list(map(int, input().split()))
As = sorted(list(map(int, input().split())))
Fs = sorted(list(map(int, input().split())),reverse=True)
Xs = sorted([(a*f,i) for i,(a,f) in enumerate(zip(As,Fs))],reverse=True)
# Xs =[a*f for a,f in zip(As,Fs)]
# print(Xs)
# print(As)
# print(Fs)
import heapq
q = []
INF = 10**6
heapq.heapify(q)
for i,(a,f) in enumerate(zip(As,Fs)):
    num = -(a*f*INF+i)
    heapq.heappush(q,num)
if K >= sum(As):
    print((0))
    exit()
for k in range(K):
    num = heapq.heappop(q)
    i = (-num)%INF
    n = (-num)//INF
    # print(i,n,As[i],Fs[i])
    As[i] -= 1
    upd = -(As[i]*Fs[i]*INF+i)
    heapq.heappush(q,upd)
num = heapq.heappop(q)
ans = (-num)//INF
print(ans)


# x_min = min(Xs)
# ns = [max(0,A-x_min//F) for A,F in zip(As,Fs)]
# print(ns)


# Optimized solution
N, K  = list(map(int, input().split()))
As = sorted(list(map(int, input().split())))
Fs = sorted(list(map(int, input().split())),reverse=True)
Xs = [a*f for a,f in zip(As,Fs)]
X_M = max(Xs)

def f(x):
    K_tmp = sum([max(0,a-x//f) for a,f in zip(As,Fs)])
    return K_tmp <= K

def  binarySearch(l,r,target):
    while r - l > 1:
        mid = (l+r)//2
        """計算を入れる"""
        # print(mid, guess)
        if f(mid):
            r = mid
        else:
            l = mid
    return r

print((binarySearch(-1,X_M,K)))
# Original solution
N, K = list(map(int, input().split()))
A = sorted(list(map(int, input().split())))
F = tuple(map(int, input().split()))


def can_eat(t):
    F_time = sorted([t // f for f in F])
    training = 0
    for i in range(N):
        training += max(0, A[i] - F_time[i])
    return training <= K


# bisect
l, r = -1, 10 ** 12
while r - l > 1:
    m = (r + l) // 2
    if can_eat(m):
        r = m
    else:
        l = m
print(r)


# Optimized solution
import sys

input = sys.stdin.readline

N, K = list(map(int, input().split()))
A = sorted(list(map(int, input().split())))
F = tuple(map(int, input().split()))


def can_eat(t):
    F_time = sorted([t // f for f in F])
    training = 0
    for i in range(N):
        training += max(0, A[i] - F_time[i])
    return training <= K


# bisect
l, r = -1, 10 ** 12
while r - l > 1:
    m = (r + l) // 2
    if can_eat(m):
        r = m
    else:
        l = m
print(r)
# Original solution
import heapq
class Heapq:
    def __init__(self, arr, desc=False):
        if desc:
            arr = [-a for a in arr]
        self.sign = -1 if desc else 1
        self.hq = arr
        heapq.heapify(self.hq)
 
    def pop(self):
        return heapq.heappop(self.hq) * self.sign
 
    def push(self, a):
        heapq.heappush(self.hq, a * self.sign)
 
    def top(self):
        return self.hq[0] * self.sign

def resolve():
    n,k  = list(map(int,input().split()))
    
    member_cost = list(map(int,input().split()))
    food_cost = list(map(int,input().split()))

    member_cost.sort()
    food_cost.sort(reverse=True)
    total_cost = []
    for i in range(len(member_cost)):
        total_cost.append(member_cost[i]*food_cost[i])

    total_cost_heap = Heapq(total_cost,True)
    if k >= sum(member_cost):
        print((0))
    else:
        while k > 0:
            k -= 1
            max_cost  = total_cost_heap.pop()
            reduce_index = total_cost.index(max_cost)
            member_cost[reduce_index] -= 1
            total_cost[reduce_index] -= food_cost[reduce_index]
            total_cost_heap.push(total_cost[reduce_index])
        print((max(total_cost)))
        
            
resolve()

# Optimized solution
class Contest:
    def __init__(self, member_cost,food_cost,k):
        self.member_cost = member_cost
        self.food_cost   = food_cost
        self.max_training_times = k
        
    def canAchieve(self,target):
        sum_training_times = 0
        for i in range(len(self.member_cost)):
            sum_training_times += max(0,self.member_cost[i] - target//self.food_cost[i])

        return  sum_training_times <= self.max_training_times
        


    def bisect(self,begin,end):
        if (end - begin <= 1 ):
            return end
        target = (begin + end)//2
        if self.canAchieve(target):
            return self.bisect(begin,target)

        else:
            return self.bisect(target,end)




def resolve():
    n,k  = list(map(int,input().split()))
    
    member_cost = list(map(int,input().split()))

    food_cost = list(map(int,input().split()))
    member_cost.sort()
    food_cost.sort(reverse=True)
    total_cost = []
    for i in range(len(member_cost)):
        total_cost.append(member_cost[i]*food_cost[i])

    max_total_cost = max(total_cost)
    contest = Contest(member_cost,food_cost,k)
    print((contest.bisect(-1,max_total_cost)))
    
resolve()
# Original solution
import heapq
import bisect

N, K = list(map(int, input().split()))
A = list(map(int, input().split()))
F = list(map(int, input().split()))

F = sorted(F, reverse = True)
A = sorted(A)
flg = 0
lst = []

for i in range(N):
	if A[i] == 0 or F[i] == 0:
		break
	else:
		lst.insert(bisect.bisect_left(lst, [A[i] * F[i], F[i]]),[A[i] * F[i], F[i]]) 
		# heapq.heappush(heap, [- A[i] * F[i], F[i]])
		
for i in range(K):
	popped = lst.pop(-1)
	popped[0] -= popped[1]
	lst.insert(bisect.bisect_left(lst, popped), popped)

print((lst[-1][0]))	

# Optimized solution
N, K = list(map(int, input().split()))
A = list(map(int, input().split()))
F = list(map(int, input().split()))

A.sort()
F.sort(reverse = True)

ng = -1
ok = 10 ** 12

while ok - ng > 1:
	mid = (ok + ng) // 2
	ctr = 0
	for i in range(N):
		ctr += max(0, A[i] - mid // F[i])
	if ctr <= K:
		ok = mid
	else:
		ng = mid

print(ok)
# Original solution
# -*- coding: utf-8 -*-

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 ** 7)
INF = 10 ** 18
MOD = 10 ** 9 + 7

def bisearch_min(mn, mx, func):
    """ 条件を満たす最小値を見つける二分探索 """

    ok = mx
    ng = mn
    while ng+1 < ok:
        mid = (ok+ng) // 2
        if func(mid):
            # 下を探しに行く
            ok = mid
        else:
            # 上を探しに行く
            ng = mid
    return ok

N, K = MAP()
A = LIST()
B = LIST()

A.sort(reverse=True)
B.sort()

def check(m):
    k = 0
    for i, a in enumerate(A):
        b = B[i]
        k += max(ceil(a - m/b), 0)
        if k > K:
            return False
    return True

print((bisearch_min(-1, INF, check)))


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

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 ** 7)
INF = 10 ** 18
MOD = 10 ** 9 + 7

def bisearch_min(mn, mx, func):
    """ 条件を満たす最小値を見つける二分探索 """

    ok = mx
    ng = mn
    while ng+1 < ok:
        mid = (ok+ng) // 2
        if func(mid):
            # 下を探しに行く
            ok = mid
        else:
            # 上を探しに行く
            ng = mid
    return ok

N, K = MAP()
A = LIST()
B = LIST()

A.sort(reverse=True)
B.sort()

def check(m):
    k = 0
    for i, a in enumerate(A):
        b = B[i]
        k += max(ceil(a - m/b), 0)
        if k > K:
            return False
    return True

print((bisearch_min(-1, 10**12, check)))
# Original solution
from collections import Counter
n, k = list(map(int, input().split()))
a = list(map(int, input().split()))
f = list(map(int, input().split()))
a.sort()
f.sort(reverse=True)

la = 10**6+1
cnt = [0] * la
for u in a:
    cnt[u] += 1
for i in range(1, la):
    cnt[i] += cnt[i-1]


def judge(x):
    y = k
    for i in range(n):
        goal = x//f[i]
        if a[i] > goal:
            y -= a[i] - goal
            if y < 0:
                return False
    return y >= 0


left = -1
right = 10**12 + 1
while left + 1 < right:
    mid = (left + right)//2
    if judge(mid):
        right = mid
    else:
        left = mid

print(right)


# Optimized solution
from collections import Counter
n, k = list(map(int, input().split()))
a = list(map(int, input().split()))
f = list(map(int, input().split()))
a.sort()
f.sort(reverse=True)


def judge(x):
    y = k
    for i in range(n):
        goal = x//f[i]
        if a[i] > goal:
            y -= a[i] - goal
            if y < 0:
                return False
    return y >= 0


left = -1
right = 10**12 + 1
while left + 1 < right:
    mid = (left + right)//2
    if judge(mid):
        right = mid
    else:
        left = mid

print(right)
# Original solution
import sys
import math
from collections import deque

sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
input = lambda: sys.stdin.readline().strip()
NI = lambda: int(eval(input()))
NMI = lambda: list(map(int, input().split()))
NLI = lambda: list(NMI())
SI = lambda: eval(input())


def make_grid(h, w, num): return [[int(num)] * w for _ in range(h)]


def main():
    N, K = NMI()
    A = NLI()
    F = NLI()
    A.sort()
    ok = 10**13
    ng = 0
    for i in range(100):
        mid = (ok+ng) // 2
        limits = [mid//f for f in F]
        limits.sort()
        ks = [max(a-l, 0) for a, l in zip(A, limits)]
        if sum(ks) <= K:
            ok = mid
        else:
            ng = mid

    print(ok)


if __name__ == "__main__":
    main()

# Optimized solution
import sys
import math
from collections import deque

sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
input = lambda: sys.stdin.readline().strip()
NI = lambda: int(eval(input()))
NMI = lambda: list(map(int, input().split()))
NLI = lambda: list(NMI())
SI = lambda: eval(input())


def make_grid(h, w, num): return [[int(num)] * w for _ in range(h)]


def main():
    N, K = NMI()
    A = NLI()
    F = NLI()
    A.sort()
    F.sort(reverse=True)
    ok = 10**13
    ng = 0
    for i in range(100):
        mid = (ok+ng) // 2
        limits = [mid//f for f in F]
        ks = [max(a-l, 0) for a, l in zip(A, limits)]
        if sum(ks) <= K:
            ok = mid
        else:
            ng = mid

    print(ok)


if __name__ == "__main__":
    main()
# Original solution
import sys
from bisect import bisect_left


def solve():
    input = sys.stdin.readline
    N, K = list(map(int, input().split()))
    A = [int(a) for a in input().split()]
    F = [int(f) for f in input().split()]
    A.sort(reverse = True)
    F.sort()
    low, high = -1, 10 ** 12 + 1
    while high - low > 1:
        mid = (low + high) // 2
        count = 0
        for i in range(N):
            if A[i] * F[i] > mid: count += A[i] - (mid // F[i])
        if count > K: low = mid
        else: high = mid
    print(high)

    return 0

if __name__ == "__main__":
    solve()

# Optimized solution
import sys

def solve():
    input = sys.stdin.readline
    N, K = list(map(int, input().split()))
    A = [int(a) for a in input().split()]
    F = [int(f) for f in input().split()]
    A.sort(reverse = True)
    F.sort()
    low, high = -1, 10 ** 12 + 1
    while high - low > 1:
        mid = (low + high) // 2
        count = 0
        for i in range(N):
            if A[i] * F[i] > mid: count += A[i] - (mid // F[i])
        if count > K: low = mid
        else: high = mid
    print(high)

    return 0

if __name__ == "__main__":
    solve()
# Original solution
import heapq

n,k = list(map(int,input().split()))
a = list(map(int,input().split()))
f = list(map(int,input().split()))

hq = []

a.sort()
f.sort(reverse = True)

for i in range(n):
    heapq.heappush(hq, (-a[i]*f[i], a[i], f[i]))

for i in range(k):
    s,a1,f1 = heapq.heappop(hq)
    if s == 0:
        print((0))
        exit()
    a1 -= 1
    heapq.heappush(hq, (-a1*f1, a1, f1))

print((-heapq.heappop(hq)[0]))


# Optimized solution
n,k = list(map(int,input().split()))
a = list(map(int,input().split()))
f = list(map(int,input().split()))

def hantei(c):
    tmp = 0
    for i in range(n):
        if af[i] > c:
            a1 = c // f[i]
            tmp += a[i]- a1
    if tmp <= k:
        return True
    else:
        return False

hq = []

a.sort()
f.sort(reverse = True)

af = []
for i in range(n):
    af.append(a[i] * f[i])

l = 0
r = 10**12+10

while r - l > 1:
    c = (l + r) // 2
    if hantei(c):
        r = c
    else:
        l = c

if hantei(l):
    print(l)
else:
    print(r)
# Original solution
from heapq import heappop, heappush

N, K = list(map(int, input().split()))
digests = list(map(int, input().split()))
foods = list(map(int, input().split()))
foods.sort()
digests.sort(reverse=True)
hq = []
for i in range(N):
  heappush(hq, (-digests[i]*foods[i], digests[i], foods[i]))
for _ in range(K):
  cost, digest, food = heappop(hq)
  if cost == 0:
    heappush(hq, (0, 0, 0))
    break
  heappush(hq, (-(digest-1)*food, digest-1, food))
ans = 0
max_c, digest, food = heappop(hq)
print((-max_c))

# Optimized solution
N, K = list(map(int, input().split()))
costs = list(map(int, input().split()))
foods = list(map(int, input().split()))
foods.sort()
costs.sort(reverse=True)

def can_eat(x):
  count = 0
  for i in range(N):
    count += max(0, costs[i]-x//foods[i])
  return count <= K

l, r = -1, 10**12+1
while r-l > 1:
  mid = (l+r)//2
  if can_eat(mid):
    r = mid
  else:
    l = mid
print(r)
# Original solution
#設定
import sys
input = sys.stdin.buffer.readline

from heapq import heappop, heappush

INF = float("inf")

def getlist():
	return list(map(int, input().split()))

#処理内容
def main():
	N, K = getlist()
	A = getlist()
	F = getlist()
	A = sorted(A)
	F = sorted(F)
	Q = []
	for i in range(N):
		heappush(Q, [ (-A[i]) * F[N - 1 - i], -A[i], -F[N - 1 - i]])
	#print(Q)
	#処理
	for i in range(K):
		if Q[0][0] == 0:
			break
		else:
			s, a, f = heappop(Q)
			a += 1
			s = -(a * f)
			heappush(Q, [s, a, f])
	#print(Q)
	ans = 0
	for i in range(N):
		ans = max(ans, -Q[i][0])
	print(ans)

if __name__ == '__main__':
	main()

# Optimized solution
#設定
import sys
input = sys.stdin.buffer.readline

INF = float("inf")

def getlist():
	return list(map(int, input().split()))

#二分探索基本形 L:リスト x:値 n:リスト長
def Binary_Search(A, F, N, K):
	#初期化
	left = 0
	right = 10 ** 12
	ans = INF
	
	#二分探索
	while left <= right:
		mid = (left + right) // 2
		cnt = 0
		for i in range(N):
			if A[i] * F[i] > mid:
				cnt += (A[i] - int(mid // F[i]))
		if cnt <= K:
			right = mid - 1
			ans = min(ans, mid)
		else:
			left = mid + 1

	return ans

#処理内容
def main():
	N, K = getlist()
	A = getlist()
	F = getlist()
	A = sorted(A)
	F = sorted(F)[::-1]
	ans = Binary_Search(A, F, N, K)
	print(ans)

if __name__ == '__main__':
	main()