1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <cstdio>
#include <vector>
#include <algorithm>
#include <functional>

std::vector<int> primes;
long long int currentBest = 1;

long long int minModulo(long long int n)
{
	long long int modulo = 100LL;
	for (int p : primes) {
		if (n % p < modulo) {
			modulo = n % p;
		}
	}
	return modulo;
}

long long int findFirstBestRec(long long int n) {
	long long int current = 1LL;
	for (int p : primes) {
		while (n % p == 0) {
			current *= p;
			n /= p;
		}
	}
	if (n > primes[0]) {
		n -= minModulo(n);
		current *= findFirstBestRec(n);
	}
	return current;
}

void initCurrentBest(long long int n)
{
	long long int localBest;
	for (int i = 0; i < 1000; ++i) {
		n -= minModulo(n);
		localBest = findFirstBestRec(n);
		if (localBest > currentBest) {
			currentBest = localBest;
			if (currentBest >= n) {
				break;
			}
		}
		n--;
	}
}

long long int getBiggest(long long int n, unsigned int idx, long long int multiplier) {
	if (n == 0) {
		return 0;
	}
	if (n < primes[primes.size()-1]) {
		if (multiplier > currentBest) {
			currentBest = multiplier;
		}
		return 1;
	}
	if (n * multiplier < currentBest) {
		// no sense to continue
		return 1;
	}

	long long int best = 1;
	long long int current;

	for (int i = idx; i < primes.size(); ++i) {
		if ((n % primes[i]) == 0) {
			current = getBiggest(n / primes[i], i, multiplier * primes[i]) * primes[i];
			if (current > best) {
				best = current;
				if (best == n) {
					break;
				}
			}
		}
	}
	for (int i = idx; i < primes.size(); ++i) {
		if ((n / primes[i]) * primes[i] > best) {
			current = getBiggest(n / primes[i], i, multiplier * primes[i]) * primes[i];
			if (current > best) {
				best = current;
				if (best == n) {
					break;
				}
			}
		}
	}

	if (multiplier * best > currentBest) {
		currentBest = multiplier * best;
	}
	return best;
}

int main()
{
	int k, p;
	long long int n;

	scanf("%d %lld", &k, &n);
	for (int i = 0; i < k; ++i) {
		scanf("%d", &p);
		primes.push_back(p);
	}

	std::sort(primes.begin(), primes.end(), std::greater<int>());
	initCurrentBest(n);
	printf("%lld\n", getBiggest(n, 0, 1));
	return 0;
}