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 static System.Console;
using static System.Int32;
using static System.Math;
using System.Numerics;

class Program
{
    static void Main(string[] args)
    {
        label:
        var sp = ReadLine().Split();
        int n = Parse(sp[0]);
        int m = Parse(sp[1]);
        int max = m / n;
        WriteLine(Yakusuu(m).Where(i => i <= max).Max());
        //goto label;
    }

    static List<int> Yakusuu(int num)
    {
        if (num == 1) return new List<int>() { 1 };
        int sq = (int)Ceiling(Sqrt(num));
        int sqsq = (int)Ceiling(Sqrt(sq));
        var gousei = new bool[sq + 1];
        for(int i = 2; i <= sqsq; ++i)
        {
            if (gousei[i]) continue;
            for(int j = i * 2; j < gousei.Length; j += i)
            {
                gousei[j] = true;
            }
        }
        var insuu = new List<List<int>>();
        for(int i = 2; i < gousei.Length; ++i)
        {
            if (!gousei[i])
            {
                if (num % i == 0)
                {
                    var list = new List<int>() { 1, i };
                    insuu.Add(list);
                    int j = i * i;
                    for(; num % j == 0; j *= i)
                    {
                        list.Add(j);
                    }
                    num /= (j / i);
                }
                if (num < i) break;
            }
        }
        if (1 < num)
        {
            insuu.Add(new List<int>() { 1, num });
        }
        var result = Get(insuu, 0).ToList();
        return result;
    }
    static IEnumerable<int> Get(List<List<int>> lislis, int i)
    {
        foreach (int n in lislis[i])
        {
            if (i == lislis.Count - 1)
            {
                yield return n;
            }
            else
            {
                foreach (var next in Get(lislis, i + 1))
                {
                    yield return n * next;
                }
            }
        }
    }
}