#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <bits/stdc++.h>
#include <set>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <map>
#define ll long long
using namespace __gnu_pbds;
using namespace std;
template <class T>
using ordered_set = tree<T , null_type , less<T> , rb_tree_tag , tree_order_statistics_node_update>;
template <class T>
using ordered_set1 = tree<T , null_type , greater<T> , rb_tree_tag , tree_order_statistics_node_update>;
// less<T>/greater<T> = ascending/descending.
// less_equal<>/greater_equal<> for ordered multiset
// ordered_multiset note : s.find(), s.erase() don't work + s.upper_bound() and s.lower_bound() swap jobs;
void fastIO(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("stdin", "r", stdin);
    //freopen("stdout", "w", stdout);
}
ll n,k;
struct ingredient {
    ll cookiecount;
    ll remainder;
    ll req;
};
bool cmp(ingredient x, ingredient y) {
    return x.cookiecount<y.cookiecount;
}
bool cmp2(ingredient x,ll y) {
    return x.cookiecount < y;
}
bool enough(ll cookienum,vector<ingredient> &can) {
    ll lastindex=lower_bound(can.begin(),can.end(),cookienum,cmp2)-can.begin();
    for (ll i =0; i<lastindex; i++) {
        if (k<=0) return false;
        k = k - (cookienum-can[i].cookiecount-1)*can[i].req - can[i].remainder;
    }
    return true;
}
int main() {
    fastIO();
    cin>>n>>k;
    vector<ll> owned(n);
    vector<ingredient> v(n);
    for (ll i = 0; i<n; i++) {
        cin>>v[i].req;
    }
    for (ll i = 0; i<n; i++) {
        cin>>owned[i];
    }
    for (ll i = 0; i<n; i++) {
        v[i].cookiecount=owned[i]/v[i].req;
        v[i].remainder=v[i].req-(owned[i]%v[i].req);
    }
    ll l = 0, r = 2e9,mid,ans=0;
    while (l<=r) {
        mid=(l+r)/2;
        if (enough(mid,v)){
            ans=mid;
            l = mid + 1;
        }
        else {
            r = mid - 1;
        }
    }
    cout<<ans;
}
