CodeEff/ECCO huggingface dataset:
# Original solution

N, M = list(map(int, input().split()))

ans = 1
for n in range(1, M // N + 1):
    res = M - n * N
    if res % n == 0:
        ans = n

print(ans)


# Optimized solution

N, M = list(map(int, input().split()))

if M % N == 0:
    print((M // N))
else:
    ans = 1
    for n in range(1, M // N + 1):
        res = M - n * N
        if res % n == 0:
            ans = n

    print(ans)
# Original solution
def make_divisors(n):
    divisors = []
    for i in range(1, int(n ** 0.5) + 1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n // i)
    # divisors.sort()
    return divisors

a,b = list(map(int, input().split()))
l = make_divisors(b)
l.sort(reverse=False)
res = 1
#print(l)
for x in l:
    if x <= b//a:
        res = max(x, res)
print(res)


# Optimized solution
# 約数のリストを得る
def make_divisors(n):
    divisors = []
    for i in range(1, int(n ** 0.5) + 1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n // i)
    return divisors

N, M = list(map(int, input().split()))
l = make_divisors(M)
# mの約数
res = 1
# 全ての約数において、kと仮定する
for k in l:
    x = M // k
    # この際、Mをkで除した数列bがN以上であるかを判定する
    if x >= N:
        res = max(res, k)
print(res)
# Original solution
N, M = list(map(int, input().split()))

ans = 1
for g in range(1, int(M ** 0.5) + 1):
    if M % g == 0 and M / g >= N:
        ans = max(ans, g)
    
    if M % g == 0:
        g2 = M // g
        if M % g2 == 0 and M / g2 >= N:
            ans = max(ans, g2)
print(ans)


# Optimized solution
N, M = list(map(int, input().split()))

ans = 0
for x in range(1, int(M ** 0.5) + 1):
    if M % x != 0:
        continue
    else:
        x1, x2 = x, M // x
        if M // x1 >= N:
            ans = max(ans, x1)
        if M // x2 >= N:
            ans = max(ans, x2)

print(ans)
# Original solution
N, M = list(map(int, input().strip().split()))

maxg = 1
if N == 1:
  maxg = M
else:
  for i in range(2, M//N+1):
    if (M - N*i) % i == 0:
      maxg = i

print(maxg)


# Optimized solution
N, M = list(map(int, input().strip().split()))

i=1
while i <= M//N: 
  if M % i == 0:
    maxg = i
    if M//i <= M//N:
      maxg = M // i
      break
  i += 1

print(maxg)
# Original solution
def is_prime(n):
    if n == 1:
        return False
    for i in range(2,int(n**0.5)+1):
        if n % i == 0:
            return False
    return True

n,m = list(map(int,input().split()))
if (is_prime(m)):
  print((1))
  exit(0)

a = int(m /n)


for i in range(a,0,-1):
  if m % i == 0:
    print(i)
    break

# Optimized solution
n,m = list(map(int,input().split()))

a = int(m /n)
for i in range(a,0,-1):
  if m % i == 0:
    print(i)
    break
# Original solution
n, m = list(map(int, input().split(" ")))
max = 1
for i in range((int)(m/n), 1, -1):
  if m % i == 0:
    max = i
    break
print(max)

# Optimized solution
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort()
    return divisors

n, m = list(map(int, input().split(" ")))
max = 1
#print(make_divisors(m))
for i in make_divisors(m):
  if i > m/n:
    break
  else:
    max = i
print(max)
# Original solution
N,M = list(map(int,input().split()))
l = M//N
if M+1-N < l:
    for i in range(N,M+1):
        if M%i == 0:
            print((M//i))
            break
else:
    for i in range(l,-1,-1):
        if M % i == 0:
            print(i)
            break

# Optimized solution
N,M = list(map(int,input().split()))

m = M
f = {}
while m%2 == 0:
    f[2] = f.get(2,0) + 1
    m = m//2

k = 3
l = int(m**0.5)+1
while m != 1:
    if k > l:
        f[m] = f.get(m,0)+1
        break
    while m%k == 0:
        f[k] = f.get(k,0)+1
        m = m//k
    k += 2
C=[1]
for k in f:
    C_tmp = []
    for c in C:
        for i in range(f[k]):
            C_tmp.append(c*(k**(i+1)))
    C.extend(C_tmp)
ans_r = M
for c in C:
    if c>=N and c<ans_r:
        ans_r = c
print((M//ans_r))
# Original solution
def main():
    n, m = list(map(int, input().split()))
    ans = 1
    v = m / n
    for i in range(2, int(m / n) + 1):
        if m % i == 0:
            ans = max(i, ans)

    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
def main():
    n, m = list(map(int, input().split()))
    for i in range(int(m / n), 0, -1):
        if m % i == 0:
            print(i)
            break


if __name__ == '__main__':
    main()
# Original solution
# a1 + a2 + a3 ... + an = M
# ai の 最大公約数をDとする
# ai = xi * D　のはず。 D * x0 + D * x1 ... + D * xn = M
# まとめて D(x1 + x2 + .... + xn) = M
# 変形し、D = M / (x1 + x2 + .... + xn)
# (x1 + ... xn) = K とすると、Kを最小化するとDが最大化する
# M / K が割り切れる必要があるので、KはMの約数のいずれか
# K >= N。なぜなら xi >= 1 なので、Kは最低でも数字の個数 N になる
# つまり、約数のうちで N 以上の最初の値が K になる
# ex: 3 14
# 14 の約数 {1, 2, 7}
# K >= N なので、　K >= 3
# K = 7 で確定。つまり D = M/K = 2 でAnswer

N, M = list(map(int, input().split()))
for i in range(1, M + 1):
    if M % i == 0 and i >= N:
        print((M // i))
        break


# Optimized solution
# a1 + a2 + a3 ... + an = M
# ai の 最大公約数をDとする
# ai = xi * D　のはず。 D * x0 + D * x1 ... + D * xn = M
# まとめて D(x1 + x2 + .... + xn) = M
# 変形し、D = M / (x1 + x2 + .... + xn)
# (x1 + ... xn) = K とすると、Kを最小化するとDが最大化する
# M / K が割り切れる必要があるので、KはMの約数のいずれか
# K >= N。なぜなら xi >= 1 なので、Kは最低でも数字の個数 N になる
# つまり、約数のうちで N 以上の最初の値が K になる
# ex: 3 14
# 14 の約数 {1, 2, 7}
# K >= N なので、　K >= 3
# K = 7 で確定。つまり D = M/K = 2 でAnswer

N, M = list(map(int, input().split()))
M_ROOT = int(M ** 0.5)
k = M
for i in range(1, M_ROOT + 1):
    if M % i == 0:
        if i >= N:
            print((M // i))
            exit()
        d = M // i
        if d < k and d >= N:
            k = d
print((M // k))
# Original solution
n,m = list(map(int,input().split()))
ans = 1
for i in range(1,int(m**0.5)+1):
    if m%i==0:
        x = m//i
        if x>=n:
            ans = max(ans,i)
        if i>=n:
            ans = max(ans,x)
        
print(ans)


# Optimized solution
n,m = list(map(int,input().split()))
ans = 1
for i in range(1,int(m**0.5)+1):
    if m%i!=0:continue
    if m//i>=n:
        ans = max(i,ans)
    if i>=n:
        ans = max(m//i,ans)

print(ans)
# Original solution
N, M = list(map(int, input().split()))

output = 1
for i in range(M//N, 0, -1):
    if M % i == 0 and output < i:
        output = i
print(output)


# Optimized solution
N, M = list(map(int, input().split()))

output = 1
for i in range(M//N, 0, -1):
    if M % i == 0 and output < i:
        output = i
        break
print(output)
# Original solution

def factorize(n):
    nn = n
    lst = []
    for i in range(2, int(1 + n ** 0.5)):
        k = 0
        while nn % i == 0:
            k += 1
            nn = nn // i
        if k > 0:
            lst.append([i, k])
    if nn != 1:
        lst.append([nn, 1])
    return lst

def gen_divisor(m):
    # not sorted!
    yield 1
    factorized = factorize(m)
    length = len(factorized)
    if length == 0:
        return
    factor_nexps = [0] * length
    while True:
        # increment
        factor_nexps[0] += 1
        for idx in range(length - 1):
            if factor_nexps[idx] > factorized[idx][1]:
                factor_nexps[idx] = 0
                factor_nexps[idx+1] += 1
        if factor_nexps[-1] > factorized[-1][1]:
            return
        divisor = 1
        for i, tup in enumerate(factorized):
            divisor *= tup[0] ** factor_nexps[i]
        yield divisor

N, M = list(map(int, input().split()))

def solve():
    divisors = sorted([di for di in gen_divisor(M) if di >= N])
    ans = M // divisors[0]
    return ans

print((solve()))



# Optimized solution
def gen_divisor(n):
    ps = []
    for i in range(1, int(1 + n ** 0.5)):
        if n % i == 0:
            yield i
            ps.append(n // i)
    if n // ps[-1] == ps[-1]:
        del ps[-1]
    for p in reversed(ps):
        yield p

N, M = list(map(int, input().split()))

def solve():
    for di in gen_divisor(M):
        if di >= N:
            ans = M // di
            return ans

print((solve()))
# Original solution
n, m = list(map(int, input().split()))

count = 1
for i in range(1, (m//n)+1):
    temp = m - (i*n)
    if temp % i == 0:
        count = i
        
print(count)


# Optimized solution
n, m = list(map(int, input().split()))

count = 1
for i in range((m//n), 0, -1):
    if m % i == 0:
        count = i
        break

print(count)
# Original solution
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time, copy
from operator import itemgetter

sys.setrecursionlimit(10**7)
inf = 10**20
mod = 10**9 + 7

stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  # ignore trailing spaces

N, M = na()
MAX = M // N + 1
ans = 1
for i in range(1, MAX):
    res = M - i * N
    if res % i == 0:
        ans = max(ans, i)
print(ans)

# Optimized solution
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time, copy,bisect
from operator import itemgetter

sys.setrecursionlimit(10**7)
inf = 10**20
mod = 10**9 + 7

stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  # ignore trailing spaces

import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time, copy
from operator import itemgetter

sys.setrecursionlimit(10**7)
inf = 10**20
mod = 10**9 + 7

stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  # ignore trailing spaces

N, M = na()
MAX = M // N
ans = 1

def make_divisors(n):
    lower_divisors , upper_divisors = [], []
    i = 1
    while i*i <= n:
        if n % i == 0:
            lower_divisors.append(i)
            if i != n // i:
                upper_divisors.append(n//i)
        i += 1
    return lower_divisors + upper_divisors[::-1]

if M % N == 0:
    print((M // N))
else:
    tmp = make_divisors(M)
    print((tmp[max(bisect.bisect_left(tmp, MAX) - 1, 0)]))
# Original solution
def run():
	N, M = (int(x) for x in input().split())
	i = 2
	result = 1

	while True:
		if M % i == 0 and N * i <= M:
			result = i

		i += 1
		if i * N > M:
			break

	print(result)



if __name__ == '__main__':
	run()

# Optimized solution
def run():
	N, M = (int(x) for x in input().split())
	i = 2
	result = 1

	for i in range(M // N, 0, -1):
		if M % i == 0:
			print(i)
			break



if __name__ == '__main__':
	run()
# Original solution
from math import gcd

def solve():
    n, m = list(map(int, input().split()))
    d = m // n
    p = m % n
    res = max(1, gcd(d, d + p))
    while d > 1:
        d -= 1
        q = m - n * d
        res = max(res, gcd(d, d + q))
    print(res)


solve()

# Optimized solution
from math import gcd

def solve():
    n, m = list(map(int, input().split()))
    d = m // n
    p = m % n
    res = max(1, gcd(d, d + p))
    if p == 0:
        print(res)
        exit()
    while d > res:
        d -= 1
        p += n
        if p % d == 0:
            res = max(res, d)
    print(res)


solve()
# Original solution
N, M = list(map(int, input().split()))
flag = True
for i in range(N, M//3 + 1):
    if M%i == 0:
        print((M//i))
        flag = False
        break
if flag:
    if M%2 == 0 and M//2 >= N:
        print((2))
    else:
        print((1))

# Optimized solution
N, M = list(map(int, input().split()))
# また答えが見つかってなければTrue
flag = True
for i in range(N, M//10 + 1):
    if M%i == 0:
        print((M//i))
        flag = False
        break
for i in range(9):
    if flag and M%(10 - i) == 0 and M//(10 - i) >= N:
        print((10 - i))
        flag = False
if flag:
    print((1))
# Original solution
import math

N, M = list(map(int, input().split()))

if N == 1:
    print(M)
else:
    d = max(d for d in range(1, math.ceil(M / (N - 1))) if M % d == 0)
    print(d)


# Optimized solution
N, M = list(map(int, input().split()))

if N == 1:
    print(M)
else:
    d = max(d for d in range(1, M // N + 1) if M % d == 0)
    print(d)
# Original solution
import math

N, M = list(map(int, input().split()))

def divisors(M):
    for d in range(1, math.floor(math.sqrt(M)) + 1):
        if M % d == 0:
            yield d
            yield M // d

d = max(d for d in divisors(M) if d <= M // N)
print(d)

# Optimized solution
import math

N, M = list(map(int, input().split()))

sqrtM = math.floor(math.sqrt(M))
maxd  = min(sqrtM, M // N)

d1 = max(      d for d in range(1, maxd  + 1) if M % d == 0)
d2 = max((M // d for d in range(N, sqrtM + 1) if M % d == 0), default=1)
print((max(d1, d2)))
# Original solution
n,m = list(map(int,input().split()))
#素因数分解(素因数を並べたリスト)(ex:60→[2,2,3,5])
def factorization(n): 
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            cnt=0
            while temp%i==0:
                cnt+=1
                temp //= i
            for _ in range(cnt):
                arr.append(i)

    if temp!=1:
        arr.append(temp)

    if arr==[]:
        arr.append(n)

    return arr
ls = factorization(m)
fi = []
for k in range(2**len(ls)):
    a = 1
    for l in range(len(ls)):
        if (k>>l)&1:
            a *= ls[l]
    if a not in fi:
        fi.append(a)
di = []
for i in range(len(fi)):
    if m//fi[i] >= n:
        di.append(fi[i])
print((max(di)))

# Optimized solution
n,m = list(map(int,input().split()))
ls = []
for i in range(1,int(m**(1/2))+1):
    if m % i == 0:
        ls.append(i)
        ls.append(m//i)
ls = sorted(list(set(ls)),reverse=True)
for j in ls:
    if j*n <= m:
        print(j)
        break
# Original solution
import itertools
N,M=list(map(int,input().split()))

def factorize(n):
    fct = []  # prime factor
    b, e = 2, 0  # base, exponent
    while b * b <= n:
        while n % b == 0:
            n = n // b
            e = e + 1
        if e > 0:
            fct.append((b, e))
        b, e = b + 1, 0
    if n > 1:
        fct.append((n, 1))
    return fct
def factorize_list(n):
    result = []
    for val,perm in factorize(n):
        result+= [val]*perm
    return result

factorized = factorize_list(M)

def mul(args):
    r =1
    for v in args:
        r*= v
    return r


result=1
for i in range(len(factorized)//2+1):
    for vals in set(itertools.combinations(factorized,i)):
        A= mul(vals)
        B= M//A
        #print(A,B,vals)
        if A>=N:
            result = max(B,result)
        if B>=N:
            result = max(A,result)


print(result)

# Optimized solution
import itertools


def factorize(n):
    fct = []  # prime factor
    b, e = 2, 0  # base, exponent
    while b * b <= n:
        while n % b == 0:
            n = n // b
            e = e + 1
        if e > 0:
            fct.append((b, e))
        b, e = b + 1, 0
    if n > 1:
        fct.append((n, 1))
    return fct
def factorize_list(n):
    result = []
    for val,perm in factorize(n):
        result+= [val]*perm
    return result



def mul(args):
    r =1
    for v in args:
        r*= v
    return r

def getcomb(l):
    if len(l)==0:
        return [1]
    result = []
    v,perm = l[0]
    for i in range(perm+1):
        result+= [(v**i)*val for val in getcomb(l[1:])]
    return result


N,M=list(map(int,input().split()))
factorized = factorize(M)
result=1
for i in range(len(factorized)//2+1):
    for vals in getcomb(factorized):
        A= vals
        B= M//A
        #print(A,B,vals)
        if A>=N:
            result = max(B,result)
        if B>=N:
            result = max(A,result)


print(result)
# Original solution
N, M = list(map(int, input().split()))
s, r = divmod(M, N)
ans = 1
for i in range(1, s+1):
    if M%i == 0:
        ans = i

print(ans)



# Optimized solution
N, M = list(map(int, input().split()))
s, r = divmod(M, N)
ans = 1
for i in range(s, 0, -1):
    if M % i == 0:
        print(i)
        break
# Original solution
import fractions
N, M = list(map(int,input().split()))
MIN = 0
MAX = 10**9
while MAX - MIN > 1:
    MID = (MAX+MIN)//2
    if M/MID > N:
        MIN = MID
    else:
        MAX = MID

for i in range(MAX,0,-1):
    if i == 1:
        print(i)
    else:
        if M % i == 0:
            print(i)
            exit()

# Optimized solution
N,M = list(map(int,input().split()))
MAX = int(M**(1/2))
ans = 0
for i in range(MAX,0,-1):
    if M % i == 0:
        j = M // i
        if j >= N:
            ans = max(ans,i)
        if i >= N:
            ans = max(ans,j)
print(ans)
# Original solution
n, m = list(map(int, input().split()))

num = []
i = 1
while i * i <= m:
    if m % i == 0:
        num.append(i)
        if m // i != i:
            num.append(m//i)
    i += 1

ans = 0
for i in num:
    if i <= m // n:
        ans = max(ans, i)

print(ans)

# Optimized solution
import math
n, m = list(map(int, input().split()))

div = []
sqrt_m = int(math.sqrt(m))
for i in range(1, sqrt_m + 1):
    if m % i == 0:
        div.append(i)
        div.append(m // i)

div.sort(reverse=True)
for i in div:
    if m >= i * n and (m - i * n) % i == 0:
        print(i)
        exit()
# Original solution
n, m = list(map(int, input().split()))
div = m//n
INF = 10**18
ans = -INF
for i in range(1, div+1):
    if m % i != 0:
        continue
    if ans < i:
        ans = i
print(ans)


# Optimized solution
n, m = list(map(int, input().split()))
div = m//n
INF = 10**18
ans = -INF
for i in reversed(list(range(1, div+1))):
    if m % i != 0:
        continue
    if ans < i:
        ans = i
        break
print(ans)
# Original solution
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(str, input().split()))
def ZIP(n): return list(zip(*(MAP() for _ in range(n))))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7
#import numpy as np
from decimal import *
 
# N以上でMを割り切ることができる最小の数nを求める　→ 答え M//n
N, M = MAP()

m = [] #Mの約数を格納
for i in range(1, int(M**0.5)+1):
    if M%i == 0:
        m.append(i)
        if i != M//i:
            m.append(M//i)

m.sort()
n = m[bisect_left(m, N)]

print((M//n))


# Optimized solution
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(str, input().split()))
def ZIP(n): return list(zip(*(MAP() for _ in range(n))))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7
#import numpy as np
from decimal import *
 
# N以上でMを割り切ることができる最小の数nを求める　→ 答え M//n
N, M = MAP()

def make_divisors(n):  #約数列挙
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n%i == 0:
            divisors.append(i)
            if i != n//i:
                divisors.append(n//i)
    divisors.sort()
    return divisors
    

divisors = make_divisors(M)
n = divisors[bisect_left(divisors, N)]
print((M//n))
# Original solution
import itertools

def prime(M):
    lst = []
    i = 2
    while M != 1:
        if M % i == 0:
            lst.append(i)
            M = M // i
        else:
            i += 1
    return lst

def volume(lst):
    res = 1
    for i in lst:
        res *= int(i)
    return res


N, M = list(map(int, input().split()))
lst = prime(M)
res_lst = []
for i in range(len(prime(M)) + 1):
    for j in itertools.combinations(lst, i):
        if not volume(j) in res_lst:
            res_lst.append(volume(j))
res_lst = sorted(res_lst)
res = 1
for num in res_lst:
    if (M // N) < num:
        break
    else:
        res = num

print(res)



# Optimized solution
import math


def prime(M):
    if M == 1:
        return [1]
    lst = []
    for i in range(1, int(math.sqrt(M)+1)):
        if M % i == 0:
            lst.append(i)
            div = M // i
            if div not in lst:
                lst.append(div)
    return sorted(lst)


N, M = list(map(int, input().split()))
lst = prime(M)
res = 1
for num in lst:
    if (M // N) < num:
        break
    else:
        res = num

print(res)
# Original solution
from itertools import combinations

def fact(M):
    ans = []
    while M > 1:
        for i in range(2, M+1):
            if M % i == 0:
                ans.append(i)
                M //=i
                break
    return ans

def solve(N, M):
    ans = [1]
    divs = fact(M)
    cand = set([tuple(Xs)
        for r in range(1, len(divs) + 1)
        for Xs in combinations(divs, r)
    ])
    for Xs in cand:
        X = 1
        for x in Xs:
            X *= x
        if M % X != 0:
            continue
        S = X * N
        if (M - S) >= 0 and (M - S) % X == 0:
            ans.append(X)
    return max(ans)

if __name__ == "__main__":
    l = input().split(" ")
    N, M = int(l[0]), int(l[1])
    print((solve(N, M)))


# Optimized solution

def solve(N, M):
    ans = [1]
    for D in range(2, M//N + 1):
        if M >= N * D and M % D == 0:
            ans.append(D)
    return max(ans)

if __name__ == "__main__":
    l = input().split(" ")
    N, M = int(l[0]), int(l[1])
    print((solve(N, M)))
# Original solution
N, M = list(map(int, input().split()))
ceil = M / N
tmp = 1
mx = 0
while ceil >= tmp:
    if (M - tmp * (N - 1)) % tmp == 0:
        mx = tmp
    tmp += 1

print(mx)


# Optimized solution
N, M = list(map(int, input().split()))
ceil = M // N
for i in range(1,ceil+1)[::-1]:
    tmp = M - i * (N - 1)
    if tmp > 0 and tmp % i == 0:
        print(i)
        break
# Original solution
import math
N, M = list(map(int, input().split()))
mx = 0
for i in range(1, math.floor(math.sqrt(M))+1):
    if M % i == 0 and M // i >= N:
        mx = max(mx, i)
    if M % i == 0 and i >= N:
        mx = max(mx, M//i)
print(mx)

# Optimized solution
import math
N, M = list(map(int, input().split()))
mx = 0
for i in range(1, math.floor(math.sqrt(M))+1):
    if M % i == 0:
        if M // i >= N:
            mx = max(mx, i)
        if i >= N:
            mx = max(mx, M//i)
print(mx)
# Original solution
N, M = list(map(int, input().split()))
mx = 0
for i in range(1, int(M**0.5)+1):
    if M % i == 0:
        if M // i >= N:
            mx = max(mx, i)
        if i >= N:
            mx = max(mx, M//i)
print(mx)


# Optimized solution
def make_divisors(div, n):
    divisors = []
    mx = 0
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if n // i >= div:
                mx = max(mx, i)
            if i != n // i:
                divisors.append(n//i)
                if i >= div:
                    mx = max(mx, n // i)
    return divisors, mx

n,m = list(map(int, input().split()))
divisors, mx = make_divisors(n, m)
print(mx)
# Original solution
N, M = list(map(int, input().split()))
tmp = M // N
ansMax = 0
for i in range(1, tmp + 1):
    ansTmp = M - ((N - 1) * i)
    if ansTmp % i == 0:
        ansMax = i

print(ansMax)

# Optimized solution
N, M = list(map(int, input().split()))
tmp = M // N
ansMax = 0
y = []
for i in range(1, (int(M ** (0.5)) + 1)):
    if M % i == 0:
        y.append(i)
        if i != M // i:
            y.append(M // i)
y.sort()

for i in y:
    if i <= tmp:
        ansMax = i
    else:
        break
print(ansMax)