# -*- coding: utf-8 -*-

from collections import defaultdict

from bisect import bisect

def inpl(): return list(map(int, input().split()))



def primes(N):

    sieve = [True]*(N+1)

    sieve[:2] = [False, False]

    for i in range(4, N+1, 2):

        sieve[i] = False



    for i in range(3, N+1, 2):

        if sieve:

            for j in range(2*i, N+1, i):

                sieve[j] = False

    P = []

    for i in range(N+1):

        if sieve[i]:

            P.append(i)

    return P



N, M = inpl()

P = primes(10**6)

searched = defaultdict(int)



Q = [1]



if N==1:

    print(M)

    exit()



if M%N == 0:

    ans = M//N

else:

    ans = 1

while Q:

    a = Q.pop()

    for p in P:

        c = a*p

        d = M - c*N

        if d < 0:

            break

        

        if d%c == 0:

            if not searched[c]:

                searched[c] = True

                ans = max(ans, c)

                Q.append(c)

print(ans)
# -*- coding: utf-8 -*-

from math import sqrt, ceil

def inpl(): return list(map(int, input().split()))



N, M = inpl()

ans = 1

for i in range(1, ceil(sqrt(M))+1):

    if M%i != 0:

        continue

    d = M // i

    if M >= N*i:

        ans = max(i, ans)

    if M >= N*d:

        ans = max(d, ans)



print(ans)
# -*- coding: utf-8 -*-
from collections import defaultdict
from bisect import bisect


def inpl():
    return list(map(int, input().split()))


def primes(N):
    sieve = [True] * (N + 1)
    sieve[:2] = [False, False]
    for i in range(4, N + 1, 2):
        sieve[i] = False
    for i in range(3, N + 1, 2):
        if sieve:
            for j in range(2 * i, N + 1, i):
                sieve[j] = False
    P = []
    for i in range(N + 1):
        if sieve[i]:
            P.append(i)
    return P


N, M = inpl()
P = primes(10**6)
searched = defaultdict(int)
Q = [1]
if N == 1:
    print(M)
    exit()
if M % N == 0:
    ans = M // N
else:
    ans = 1
while Q:
    a = Q.pop()
    for p in P:
        c = a * p
        d = M - c * N
        if d < 0:
            break
        if d % c == 0:
            if not searched[c]:
                searched[c] = True
                ans = max(ans, c)
                Q.append(c)
print(ans)

# -*- coding: utf-8 -*-
from math import sqrt, ceil


def inpl():
    return list(map(int, input().split()))


N, M = inpl()
ans = 1
for i in range(1, ceil(sqrt(M)) + 1):
    if M % i != 0:
        continue
    d = M // i
    if M >= N * i:
        ans = max(i, ans)
    if M >= N * d:
        ans = max(d, ans)
print(ans)

-from collections import defaultdict -from bisect import bisect +from math import sqrt, ceil -def primes(N): -    sieve = [True] * (N + 1) -    sieve[:2] = [False, False] -    for i in range(4, N + 1, 2): -        sieve[i] = False -    for i in range(3, N + 1, 2): -        if sieve: -            for j in range(2 * i, N + 1, i): -                sieve[j] = False -    P = [] -    for i in range(N + 1): -        if sieve[i]: -            P.append(i) -    return P - - -P = primes(10**6) -searched = defaultdict(int) -Q = [1] -if N == 1: -    print(M) -    exit() -if M % N == 0: -    ans = M // N -else: -    ans = 1 -while Q: -    a = Q.pop() -    for p in P: -        c = a * p -        d = M - c * N -        if d < 0: -            break -        if d % c == 0: -            if not searched[c]: -                searched[c] = True -                ans = max(ans, c) -                Q.append(c) +ans = 1 +for i in range(1, ceil(sqrt(M)) + 1): +    if M % i != 0: +        continue +    d = M // i +    if M >= N * i: +        ans = max(i, ans) +    if M >= N * d: +        ans = max(d, ans)