/*
 * じょえチャンネル
 * 高評価・チャンネル登録よろしくおねがいします！
 * https://www.youtube.com/channel/UCRXsI3FL_kvaVL9zoolBfbQ
 */

#include <bits/stdc++.h>

//#pragma GCC target("avx2")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")

#define f(i,n) for(int i=0;i<(n);i++)




//here!!!
// define int long long !!!!!

#define int long long

// define int long long !!!!!


#define mod (int)((1e9)+7)
//constexpr int mod = 998244353ll;


#ifdef int
#define inf (int)(3e18)
#else
#define inf (int)(5e8)
#endif

#define intt long long
#define itn long long
#define P pair<int,int>

#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,n) for(int i=1;i<=n;i++)

#define ALL(v) v.begin(),v.end()

using namespace std;

//Library
//モッドパウ
inline int modpow(int x, int y, int m = mod) {
    int res = 1;
    while (y) {
        if (y & 1) {
            res *= x;
            res %= m;
        }
        x = x * x % m;
        y /= 2;
    }
    return res;
}

int mypow(int x, int y) {
    int res = 1;
    while (y) {
        if (y % 2) {
            res *= x;
        }
        x = x * x;
        y /= 2;
    }
    return res;
}
//is the number (x) a prime number?
bool prime(int x) {
    for (int i = 2; i * i <= x; i++) {
        if (!(x % i)) {
            return false;
        }
    }
    return true;
}


//saidai-kouyakusuu
inline int gcd(int x, int y) {
    if (!y) {
        return x;
    }
    return gcd(y, x % y);
}


//number of keta
int keta(int x) {
    int ans = 0;
    while (x) {
        x /= 10;
        ans++;
    }
    return ans;
}

//sum of keta
int ketasum(int x) {
    int ans = 0;
    while (x) {
        ans += x % 10;
        x /= 10;
    }
    return ans;
}

inline int lcm(int x, int y) {
    int ans = x / gcd(x, y) * y;
    return ans;
}
int twobeki(int x) {
    int ans = 0;
    while (1) {
        if (!(x & 1)) {
            ans++;
            x /= 2;
        }
        else {
            break;
        }
    }
    return ans;
}


template <class T, class U>
inline bool chmax(T& lhs, const U& rhs) {
    if (lhs < rhs) {
        lhs = rhs;
        return 1;
    }
    return 0;
}
template <class T, class U>
inline bool chmin(T& lhs, const U& rhs) {
    if (lhs > rhs) {
        lhs = rhs;
        return 1;
    }
    return 0;
}
void Yes(){
    cout<<"Yes"<<endl;
}
void No(){
    cout<<"No"<<endl;
}
void YES(){
    cout<<"YES"<<endl;
}
void NO(){
    cout<<"NO"<<endl;
}


#define fin(i) scanf("%lld",&i)
#define fout(i) printf("%lld",i)
#define fendl printf("\n")

int kai(int x, int y) {
    int res = 1;
    for (int i = x - y + 1; i <= x; i++) {
        res *= i; res %= mod;
    }
    return res;
}

int comb(int x, int y) {
    if (y > x)return 0;
    //    cout<<kai(x, y)<<' '<<modpow(kai(y, y), mod - 2)<<endl;
    return kai(x, y) * modpow(kai(y, y), mod - 2) % mod;
}
//Library-End


#define vecin(v) for(int i=0;i<v.size();i++)scanf("%lld",&v[i]);
#define vecout(v) {for(int i=0;i<(int)v.size();i++)printf("%lld ",v[i]);printf("\n");}

template<typename T, typename U>
class SegTree {
    int n = 1;
    T* node = NULL;
    U* lazy = NULL;
    bool* lazyflag = NULL;
    T nodee;
    function<T(T, T)> nodef;
    function<U(U, U)> lazyf;
    function<T(T, U, int, int)> updf;
    void eval(int k, int l, int r) {
        if (lazyflag[k]) {
            node[k] = updf(node[k], lazy[k], l, r);
            if (r - l > 1) {
                if (lazyflag[2 * k + 1])lazy[2 * k + 1] = lazyf(lazy[2 * k + 1], lazy[k]);
                else lazy[2 * k + 1] = lazy[k];
                if (lazyflag[2 * k + 2])lazy[2 * k + 2] = lazyf(lazy[2 * k + 2], lazy[k]);
                else lazy[2 * k + 2] = lazy[k];
                lazyflag[2 * k + 1] = lazyflag[2 * k + 2] = true;
            }
            lazyflag[k] = false;
        }
    }
public:
    SegTree(int m, T init, T nodee, function<T(T, T)> nodef, function<U(U, U)> lazyf, function<T(T, U, int, int)> updf) :nodee(nodee), nodef(nodef), lazyf(lazyf), updf(updf) {
        delete[] node;
        delete[] lazy;
        while (n < m)n *= 2;
        node = new T[2 * n], lazy = new U[2 * n], lazyflag = new bool[2 * n];
        for (int i = n - 1; i < 2 * n - 1; i++)node[i] = init;
        for (int i = n - 2; i >= 0; i--)node[i] = nodef(node[2 * i + 1], node[2 * i + 2]);
        rep(i, 2 * n)lazyflag[i] = false;
    }
    SegTree(int m, T nodee, function<T(T, T)> nodef, function<U(U, U)> lazyf, function<T(T, U, int, int)> updf, vector<T> initvec) :nodee(nodee), nodef(nodef), lazyf(lazyf), updf(updf) {
        if (m != initvec.size()) {
            cerr << "Invalid Initialization of SegmentTree" << endl;
            exit(1);
        }
        delete[] node;
        delete[] lazy;
        while (n < m)n *= 2;
        node = new T[2 * n], lazy = new U[2 * n], lazyflag = new bool[2 * n];
        for (int i = n - 1; i < 2 * n - 1; i++) {
            if (i - n + 1 < m)node[i] = initvec[i - n + 1];
            else node[i] = nodee;
        }
        for (int i = n - 2; i >= 0; i--)node[i] = nodef(node[2 * i + 1], node[2 * i + 2]);
        rep(i, 2 * n)lazyflag[i] = false;
    }
    ~SegTree() {
        delete[] node;
        delete[] lazy;
    }
    void update(int a, int b, U x, int k = 0, int l = 0, int r = -1) {
        if (r == -1)r = n;
        eval(k, l, r);
        if (b <= l || r <= a)return;
        if (a <= l && r <= b) {
            lazyflag[k] = true;
            lazy[k] = x;
            eval(k, l, r);
        }
        else {
            update(a, b, x, 2 * k + 1, l, (l + r) / 2);
            update(a, b, x, 2 * k + 2, (l + r) / 2, r);
            node[k] = nodef(node[2 * k + 1], node[2 * k + 2]);
        }
    }
    T query(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r == -1)r = n;
        eval(k, l, r);
        if (b <= l || r <= a)return nodee;
        if (a <= l && r <= b)return node[k];
        T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
        T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
        return nodef(vl, vr);
    }
};
template<typename T>
class RAQRSQ :public SegTree<T, T> {
public:
    RAQRSQ(int size, const T& def = T()) :SegTree<T, T>(size, def, T(), [](T a, T b) {return a + b; }, [](T a, T b) {return a + b; }, [](T a, T b, int l, int r) {return a + (r - l) * b; }) {};
};
template<typename T>
class RAQRMiQ :public SegTree<T, T> {
public:
    RAQRMiQ(int size, const T& def = T()) :SegTree<T, T>(size, def, inf, [](T a, T b) {return min(a, b); }, [](T a, T b) {return a + b; }, [](T a, T b, int l, int r) {return a + b; }) {};
};
template<typename T>
class RAQRMaQ :public SegTree<T, T> {
    using base = SegTree<T, T>;
public:
    RAQRMaQ(int size, const T& def = T()) :base(size, def, -inf, [](T a, T b) {return max(a, b); }, [](T a, T b) {return a + b; }, [](T a, T b, int l, int r) {return a + b; }) {};
};
template<typename T>
class RUQRSQ :public SegTree<T, T> {
    using base = SegTree<T, T>;
public:
    RUQRSQ(int size, const T& def = T()) :base(size, def, T(), [](T a, T b) {return a + b; }, [](T a, T b) {return b; }, [](T a, T b, int l, int r) {return (r - l) * b; }) {};
};
template<typename T>
class RUQRMQ :public SegTree<T, T> {
    using base = SegTree<T, T>;
public:
    RUQRMQ(int size, const T& def = T()) :base(size, def, T(), [](T a, T b) {return min(a, b); }, [](T a, T b) {return b; }, [](T a, T b, int l, int r) {return b; }) {};
};
template<typename T>
class PPAP :public SegTree<T, T> {
    using base = SegTree<T, T>;
public:
    PPAP(int size, const T& def = T()) :base(size, def, inf, [](T a, T b) {return min(a, b); }, [](T a, T b) {return min(a,b); }, [](T a, T b, int l, int r) {return min(a,b); }) {};
};
#define R_MIN ([](long long a, long long b) { return min(a, b); })
#define R_MAX ([](long long a, long long b) { return max(a, b); })
#define R_SUM ([](long long a, long long b) { return a + b; })

#define NORMAL_UPDATE ([](long long a, long long b) { return b; })
#define ADD_UPDATE ([](long long a, long long b) { return a + b; })
#define MINUS_UPDATE ([](long long a, long long b) { return a - b; }

class Union_Find {
    vector<int> par;
    vector<int> rankmy;
    vector<int> ookisa;
    
public:
    Union_Find(int size) {
        par = vector<int>(size);
        rankmy = vector<int>(size);
        ookisa=vector<int>(size);
        for (int i = 0; i < size; i++) {
            par[i] = i;
            ookisa[i]=1;
        }
    }
    
    int find(int x) {
        if (par[x] == x) {
            return x;
        }
        return par[x] = find(par[x]);
    }
    
    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return;
        }
        if (rankmy[x] < rankmy[y]) {
            par[x] = y;
            ookisa[y]+=ookisa[x];
            ookisa[x]=0;
        }
        else {
            par[y] = x;
            ookisa[x]+=ookisa[y];
            ookisa[y]=0;
            if (rankmy[x] == rankmy[y]) {
                rankmy[x]++;
            }
        }
    }
    int size(int i){
        i=find(i);
        return ookisa[i];
    }
    bool same(int x, int y){
        return find(x) == find(y);
    }
    
};

//Union-Find-End

int perm[1000005];
void init_perm() {
    perm[0] = 1;
    REP(i, 1000000) {
        perm[i] = perm[i - 1] * i % mod;
    }
}

int nCk(int x, int y) {
    return perm[x] * modpow(perm[x - y], mod - 2) % mod * modpow(perm[y], mod - 2) % mod;
}

double kyori(pair<int, int> f, pair<int, int> s) {
    double ans = 0;
    double t = fabs(f.first - s.first);
    double y = fabs(f.second - s.second);
    ans = sqrt(t * t + y * y);
    return ans;
}

inline string stringmax(string& x,string& y){
    if (x.size()>y.size()) {
        return x;
    }
    if (x.size()<y.size()) {
        return y;
    }
    rep(i,x.size()){
        if (x[i]>y[i]) {
            return x;
        }
        if (x[i]<y[i]) {
            return y;
        }
    }
    return x;
}

#define endl "\n" //interactive の時に注意！！！



int n,m,ans;

signed main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cin>>n>>m;
    for (int i=1; i*i<=m; i++) {
        if(!(m%i)){
            if (i>=n) {
                chmax(ans, m/i);
            }
            if (m/i>=n) {
                chmax(ans, i);
            }
        }
    }
    cout<<ans<<endl;
}








Measured memory_bytes: 256