#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <time.h>
#define sf scanf
#define pf printf
#define lf double
#define ll long long
#define p123 printf("123\n");
#define pn printf("\n");
#define pk printf(" ");
#define p(n) printf("%d",n);
#define pln(n) printf("%d\n",n);
#define s(n) scanf("%d",&n);
#define ss(n) scanf("%s",n);
#define ps(n) printf("%s",n);
#define sld(n) scanf("%lld",&n);
#define pld(n) printf("%lld",n);
#define slf(n) scanf("%lf",&n);
#define plf(n) printf("%lf",n);
#define sc(n) scanf("%c",&n);
#define pc(n) printf("%c",n);
#define gc getchar();
#define re(n,a) memset(n,a,sizeof(n));
#define len(a) strlen(a)
#define LL long long
using namespace std;

int main() {
    ll n = 0ll,m = 0ll;
    sld(n); sld(m)
    ll maxn = 0ll;
    if(m % n == 0ll){
        ll x = m / n;
        ll mini = min(x,n);
        ll maxi = max(x,n);
        if(mini >= n){
            if(maxi > maxn){
                maxn = maxi;
            }
        }else if(maxi >= n && n > mini){
            if(mini > maxn){
                maxn = mini;
            }
        }
        pld(maxn); pn
    }else{
        for(ll i = (ll)(sqrt(m)); i >= 1ll;  i -- ){
            if(m % i == 0ll){
                ll x = m / i;
                ll mini = min(x,i);
                ll maxi = max(x,i);
                if(mini >= n){
                    if(maxi > maxn){
                        maxn = maxi;
                    }
                }else if(maxi >= n && n > mini){
                    if(mini > maxn){
                        maxn = mini;
                    }
                }
            }
        }
        pld(maxn) pn
    }
    /*for(int i = 0; i < n; i ++){
        s(a[i].c) s(a[i].t)
    }*/
    return 0;
}




//2.7.1 分解质因素求欧拉函数
/*
long long factor[100][2];
int fatCnt;
int getFactors(long long x) {
fatCnt=0;
long long tmp=x;
for(int i=1; prime[i]<=tmp/prime[i]; i++) {
factor[fatCnt][1]=0;
if(tmp%prime[i]==0) {
factor[fatCnt][0]=prime[i];
while(tmp%prime[i]==0) {
factor[fatCnt][1]++;
tmp/=prime[i];
}
fatCnt++;
}
}
if(tmp!=1) {
factor[fatCnt][0]=tmp;
factor[fatCnt++][1]=1;
}
return fatCnt;
}

getFactors(n);
int ret = n;
for(int i = 0; i < fatCnt; i++) {
ret = ret/factor[i][0]*(factor[i][0]−1);
}
*/

/*
int x[1000];









int main() {
ll a,b,n;
x[1] = 1;
x[2] = 1;
while(~scanf("%lld%lld%lld",&a,&b,&n) && (a || b || n)) {
a %= 7;
b %= 7;
int T = 0;
x[3] = (a*x[2]+b*x[1])%7;
x[4] = (a*x[3]+b*x[2])%7;
for(int i = 5; i < 1000; i ++) {
x[i] = (a*x[i-1]+b*x[i-2])%7;
if(x[i] == x[4] && x[i-1] == x[3]) {
T = i-4;
break;
}
}


if(n == 1 || n == 2) {
p(1) pn
} else if(n % T == 1) {
p(x[n%T+T-1]) pn
} else if(n % T == 2) {
p(x[n%T+T-2]) pn
} else if(n % T == 0) {
p(x[n%T+T]) pn
} else {
p(x[n%T]) pn
}
}
return 0;
}










/*struct A{
int x,y;
}a[160000];
int is[150000];
int group[150000];
bool cmp(A a,A b){
if(a.x < b.x)return true;
if(a.x == b.x && a.y < b.y) return true;
return false;
}
int main(){
int n,m;
s(n) s(m)
re(is,0);
re(group,0);
int x,y;
for(int i = 0;i < m; i ++){
s(a[i].x) s(a[i].y)
if(a[i].x > a[i].y){
int temp = a[i].x;
a[i].x = a[i].y;
a[i].y = temp;
}
is[a[i].x] ++;
is[a[i].y] ++;
}
sort(a,a+m,cmp);
for(int i = 0; i < n; i ++){
if(is[i] <= 1){
group[i] = 1;
}
}
re(is,0);
int sta = 0;
for(int i = 0; i < m; i ++){
if(group[a[i].x] == 0 && group[a[i].y] == 0){
group[a[i].x] = 1;
group[a[i].y] = 2;
is[a[i].x] ++;
is[a[i].y] ++;
}else if(group[a[i].x] == 1 && group[a[i].y] == 0){
group[a[i].y] = 2;
is[a[i].y] ++;
}else if(group[a[i].x] == 2 && group[a[i].y] == 0){
group[a[i].y] = 1;
is[a[i].y] ++;
}else if(group[a[i].x] == 1 && group[a[i].y] == 1){
is[a[i].x] ++;
is[a[i].y] ++;
}else if(group[a[i].x] == 2 && group[a[i].y] == 2){
is[a[i].x] ++;
is[a[i].y] ++;
}
if(is[a[i].x] >= 2 || is[a[i].y] >= 2){
sta = 1;
goto l;
}
}
l:0;
if(sta == 0){
p(group[0])
for(int i = 1; i < n; i ++){
pk p(group[i]);
}
pn
}else if(sta == 1){
puts("-1");
}
return 0;
}
*/




/*
struct A {
int last = 0;
int data = 0;
int next = 0;
} a[100500];
int main() {
int address = 0,N = 0,K = 0;
s(address) s(N) s(K)
int x = 0;
for(int i = 0; i < N; i ++) {
s(x) s(a[x].data) s(a[x].next)
a[x].last = x;
}
A b[100500];
for(int i = 0; i < N; i ++) {
b[i] = a[address];
address = a[address].next;
}
int xx = N / K;
int xxx = N % K;
A c[100500];
int num = 0;
for(int i = 0; i < xx; i ++) {
for(int j = (K-1)*(i+1); j >= (K-1)*i; j --) {
if(j == (K-1)*i) {
c[num].last = b[j].last;
c[num].data =  b[j].data;
c[num].next =  b[(K-1)*(i+1)].next;
num ++;
} else {
c[num].last = b[j].last;
c[num].data =  b[j].data;
c[num].next =  b[j-1].next;
num ++;
}
}
}

for(int i =0; i < N; i ++){
pf("%05d %d %d\n",b[i].last,b[i].data,b[i].next);
}
/*for(int i = (K-1)*(xx)+1; i <= (K-1)*(xx)+xxx; i ++) {
if(b[i].next == -1) {
pf("%05d %d %d\n",b[i].last,b[i].data,b[i].next);
return 0;
}
pf("%05d %d %05d\n\n",b[i].last,b[i].data,b[i].next);
}*/
/*
return 0;
}
*/

/*
* 素数筛选，存在小于等于MAXN 的素数
* prime[0] 存的是素数的个数
*/
/*
const ll MAXN=70000;
ll prime[MAXN+1];
void getPrime() {
memset(prime,0,sizeof(prime));
for(ll i=2; i<=MAXN; i++) {
if(!prime[i])
prime[++prime[0]]=i;
for(ll j=1; j<=prime[0]&&prime[j]<=MAXN/i; j++) {
prime[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
}
}

ll x[1050000];
int main() {
getPrime();
//p(prime[0]); pn
ll a,b;
ll a1,a2,b1,b2,mini,maxi;
while(~sf("%lld%lld",&a,&b)) {
re(x,0);
for(ll i = a; i <= b; i ++) {
for(ll j = 1; j <= 6935; j ++) {
if(i % j == 0) {
x[i-a] = 1;
}
}
}
int count0 = 0;
int sta = 0;
int xx = 0;
for(int i = 0; i <= b-a; i ++) {
if(x[i] == 0) {
count0 ++;
}
if(x[i] == 0 && sta == 0) {
sta = 1;
xx = i+a;
}
if(x[i] == 0 && sta == 1) {
sta = 2;
mini = i+a-xx;
maxi = i+a-xx;
a1 = xx;
a2 = xx;
b1 = i+a;
b2 = i+a;
}
}
p(b1)  pk p(b2) pn
if(count0 == 0) {
puts("There are no adjacent primes.");
} else {

}
}
return 0;
}

*/


Measured memory_bytes: 256