#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
 
using namespace std;
 
const int MAX_N = int(1e6) + 10;
const long long int MOD=1e9+7;
const long long int INF=1e18;

 
typedef long long int ll;
typedef unsigned long long int llu;



struct fenwick{
  int lim;
  long long int *tree;
  fenwick(int _lim){
      lim=_lim;
      tree=new long long int[lim];
  }
  void init(){
    for(int i=0;i<lim;i++){
      tree[i]=0;
    }
  }
  void update(int x,long long int v){
    while(x<lim){
      tree[x]+=v;
      x+=x&(-x);
    }
  }
  long long int query(int x){
    long long int ans=0;
    while(x>0){
      ans+=tree[x];
      x-=x&(-x);
    }
    return ans;
  }
  int _query(int k){
    int low=1;
    int high=500000;
    int ans=0;int x=k;
    while(low<=high){
      int mid=low+(high-low)/2;
      if(query(mid)>=x){
        ans=mid;
        high=mid-1;
      }else{
        low=mid+1;
      }
    }
    return ans;
  }
};/*
struct z_function{
  string &txt;
  int *z;
  z_function(string &_txt):txt(_txt){
    z=new int[1+txt.length()];
  }
  void cal(){
    z[0]=0;
    int l=0;
    int r=0;
    for(int i=1;i<txt.length();i++){
    //  cout<<l<<" "<<r<<endl;
      if(i>r){
        l=i;
        r=i;
        while(r<txt.length() && txt[r]==txt[r-l]){
          r++;
        }
      //  cout<<r<<" ";
        z[i]=r-l;
        r=r-1;
      }else{
              if(z[i-l]<r-i+1)
                z[i]=z[i-l];
              else{
                l=i;
                while(r<txt.length() && txt[r]==txt[r-l]){
                  r++;
                }
                z[i]=r-l;
                r=r-1;
              }
      }
    }
  }
};
struct palindromic_tree{
  map<char,struct palindromic_tree*>m;
  int length;
  int end_indx;
  struct palindromic_tree* suffix;
  palindromic_tree(int _length,int _end_indx){
    length=_length;
    end_indx=_end_indx;
  }
};
class palindromic_string{
public:
  string &s;
  struct palindromic_tree* real_root;
  struct palindromic_tree* imaginary_root;
  struct palindromic_tree* curr;
  long long int *prefix;
  palindromic_string(string &_s):s(_s){
       real_root=new palindromic_tree(0,-1);
       imaginary_root=new palindromic_tree(-1,-1);
       curr=real_root;
       real_root->suffix=imaginary_root;prefix=new long long int[1+s.length()];
       imaginary_root->suffix=imaginary_root;
  }
  void add(char ch){
    int indx=s.size();
    struct palindromic_tree* temp=curr;
    s+=ch;
    while(indx-temp->length-1<0 || s[indx-temp->length-1]!=s[indx])
      temp=temp->suffix;
    if((temp->m).find(ch)!=(temp->m).end()){
      curr=(temp->m)[ch];
      return;
    }else{
      curr=new palindromic_tree((temp->length)+2,indx);
    }
 
    (temp->m)[ch]=curr;
 
    if(curr->length==1){
      curr->suffix=real_root;
      return;
    }else{
      temp=temp->suffix;
      while(indx-temp->length-1<0 || s[indx-temp->length-1]!=s[indx])
        temp=temp->suffix;
      curr->suffix=(temp->m)[ch];
    }
  }
 
  void cal(){
    prefix[0]=0;
    long long int p=29LL;
    for(int i=0;i<s.length();i++){
      prefix[i+1]=(prefix[i]+(p*s[i]))%MOD;
      p=(p*p)%MOD;
    }
  }
};
struct prime_numbers{
  int *seive;
  int len;
  prime_numbers(int _len){
    len=_len;
    seive=new int[len+1];
  }
  void init(){
    seive[0]=1;
    seive[1]=1;
  }
  void cal(){
    for(int i=2;i*i<=len;i++){
      for(int j=i*i;j<=len;j+=i){
        seive[j]=1;
      }
    }
  }
};
*/
ll mul(ll a,ll b){
  ll ans=(a%MOD*b%MOD)%MOD;
  if(ans<0)ans+=MOD;
  return ans;
}
ll add(ll a,ll b){
  a=a%MOD;
  b=b%MOD;
  ll ans=(a+b)%MOD;
  if(ans>MOD)ans-=MOD;
  if(ans<0)ans+=MOD;
  return ans;
}
ll power(ll a,ll b,ll c){
  ll ans=1;
  while(b){
    if(b&1){
      ans=ans*a;
      ans=ans%c;
    }
    a=a*a;
    a=a%c;
    b=b/2;
  }
  return ans;
}
template<class T1, class T2>
istream &operator>>(istream &in, pair<T1, T2> &P){
  in >> P.first >> P.second;
  return in;
}
template<class T1, class T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &P){
  out << "(" << P.first << ", " << P.second << ")";
  return out;
}
template<class T>
istream &operator>>(istream &in, vector<T> &arr){
  for(auto &x: arr) in >> x;
  return in;
}
template<class T>
ostream &operator<<(ostream &out, const vector<T> &arr){
  for(auto &x: arr) out << x << ' '; cout << "\n";
  return out;
}
template<class T>
istream &operator>>(istream &in, deque<T> &arr){
  for(auto &x: arr) in >> x;
  return in;
}
template<class T>
ostream &operator<<(ostream &out, const deque<T> &arr){
  for(auto &x: arr) out << x << ' '; cout << "\n";
  return out;
}
mt19937 rnd(time(0));
struct sparse{
  int table[200005][25];
  int n;
  sparse(int len1):n(len1){
  }
  void init(int *a){
 
    for(int i=1;i<=n;i++){
      table[i][0]=a[i];
    }
 
   // cout<<table[1][0]<<endl;
 
    for(int j=1;j<25;j++){
      for(int i=1;i<=n;i++){
        if(i+(1<<j)-1<=n){
          table[i][j]=__gcd(table[i][j-1],table[i+(1<<(j-1))][j-1]);
        }
      }
    }
  }
  int find(int *a,int start,int end){
    int dis=end-start+1;
    int g=0;
    for(int j=25;j>=0;j--){
      if(dis&(1<<j)){
     //     cout<<dis<<" "<<table[start][j]<<" "<<j<<endl;
          g=__gcd(g,table[start][j]);
          start=start+(1<<j);
      }
    }
    return g;
  }
};
inline ll gcd(ll a,ll b){
  while(b)a%=b,swap(a,b);
  return a;
}
// vector<pair<int,int> >v[1000005];
// ll t[1000005];ll h[1000005]; ;;;;;;multiset<pair<ll,pair<int,pair<ll,ll> > > >s;ll A,B;bool vis[1000005];ll dis[1000005];int parent[1000005];vector<int>ans;
// ll c[1000005];

struct SOS{
  ll *dp;
  int limit;
  vector<int>&arr;

  SOS(int _limit,vector<int>&v):arr(v){

    limit=_limit;
    dp=new ll[1<<limit];
  }

  void init(){
    for(int i=0;i<(1<<limit);i++){
      dp[i]=0;
    }
    for(int i=0;i<arr.size();i++){
       dp[arr[i]]++;
    }
  }

  void build(){
    for(int i=0;i<limit;i++){
      for(int j=0;j<(1<<limit);j++){
        if(j&(1<<i)){
          dp[j]+=dp[j^(1<<i)];
      }
    }
  }
}

};
void solve(){
  int n;
  ll K;
  cin>>n>>K;
  vector<ll>v(n+1);
  vector<ll>F(n+1);
  ll sum=0;
  for(int i=1;i<=n;i++){
    cin>>v[i];
  }
  for(int j=1;j<=n;j++){
    cin>>F[j];
  }

  sort(v.begin()+1,v.end());

  sort(F.begin()+1,F.end());
  reverse(F.begin()+1,F.end());

  for(int i=1;i<=n;i++){
    sum+=v[i];
  }

  if(sum<=K){
    cout<<0<<endl;
    return;
  }

  ll low=0;
  ll high=1e18;
  ll ans=0;
  while(low<=high){
    ll mid=low+(high-low)/2LL;
    ll steps=0;
    for(int i=1;i<=n;i++){
      ll d=v[i]*F[i];
      if(d<=mid)continue;
      steps+=v[i]-mid/F[i];
    }
    if(steps<=K){
      ans=mid;
      high=mid-1;
    }else{
      low=mid+1;
    }
  }

  cout<<ans<<endl;
}
int main()
{

  /*freopen("f.in","r",stdin);
  */
 
  // int n,m;
  // cin>>n>>m; ;;;;;;for(int i=1;i<=n;i++){
  //   dis[i]=1000000000000000000LL;
  // }

  // cin>>A>>B;

  // for(int i=1;i<=m;i++){
  //   ;;;;;;
  //   int x,y;
  //   cin>>x>>y;
  //   v[x].push_back(make_pair(y,i));
  //   v[y].push_back(make_pair(x,i));
  //   cin>>t[i]>>c[i]>>h[i];
  // }

  // dis[1]=0;

  // s.insert({0,{1,{0,0}}});

  // while(!s.empty()){
  //   auto p=*s.begin();
  //   int x=p.second.first;
  //   s.erase(s.begin());
  //   if(vis[x]==true)continue;
  //   vis[x]=true;
  //   for(int j=0;j<v[x].size();j++){
  //     int y=v[x][j].first; ;;;;;;int cnt=v[x][j].second;
  //     if(vis[y]==false){
  //       ll next=((p.second.second.first+h[cnt]-1)/h[cnt])*h[cnt]+t[cnt];
  //       ll cost=A*next+B*(p.second.second.second+c[cnt]);
  //        // cout<<x<<" "<<y<<" "<<cost<<endl;
  //       if(cost<dis[y]){
  //         parent[y]=x;
  //         dis[y]=cost;
  //         s.insert({cost,{y,{next,p.second.second.second+c[cnt]}}});
  //       }

  //     }
  //   }
  // }

  // while(n){
  //   ans.push_back(n);
  //   n=parent[n];
  // }

  // for(int j=ans.size()-1;j>=1;j--){
  //   cout<<ans[j]<<" ";
  // }
  
  solve();


}



/*

PROBLEM STATEMENT Points: 50
Note: You can skip to BRIEF if you do not want to read the complete story.

Khaolin Temple is world's most famous algorithmic pilgrimage situated on Mount Kong in China. It is believed that human civilization has never seen better coders than Khaolin Coders and its well known about them that that they were so good at problem solving that they could even solve "NP-Complete" problems in constant amortized time. There are many folktales about Khaolin Coders, the most famous ones being about Monk Bosky who was incomparably the best Khaolin Coder. Following is a famous incident from Monk Bosky's early days at Khaolin Temple.

"During his early days at Khaolin Temple Bosky was the brightest and most notorious pupil at Khaolin. Once his master asked all his pupils to water the khaolin flowers[khaolin flowers are special flower which grow 1 meter tall on pouring 1 litre water to them]. Master wanted to keep everyone busy [specially Bosky] so that he could meditate in silence. He told his pupils where the flowers were and how tall they were at present and asked them to come back only when they are finished watering all the flowers assigned to them. He also told them that only those pupils will be allowed to enter the temple who will tell the correct heights of flowers after the watering process is complete.

Master knew that his pupils will cheat and calculate the height that will be achieved by flowers after pouring water to them if he asks them to water them one by one, hence he decided to make it difficult for them to calculate the height by asking them to follow certain rules while watering flowers.

He asked them to follow the following rules while watering flowers:

Rule 1: Every pupil will water all flowers assigned to him as an array of n khaolin flowers with heights [H1 H2 ... Hn].
Rule 2: When a pupil will be standing next to Kth flower he will have to go back to (K-1)th flower and inspect its height,if it is greater or equal to height of Kth flower he will have to note its index down,then he will have to go further back to (K-2)th flower and if its height is greater or equal to Kth flower he will again have to note down its index. And he must continue to do so till he reaches flower 1. After reaching flower 1 he has a list of indices of flowers with height>= Hk [i.e. height of Kth flower].Now he will have to bring sufficient water from river nearby and pour 1 litre water to each flower whose index he has noted down [NOTE: By pouring 1 litre water to the flowers he will be making them 1 meter taller].
Rule 3: Pupil can move to Kth flower only if he has applied Rule 2 standing next to (K-1)th flower. If (K+1)th flower exists he must continue to apply Rule 2 to (K+1)th flower after he has applied Rule 2 standing next to Kth flower.
Rule 4: Pupil must start watering process standing next to 1st flower

Master knew that if his pupils sincerely followed these rules while watering flowers they won't be able to water all flowers before a month's time span and in the meantime he could meditate in silence without being disturbed by anyone. Since this task was very boring, Master decided to reward the pupil who enters back into temple first,obviously by telling heights of all flowers correctly after the process of watering the plants was complete. As a reward Master will teach him secret algorithmic skills till the next pupil enters the temple and as soon as the next pupil enters the temple Master will stop teaching the first pupil. With that said,Master sent all his pupils to water Khaolin flowers and expected that no pupil will return before a month and also expected that he will have to teach secret algorithms as a reward only for few hours because if they follow same process they will complete the task in nearly equal time.

But to Master's utter surprise he heard a pupil on the gate of Khaolin Temple claiming that he has watered all the flowers in an hour and that pupil was Bosky who further astonished Master by reporting the correct heights of the flowers as expected by Master. Master refused to reward him as Bosky clearly cheated and did not follow his rules. But after Bosky explained Master the process he followed to water flowers which produced same height of flowers as Master expected,Master was so impressed that he taught him everything he knew for the next month and also declared him to be heir to his position in the Khaolin."

No one in today's world knows the algorithm Great Monk Bosky used to solve the problem given by his master but today we have at least been able to reconstruct such cases and time limits which can only be passed by using algorithm which is equivalent to Monk Bosky's algorithm or more efficient than it. You are thereby challenged to match Monk Bosky's efficiency and mightiness by telling the heights of flowers after watering them as stated in the question.

BRIEF
- An array A of N integers is given [a1, a2 … aN].
- Step 1: For every A[i] (1 <= i <= N), create an array B of size m which contains integers [b1, b2 … bm] where B[j] < i (for all 1 <= j <= m) and each A[B[j]] >= A[i].
- Step 2: Increment B[j]th element in A with 1 (i.e. do A[B[j]] = A[B[j]] + 1, where 1 <= j <= m).
- Step 3: If i < N, do i = i+1 and goto Step 1, otherwise print array A.

Your task is to print the transformed array A.

Input:
First line will contain an integer N, where N represents the number of flowers (integers). Next line will contain N space-separated integers H1 H2 ... HN representing heights of flowers in sequential order.

Output
Print N space separated integers that represent heights of flowers after all flowers have been watered.

Constrains
1 <= N <= 105
1 <= Hi <= 109

SAMPLE INPUT 
5
7 5 2 1 8
SAMPLE OUTPUT 
11 7 3 1 8
Explanation
7 5 2 1 8 (begin) -> 8 5 2 1 8 (A[1] >= A[2]) -> 9 6 2 1 8 (A[1], A[2] >= A[3]) -> 10 7 3 1 8 (A[1], A[2], A[3] >= A[4]) -> 11 7 3 1 8 (A[1] >= A[5])

*/


Measured memory_bytes: 3328