CodeEff/ECCO huggingface dataset:
# Original solution
def resolve():
    N, K = list(map(int, input().split()))
    A = sorted(list(map(int, input().split())), reverse=True)
    F = sorted(list(map(int, input().split())))
    q = []
    for i in range(N):
        q.append((-A[i]*F[i], A[i], F[i]))
    import heapq
    heapq.heapify(q)
    for i in range(K):
        time, a, f = heapq.heappop(q)
        # print("###########")
        # print(time, a, f)
        if a <= 0:
            print((0))
            return
        heapq.heappush(q, (-(a-1)*f, a-1, f))
        # print(-(a-1)*f, a-1, f)
    time, _, __ = heapq.heappop(q)
    print((-time))

    
if __name__ == "__main__":
    resolve()


# Optimized solution
def resolve():
    N, K = list(map(int, input().split()))
    A = sorted(list(map(int, input().split())))
    F = sorted(list(map(int, input().split())), reverse=True)
    q = []
    for i in range(N):
        q.append((A[i]*F[i], A[i], F[i]))

    def isok(time):
        total = 0
        for t, a, f in q:
            acc = time // f
            if acc < a:
                total += a - acc
        return True if total <= K else False

    left = -1
    right = A[-1]*F[0]
    while (right - left > 1):
        mid = left + (right - left) // 2
        if isok(mid):
            right = mid
        else:
            left = mid
    print(right)

    
if __name__ == "__main__":
    resolve()
# Original solution
n,k = list(map(int,input().split()))
a = list(map(int,input().split()))
b = list(map(int,input().split()))
a.sort()
b.sort(reverse=True)
#print(a)
#print(b)
c = []
for i in range(n):
  c.append([-a[i]*b[i],b[i]])
#print(c)
import heapq
heapq.heapify(c)
cnt = 0
while True:
  now = heapq.heappop(c)
  if now[0] == 0:
    heapq.heappush(c,now)
    break
  red = (c[0][0] - now[0]) // now[1]
  #print(red)
  if red > k - cnt:
    heapq.heappush(c, [now[0]+(k-cnt)*now[1],now[1]] )
    break
  elif red == 0:
    heapq.heappush(c, [now[0]+now[1],now[1]] )
    cnt += 1
  else:
    heapq.heappush(c, [now[0]+red*now[1],now[1]] )
    cnt += red
  if k == cnt:
    break
  #print(cnt,c)
#print(c)
ans = 0
for i in range(n):
  if ans > c[i][0]:
    ans = c[i][0]
print((-1*ans))

# Optimized solution
n,k = list(map(int,input().split()))
a = list(map(int,input().split()))
b = list(map(int,input().split()))
a.sort()
b.sort(reverse=True)
#print(a)
#print(b)
big = 44
stand = 2 ** big
width = 2 ** (big-1)
if sum(a) <= k:
  print((0))
else:
  while True:
    tmp = []
    for i in range(n):
       tmp.append(max(0,a[i]-stand//b[i]))
    if width == 0:
      if sum(tmp) <= k:
        print(stand)
      else:
        print((stand+1))
      break
    if sum(tmp) <= k:
      stand -= width
      width //= 2
    else:
      stand += width
      width //= 2
    #print(stand,tmp)
# Original solution
n,k = list(map(int,input().split()))
a = list(map(int,input().split()))
b = list(map(int,input().split()))
a.sort()
b.sort(reverse=True)
#print(a)
#print(b)
big = 44
stand = 2 ** big
width = 2 ** (big-1)
if sum(a) <= k:
  print((0))
else:
  while True:
    tmp = []
    for i in range(n):
       tmp.append(max(0,a[i]-stand//b[i]))
    if width == 0:
      if sum(tmp) <= k:
        print(stand)
      else:
        print((stand+1))
      break
    if sum(tmp) <= k:
      stand -= width
      width //= 2
    else:
      stand += width
      width //= 2
    #print(stand,tmp)

# 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)
#print(a)
#print(f)
scale = 42
aim = 2 ** scale -1
gap = 2 ** (scale-1)
while True:
  train = 0
  for i in range(n):
    train += max(0, a[i] - aim//f[i])
  if gap == 0:
    if train <= k:
      print(aim)
    else:
      print((aim+1))
    break
  #print(aim,gap,train)
  if train <= k:
    aim -= gap
    gap //= 2
  else:
    aim += gap
    gap //= 2
# Original solution
#coding:utf-8
import sys
import bisect
import math
sys.setrecursionlimit(10**6)
write = sys.stdout.write
dbg = lambda *something : print(*something) if DEBUG else 0
DEBUG = True
def main(given = sys.stdin.readline):
    input = lambda : given().rstrip()
    LMIIS = lambda : list(map(int,input().split()))
    II = lambda : int(input())
    XLMIIS = lambda x : [LMIIS() for _ in range(x)]

    n, k = LMIIS()
    aa = LMIIS()
    ff = LMIIS()
    aa.sort(reverse=True)
    ff.sort()
    a = tuple(aa)
    f = tuple(ff)


    max_ = 10**12
    min_ = 0

    while max_ != min_ + 1:
        x = (max_ + min_) // 2
        shugyo = 0
        for i in range(n):
            shugyo += max(0, a[i] - x // f[i])

        if shugyo <= k:
            max_ = x
        else:
            min_ = x


    if x == min_:
        x += 1
    if sum(a) <= k:
        x = 0
    print(x)

if __name__ == '__main__':
    main()


# Optimized solution
#coding:utf-8
import sys
sys.setrecursionlimit(10**6)
write = sys.stdout.write
dbg = lambda *something : print(*something) if DEBUG else 0
DEBUG = True
def main(given = sys.stdin.readline):
    input = lambda : given().rstrip()
    LMIIS = lambda : list(map(int,input().split()))
    II = lambda : int(input())
    XLMIIS = lambda x : [LMIIS() for _ in range(x)]

    n, k = LMIIS()
    aa = LMIIS()
    ff = LMIIS()
    aa.sort(reverse=True)
    ff.sort()
    a = tuple(aa)
    f = tuple(ff)


    max_ = 10**12
    min_ = 0

    while max_ != min_ + 1:
        x = (max_ + min_) // 2
        shugyo = 0
        for i in range(n):
            shugyo += max(0, a[i] - x // f[i])

        if shugyo <= k:
            max_ = x
        else:
            min_ = x


    if x == min_:
        x += 1
    if sum(a) <= k:
        x = 0
    print(x)

if __name__ == '__main__':
    main()
# Original solution
from heapq import *
def abc144c():
  n,k=list(map(int,input().split()))
  a=sorted(list(map(int,input().split())))
  f=sorted(list(map(int,input().split())))[::-1]
  q=[] 
  for i,j in zip(a,f):
    heappush(q,(-i*j,j))
  for i in range(k):
    tmp,key=heappop(q)
    heappush(q,(tmp+key,key))
  ans,key=heappop(q)
  print((max(-ans,0)))
abc144c()


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

if sum(abilities)<=k:
  print((0))
  exit()
  
def check(score):
  ret=0
  for a,f in zip(abilities,foods):
    ret+=max(0,(a*f-score+f-1)//f)
  return ret<=k

ok=10**12+1
ng=0
for _ in range(50):
  mid=(ok+ng)//2
  if check(mid):
    ok=mid
  else:
    ng=mid
print(ok)
# Original solution
n,k=list(map(int,input().split()))
abilities=sorted(list(map(int,input().split())))
foods=sorted(list(map(int,input().split())),reverse=True)

if sum(abilities)<=k:
  print((0))
  exit()
  
def check(score):
  ret=0
  for a,f in zip(abilities,foods):
    ret+=max(0,(a*f-score+f-1)//f)
  return ret<=k

ok=10**12+1
ng=0
for _ in range(50):
  mid=(ok+ng)//2
  if check(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.sort()
f.sort(reverse=True)

def check(s):
  ret=0
  for i,j in zip(a,f):
    ret+=max(0,i-s//j)
  return ret<=k

ok=10**12+1
ng=-1
while ok-ng>1:
  mid=(ok+ng)//2
  if check(mid):
    ok=mid
  else:
    ng=mid
print(ok)
# Original solution
import heapq
import sys

input = sys.stdin.readline


class AtCoder:
    def __lt__(self, other):
        return self[0] < other[0]

    def main(self):
        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)

        hq = []
        heapq.heapify(hq)
        for i in range(N):
            heapq.heappush(hq, (-1 * A[i] * F[i], (F[i], A[i])))

        while K > 0:
            score = heapq.heappop(hq)
            if score[1][1] == 0:
                print((0))
                exit()
            else:
                if score[1][1] - F[0] > 0:
                    K -= score[1][1] - F[0]
                    new_A = F[0]
                else:
                    K -= 1
                    new_A = score[1][1] - 1
                heapq.heappush(hq, (-1 * new_A * score[1][0], (score[1][0], new_A)))

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


# Run main
if __name__ == '__main__':
    AtCoder().main()


# Optimized solution
import sys

input = sys.stdin.readline


class AtCoder:
    def main(self):
        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)

        l, r = -1, 10 ** 12
        while l + 1 < r:
            mid = (l + r) // 2

            s = 0
            for i in range(N):
                s += max(0, A[i] - mid // F[i])
            if s <= K:
                r = mid
            else:
                l = mid
        print(r)


# Run main
if __name__ == '__main__':
    AtCoder().main()
# Original solution
N, K = list(map(int, input().split()))
A = sorted(list(map(int, input().split())), reverse=True)
F = sorted(list(map(int, input().split())))


def binary_search(min_n, max_n):

    while max_n - min_n != 1:
        tn = (min_n + max_n) // 2
        if judge(tn):
            max_n = tn
        else:
            min_n = tn

    return max_n


def judge(tn):

    k = 0
    for i in range(N):
        if A[i] * F[i] > tn:
            k += A[i] - (tn // F[i])
        if k > K:
            return False

    return True


def solve():

    ans = binary_search(-1, 10**12)
    print(ans)


if __name__ == '__main__':
    solve()


# Optimized solution
import sys

input = lambda: sys.stdin.readline().rstrip()

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


def binary_search(min_n, max_n):

    while max_n - min_n != 1:
        tn = (min_n + max_n) // 2
        if judge(tn):
            max_n = tn
        else:
            min_n = tn

    return max_n


def judge(tn):

    k = 0
    for i in range(N):
        if A[i] * F[i] > tn:
            k += A[i] - (tn // F[i])
        if k > K:
            return False

    return True


def solve():

    ans = binary_search(-1, 10**12)
    print(ans)


if __name__ == '__main__':
    solve()
# Original solution
import math

def cal(sum_, F, N, K, d):
    count = 0
    for i in range(N):
        if sum_[i] > d:
            count += math.ceil((sum_[i] - d) / F[i])
            if count > K:
                #作ることができない
                return False
    return True


def main():
    N, K = list(map(int, input().split()))
    A = [int(i) for i in input().split()]
    F = [int(i) for i in input().split()]
    A.sort()
    F.sort(reverse=True)
    sum_ = []
    for i in range(N):
        sum_.append(A[i] * F[i])

    right = 10 ** 12
    left = 0
    count = 0
    pre_mid = 0
    while count < 100:
        mid = (right + left) // 2
        if pre_mid == mid:
            break
        if cal(sum_, F, N, K, mid):
            # midを小さくすることができる
            right = mid
        else:
            # midを大きくしなければならない
            left = mid + 1
        pre_mid = mid
        count += 1
    print(mid)


if __name__ == "__main__":
    main()


# Optimized solution
import math

def cal(sum_, F, N, K, d):
    count = 0
    for i in range(N):
        if sum_[i] > d:
            count += math.ceil((sum_[i] - d) / F[i])
            if count > K:
                #作ることができない
                return False
    return True


def main():
    N, K = list(map(int, input().split()))
    A = [int(i) for i in input().split()]
    F = [int(i) for i in input().split()]
    A.sort()
    F.sort(reverse=True)
    sum_ = []
    for i in range(N):
        sum_.append(A[i] * F[i])

    right = 10 ** 12
    left = 0
    count = 0
    pre_mid = 0
    while True:
        mid = (right + left) // 2
        if pre_mid == mid:
            break
        if cal(sum_, F, N, K, mid):
            # midを小さくすることができる
            right = mid
        else:
            # midを大きくしなければならない
            left = mid + 1
        pre_mid = mid
        count += 1
    print(mid)


if __name__ == "__main__":
    main()
# Original solution
# https://atcoder.jp/contests/abc144/tasks/abc144_e


# 修行を行わないときに最適なのは両方を逆順でソートしておくこと
# そうしたときになるべく食べ物のコストの大きい方から修行していったほうが最適なので
# greedyにKをみたすまで引いてあげる

# 求めたいのは最大値！
# 最小はxにできると仮定してみる？
# 答えはxより小さくなる→greedyに(Ai-a)Fi<xして判定すれば良い

import sys
sys.setrecursionlimit(1 << 25)
read = sys.stdin.readline
ra = range
enu = enumerate


def read_ints():
    return list(map(int, read().split()))


N, K = read_ints()
A = read_ints()
F = read_ints()
A.sort()  # 前からFの大きい順に対処していく人になっている
F.sort(reverse=True)
# print(A)
# print([x * y for x, y in zip(A, F)])  # ここから崩すことができるポイントを探せる

from math import ceil


def is_ok(x, K):
    for i in range(N):
        if A[i] * F[i] <= x:
            continue
        a = ceil(A[i] - x / F[i])  # Kから使うべき個数
        K -= a
        if K < 0:
            return False
    return K > -1


def meguru_bisect(ng, ok):
    '''
    define is_okと
    初期値のng,okを受け取り,is_okを満たす最小(最大)のokを返す
    ng ok は  とり得る最小の値-1 とり得る最大の値+1
    最大最小が逆の場合はよしなにひっくり返す
    '''
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid, K):
            ok = mid
        else:
            ng = mid
    return ok


print((meguru_bisect(-1, 10**12 + 1)))


# Optimized solution
# https://atcoder.jp/contests/abc144/tasks/abc144_e


# 修行を行わないときに最適なのは両方を逆順でソートしておくこと
# そうしたときになるべく食べ物のコストの大きい方から修行していったほうが最適なので
# greedyにKをみたすまで引いてあげる

# 求めたいのは最大値！
# 最小はxにできると仮定してみる？
# 答えはxより小さくなる→greedyに(Ai-a)Fi<xして判定すれば良い

import sys
sys.setrecursionlimit(1 << 25)
read = sys.stdin.readline
ra = range
enu = enumerate


def read_ints():
    return list(map(int, read().split()))


N, K = read_ints()
A = read_ints()
F = read_ints()
A.sort()  # 前からFの大きい順に対処していく人になっている
F.sort(reverse=True)
# print(A)
# print([x * y for x, y in zip(A, F)])  # ここから崩すことができるポイントを探せる


def is_ok(x, K):
    for i in range(N):
        if A[i] * F[i] <= x:
            continue
        a = A[i] - (x // F[i])  # Kから使うべき個数
        K -= a
        if K < 0:
            return False
    return K > -1


def meguru_bisect(ng, ok):
    '''
    define is_okと
    初期値のng,okを受け取り,is_okを満たす最小(最大)のokを返す
    ng ok は  とり得る最小の値-1 とり得る最大の値+1
    最大最小が逆の場合はよしなにひっくり返す
    '''
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid, K):
            ok = mid
        else:
            ng = mid
    return ok


print((meguru_bisect(-1, 10**12 + 1)))
# Original 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)

def is_ok(x):
    c = 0
    for i in range(n):
        a = A[i]
        f = F[i]
        if a >= x//f:
            c += a-x//f
    if c <= k:
        return True
    else:
        return False

if is_ok(0):
    print((0))
    exit()

l = 0
r = 10**18
while l+1 < r:
    c = (l+r)//2
    if is_ok(c):
        r = c
    else:
        l = c
print(r)


# 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)

def is_ok(x):
    c = 0
    for a, f in zip(A, F):
        c += max(0, a-x//f)
    if c <= k:
        return True
    else:
        return False

ng = -1
ok = 10**18
while ng+1 < ok:
    c = (ng+ok)//2
    if is_ok(c):
        ok = c
    else:
        ng = c
print(ok)
# Original 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)

left, right = -1, a[-1] * f[0]

while right - left > 1:
    mid = (left + right) // 2
    ck = sum([max(0, a[i] - mid // f[i]) for i in range(n)])
    if ck <= k: 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()))
a.sort()
f.sort(reverse=True)

left, right = -1, a[-1] * f[0]

while right - left > 1:
    mid = (left + right) // 2
    ck = 0
    for i in range(n): ck += max(0, a[i] - mid // f[i])
    if ck <= k: right = mid
    else: left = mid

print(right)
# Original solution
import heapq
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()

if sum(A) <= K:
  print("0")
  exit(0)

L = []
for i in range(N):
  heapq.heappush(L, (-A[i]*F[i],A[i],F[i]))

for i in range(K):
  temp = heapq.heappop(L)
  rep = (-(temp[1]-1)*temp[2], (temp[1]-1), temp[2])
  heapq.heappush(L, rep)
ans = heapq.heappop(L)
print((-1*ans[0]))

# Optimized solution
def solve(B,G,x):
  sums = 0
  for i in range(N):
    req = B[i] - x//G[i] 
    sums += max(0,req)
  if sums <= K:
    return True
  else:
    return False

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()

if sum(A) <= K:
  print("0")
  exit(0)

L = []
MAX = 0
for i in range(N):
  temp = A[i]*F[i]
  MAX = max(MAX,temp)
ng = 1
ok = MAX+1
while abs(ng-ok) > 1:
  mid = (ok+ng)//2
  #print(mid,solve(A,F,mid))
  if solve(A,F,mid):
    ok = mid
  else:
    ng = mid
print(ok)
# Original solution
import sys
import heapq

N,K=list(map(int,input().split()))
alist=list(map(int,input().split()))
flist=list(map(int,input().split()))

alist.sort()
flist.sort(reverse=True)
#print(alist)
#print(flist)

if sum(alist)<=K:
  print((0))
  sys.exit(0)
  
hq=[]
for i in range(N):
  heapq.heappush(hq,(-alist[i]*flist[i],alist[i],flist[i]))
  
for i in range(K):
  naf,a,f=heapq.heappop(hq)
  naf+=f
  a-=1
  if a>0:
    heapq.heappush(hq,(naf,a,f))
    
if len(hq)==0:
  print((0))
else:
  naf,a,f=heapq.heappop(hq)
  print((-naf))

# Optimized solution
import sys
N,K=list(map(int,input().split()))
alist=list(map(int,input().split()))
flist=list(map(int,input().split()))
alist.sort()
flist.sort(reverse=True)
#print(alist)
#print(flist)

def check(m):
  cnt=0
  for i in range(N):
    if alist[i]*flist[i]>m:
      cnt+=-(-(alist[i]*flist[i]-m)//flist[i])
  
  #print(m,cnt,K)
  if cnt<=K:
    return True
  else:
    return False

if sum(alist)<=K:
  print((0))
  sys.exit(0)

baseline=0
for i in range(N):
  baseline=max(baseline,alist[i]*flist[i])
#print(baseline)

l,r=0,baseline
while l<=r:
  mid=(l+r)//2
  #print(l,mid,r)
  if not check(mid-1) and check(mid):
    print(mid)
    break
  elif not check(mid):
    l=mid+1
  else:
    r=mid-1
# Original solution
import math
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)

hq = []

upper_limit = int(1e+12)
lower_limit = int(0)

def is_ok(checking):
    cost = 0
    for i in range(n):
        cost += max(0,math.ceil((a[i]*f[i]-checking)/f[i]))
    if cost <= k:
        return True
    else:
        return False

def meguru_bisect(ng, ok):
    while (abs(ok-ng)>1):
        mid = (ok+ng)//2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok

ok = meguru_bisect(-1, 1e+100) 
print((int(ok)))
# 初期値の範囲は取りえる値-1～+1とする←範囲内はok,ngどちらもあり得るため

# Optimized solution
import math
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)

hq = []

def is_ok(checking):
    cost = 0
    for i in range(n):
        cost += max(0,math.ceil((a[i]*f[i]-checking)/f[i]))
    if cost <= k:
        return True
    else:
        return False

def meguru_bisect(ng, ok):
    while (abs(ok-ng)>1):
        mid = (ok+ng)//2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok

ok = meguru_bisect(-1, 1e+12+1) 
print((int(ok)))
# 初期値の範囲は取りえる値-1～+1とする←範囲内はok,ngどちらもあり得るため
# Original solution
import heapq
N, K = list(map(int, input().split()))
A = sorted([int(i) for i in input().split()], reverse=True)
F = sorted([int(i) for i in input().split()])

if sum(A) <= K:
    print((0))
    exit()
else:
    hq = [(-(A[i]*F[i]), A[i], F[i]) for i in range(N)]
    heapq.heapify(hq)  # リストhqのheap化

    for i in range(K):
        c, a, f = heapq.heappop(hq)  # heap化されたリストhqから最小値を削除＆その最小値を出力

        a -= 1
        heapq.heappush(hq, (-(a*f), a, f))

    c, a, f = heapq.heappop(hq)  # heap化されたリストhqから最小値を削除＆その最小値を出力
    print((-c))


# Optimized solution
N, K = list(map(int, input().split()))
A = sorted([int(i) for i in input().split()])
F = sorted([int(i) for i in input().split()], reverse=True)

if sum(A) <= K:
    print((0))
    exit()
else:
    OK = 10**12
    NG = -1

    while OK-NG > 1:
        mid = (OK+NG)//2
        cnt = 0

        for i, a in enumerate(A):
            cnt += max(0, a-mid//F[i])
        if cnt <= K:
            OK = mid
        else:
            NG = mid

print(OK)
# Original 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)

def calc(x): #全てx以下にするために何回変える必要があるか
    tmp = 0
    for a, f in zip(A, F):
        tmp += max(0, a - (x // f))
    return tmp

ng = -1
ok = 10 ** 18
while ok - ng > 1:
    mid = (ok + ng) // 2
    if calc(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()
F.sort(reverse = True)

def calc(x): #全てx以下にするために何回変える必要があるか
    tmp = 0
    for a, f in zip(A, F):
        tmp += max(0, a - (x // f))
        if tmp > K:
            return tmp
    return tmp

ng = -1
ok = 10 ** 18
while ok - ng > 1:
    mid = (ok + ng) // 2
    if calc(mid) <= K:
        ok = mid
    else:
        ng = mid

print (ok)
# Original 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()


def judge(x):
    val = 0
    for i in range(N):
        val += max(A[i] - x // F[i], 0)
        if val > K:
            return False
    if val <= K:
        return True


ub = 10**12
lb = 0

for i in range(150):
    x = (ub+lb)/2
    if judge(x):
        ub = x
    else:
        lb = x

print((int(x)))

# 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()


def judge(x):
    val = 0
    for i in range(N):
        val += max(A[i] - x // F[i], 0)
        if val > K:
            return False
    if val <= K:
        return True


ub = 10**12
lb = -1

while lb + 1 < ub:
    x = (ub+lb)/2
    if judge(x):
        ub = x
    else:
        lb = x

print((int(ub)))
# Original solution
from heapq import heappop, heappush, heapify
N, K = list(map(int, input().split()))
A = [int(i) for i in input().split()]
F = [int(i) for i in input().split()]
A.sort()
F.sort(reverse=True)
H = []
for i in range(N):
    H.append((-A[i]*F[i],F[i]))
heapify(H)

while K>0:
    K -= 1
    x,y = heappop(H)
    x = min(0,x+y)
    heappush(H,(x,y))
print((-H[0][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
    cnt = 0

    for i,e in enumerate(a):    
        cnt += max(0,e-mid//f[i])
    if cnt <= k:
        ok = mid
    else:
        ng = mid

print(ok)
# Original 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
    cnt = 0

    for i,e in enumerate(a):    
        cnt += max(0,e-mid//f[i])
    if cnt <= 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()
F.sort(reverse=True)
ok = 10**12
ng = -1

while ok-ng>1:
  X = (ok+ng)//2
  tmp = 0
  for i,e in enumerate(A):
    tmp += max(e-X//F[i],0)
  if tmp<=K:
    ok = X
  else:
    ng = X
print(ok)