Problem:
Score : 400 points

Problem Statement

You are given integers N and M.

Consider a sequence a of length N consisting of positive integers such that a_1 + a_2 + ... + a_N = M. Find the maximum possible value of the greatest common divisor of a_1, a_2, ..., a_N.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

N \leq M \leq 10^9

Input

Input is given from Standard Input in the following format:

N M

Output

Print the maximum possible value of the greatest common divisor of a sequence a_1, a_2, ..., a_N that satisfies the condition.

Sample Input 1

3 14

Sample Output 1

2

Consider the sequence (a_1, a_2, a_3) = (2, 4, 8). Their greatest common divisor is 2, and this is the maximum value.

Sample Input 2

10 123

Sample Output 2

3

Sample Input 3

100000 1000000000

Sample Output 3

10000

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using static System.Console;
using static PB10004.Algorithm.Util;

namespace PB10004.Algorithm
{
    class Template
    {
        static void Main(string[] args)
        {
            new D().Solve();
        }
    }
    class A
    {
        public void Solve()
        {
            var N = ReadInt();
            if(N == 1)
            {
                WriteLine("Hello World");
            }
            else
            {
                WriteLine(ReadInt() + ReadInt());
            }
        }
    }
    class B
    {
        public void Solve()
        {
            var array = ReadIntArray();
            var N = array[0];
            var T = array[1];
            var min = 9999999;
            var minT = 9999999;
            for (int i = 0; i < N; i++)
            {
                var line = ReadIntArray();
                var c = line[0];
                var t = line[1];
                if(t <= T)
                {
                    min = Math.Min(c, min);
                    minT = Math.Min(t, minT);
                }
            }
            if (minT > T)
                WriteLine("TLE");
            else
                WriteLine(min);
        }
    }
    class C
    {
        List<Point> points = new List<Point>();
        List<Point> tmp = new List<Point>();
        public void Solve()
        {
            var N = ReadInt();
            for (int i = 0; i < N; i++)
            {
                var array = ReadLongArray();
                var p = new Point(array[0], array[1], array[2]);
                if(array[2] > 0)
                    points.Add(p);
                tmp.Add(p);
            }
            if (points.Count == 0)
                points.AddRange(tmp);
            for (int i = 0; i <= 100; i++)
            {
                for (int j = 0; j <= 100; j++)
                {
                    long temp = -1;
                    bool isSuccess = true;
                    foreach (var item in points)
                    {
                        var H = Math.Abs(i - item.X) + Math.Abs(j - item.Y) + item.H;
                        if (temp == -1) temp = H;
                        else
                        {
                            if (temp != H)
                            {
                                if (item.H == 0 && temp - Math.Abs(i - item.X) - Math.Abs(j - item.Y) < 0)
                                    temp = temp;
                                else
                                    isSuccess = false;
                            }
                        }
                    }
                    if (isSuccess)
                    {
                        WriteLine("{0} {1} {2}", i, j, temp);
                        return;
                    }
                }
            }
        }
    }
    struct Point
    {
        public Point(long x, long y, long h)
        {
            X = x;
            Y = y;
            H = h;
        }
        public long X,Y,H;
    }
    class D
    {
        public void Solve()
        {
            var array = ReadLongArray();
            var N = array[0];
            var M = array[1];
            long tmp = 1;
            if(N == 1)
            {
                WriteLine(M);
                return;
            }
            List<long> next = new List<long>();
            for (long i = 1; i <= Math.Sqrt(M); i++)
            {
                if(M % i == 0)
                {
                    var div = M / i;
                    next.Add(div);
                    if(div >= N)
                    {
                        tmp = i;
                    }
                    else
                    {
                        WriteLine(tmp);
                        return;
                    }
                }
            }
            foreach (var item in next.Reverse<long>())
            {
                var div = M / item;
                next.Add(div);
                if (div >= N)
                {
                    tmp = item;
                }
                else
                {
                    WriteLine(tmp);
                    return;
                }
            }
        }
    }
    public static class Util
    {
        /// <summary>
        /// 標準入力をint型にパースする
        /// </summary>
        /// <returns></returns>
        public static int ReadInt()
        {
            return int.Parse(ReadLine());
        }
        /// <summary>
        /// 標準入力をint型の配列にする
        /// </summary>
        /// <returns></returns>
        public static int[] ReadIntArray()
        {
            return ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
        }
        /// <summary>
        /// 標準入力をlong型にパースする
        /// </summary>
        /// <returns></returns>
        public static long ReadLong()
        {
            return long.Parse(ReadLine());
        }
        /// <summary>
        /// 標準入力をlong型の配列にする
        /// </summary>
        /// <returns></returns>
        public static long[] ReadLongArray()
        {
            return ReadLine().Split(' ').Select(long.Parse).ToArray();
        }
        /// <summary>
        /// 一定値の数列を生成する
        /// </summary>
        /// <param name="value"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static IEnumerable<long> ConstSeq(long value, long length)
        {
            for (int i = 0; i < length; i++)
            {
                yield return value;
            }
        }
        /// <summary>
        /// int配列の累積和を求める
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static IEnumerable<int> CumulativeSum(IEnumerable<int> array)
        {
            int tmp = 0;
            foreach (var num in array)
                yield return tmp += num;
        }
        /// <summary>
        /// long配列の累積和を求める
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static IEnumerable<long> CumulativeSum(IEnumerable<long> array)
        {
            long tmp = 0;
            yield return tmp;
            foreach (var num in array)
                yield return tmp += num;
        }
        /// <summary>
        /// 最大公約数をユークリッドの互除法で求める
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static long Gcd(long a, long b)
        {
            return b == 0 ? a : Gcd(b, a % b);
        }
        /// <summary>
        /// 最小公倍数を求める
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static long Lcm(long a, long b)
        {
            return a * b / Gcd(a, b);
        }
    }
}