Problem:
Bamboo Blossoms

The bamboos live for decades, and at the end of their lives,
they flower to make their seeds. Dr. ACM, a biologist, was fascinated
by the bamboos in blossom in his travel to Tsukuba. He liked
the flower so much that he was tempted to make a garden where
the bamboos bloom annually. Dr. ACM started research of
improving breed of the bamboos, and finally, he established
a method to develop bamboo breeds with controlled lifetimes.
With this method, he can develop bamboo breeds that flower
after arbitrarily specified years.

Let us call bamboos that flower k years after sowing
"k-year-bamboos."
k years after being sowed, k-year-bamboos make
their seeds and then die,
hence their next generation flowers after another k years.
In this way, if he sows seeds of k-year-bamboos, he can
see bamboo blossoms every k years. For example,
assuming that he sows seeds of 15-year-bamboos,
he can see bamboo blossoms every 15 years;
15 years, 30 years, 45 years, and so on, after sowing.

Dr. ACM asked you for designing his garden. His garden is partitioned
into blocks, in each of which only a single breed of bamboo can grow.
Dr. ACM requested you to decide which breeds of bamboos
should he sow in the blocks in order to see bamboo blossoms
in at least one block for as many years as possible.

You immediately suggested to sow seeds of one-year-bamboos in all blocks.
Dr. ACM, however, said that it was difficult to develop a bamboo breed
with short lifetime, and would like a plan using only those breeds with
long lifetimes. He also said that, although he could wait for some years
until he would see the first bloom, he would like to see it in
every following year.
Then, you suggested a plan
to sow seeds of 10-year-bamboos, for example, in different blocks each year,
that is, to sow in a block this year and in another block next year, and so on,
for 10 years. Following this plan, he could see
bamboo blossoms in one block every year except for the first 10 years.
Dr. ACM objected again saying he had determined to sow in all
blocks this year.

After all, you made up your mind to make a sowing plan where the bamboos
bloom in at least one block for as many consecutive years as possible
after the first m years (including this year)
under the following conditions:

the plan should use only those bamboo breeds whose
lifetimes are m years or longer, and

Dr. ACM should sow the seeds in all the blocks only this year.

Input

The input consists of at most 50 datasets, each in the following format.

m n

An integer m (2 ≤ m ≤ 100) represents the lifetime
(in years)
of the bamboos with the shortest lifetime that Dr. ACM can use for
gardening.
An integer n (1 ≤ n ≤ 500,000) represents the number of blocks.

The end of the input is indicated by a line containing two zeros.

Output

No matter how good your plan is, a "dull-year" would
eventually come, in which the bamboos do not flower in any block.
For each dataset, output in a line an integer meaning how many
years from now the first dull-year comes after the first m years.

Note that the input of m = 2 and n = 500,000
(the last dataset of the Sample Input) gives the largest answer.

Sample Input

3 1
3 4
10 20
100 50
2 500000
0 0

Output for the Sample Input

4
11
47
150
7368791

Solution in Rust (judge verdict: Accepted)

pub struct Scanner<R> {
    reader: R,
}

impl<R> Scanner<R> {
    pub fn new(reader: R) -> Scanner<R> {
        Scanner { reader }
    }
}

fn is_whitespace(b: u8) -> bool {
    b == b' ' || b == b'\n' || b == b'\r' || b == b'\t'
}

impl<R: std::io::Read> Scanner<R> {
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        let buf = std::io::Read::bytes(self.reader.by_ref())
            .map(|b| b.expect("Read failed"))
            .skip_while(|&b| is_whitespace(b))
            .take_while(|&b| !is_whitespace(b))
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error")
    }

    pub fn read_vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }

    pub fn read_chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}

fn main() {
    let stdin = std::io::stdin();
    let mut sc = Scanner::new(stdin.lock());
    loop {
        let m: usize = sc.read();
        let n: usize = sc.read();
        if m == 0 {
            break;
        }
        let max = 7368791 + 1;
        let mut used = vec![false; max];
        let mut count = 0;
        for i in m..usize::max_value() {
            if !used[i] {
                count += 1;
                if count > n {
                    println!("{}", i);
                    break;
                }
                for k in 1..usize::max_value() {
                    let j = i * k;
                    if j >= max {
                        break;
                    }
                    used[j] = true;
                }
            }
        }
    }
}