// We have some coin denominations and unlimited supply of each.
// Goal: find the k-th smallest sum we can make.
// e.g. coins = {3, 5} -> makeable sums are 3, 5, 6, 8, 9, 10, 11, ...
// so k=4 gives 8.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
long long k;
cin >> n >> k;
vector<long long> coins(n);
for (int i = 0; i < n; i++) cin >> coins[i];
// Key idea: if we can already make some sum S,
// then we can also make S + smallest, S + 2*smallest, etc
// by just adding more of the smallest coin.
// So sums naturally fall into groups based on their remainder
// when divided by smallest. Within each group we only care
// about the first (smallest) sum we can make — the rest follow on its own.
long long smallest = *min_element(coins.begin(), coins.end());
// This whole approach is O(smallest) in memory and time,
// so smallest needs to be reasonably small. Also needs to fit in an int
// since we use it as array size and loop bound.
if (smallest > 2'000'000) {
// too large for the residue graph approach - bail out
// (remove this check if the problem doesn't allow early exit)
assert(false);
}
int M = (int)smallest;
// For each remainder group, find the smallest sum we can make in it.
// We model this as a shortest path problem:
// - each remainder (0 to M-1) is a node
// - adding a coin takes us from one remainder to another
// - we want to reach each remainder with the least total value
// minSum[r] = smallest sum we can make that gives remainder r
vector<long long> minSum(M, LLONG_MAX);
minSum[0] = 0; // sum of 0 has remainder 0, that's our starting point
using Entry = pair<long long, int>;
priority_queue<Entry, vector<Entry>, greater<Entry>> heap; // min-heap
heap.push({0, 0});
while (!heap.empty()) {
auto [curSum, rem] = heap.top();
heap.pop();
// we already found a better sum for this remainder before, skip
if (curSum != minSum[rem]) continue;
// try adding one of each coin and see if it improves any remainder
for (long long coin : coins) {
// reduce coin mod M first — coin could be way bigger than M
int newRem = (rem + (int)(coin % M)) % M;
// use __int128 for the addition — curSum + coin could overflow long long.
// only skip if it actually overflows; don't cut at some arbitrary threshold
// because the real answer might legitimately be that large.
__int128 newSum128 = (__int128)curSum + coin;
if (newSum128 > LLONG_MAX) continue;
long long newSum = (long long)newSum128;
if (newSum < minSum[newRem]) {
minSum[newRem] = newSum;
heap.push({newSum, newRem});
}
}
}
// Now we can quickly count how many sums are makeable up to any limit.
// For remainder r, the makeable sums are minSum[r], minSum[r]+smallest, minSum[r]+2*smallest, ...
// so the count up to limit is simply (limit - minSum[r]) / smallest + 1.
// We add that up for all remainders and subtract 1 to ignore the empty sum (0).
// Using __int128 because the count can get really large when k is big.
auto countUpTo = [&](long long limit) -> __int128 {
__int128 total = 0;
for (int r = 0; r < M; r++) {
if (minSum[r] != LLONG_MAX && minSum[r] <= limit) {
total += 1 + (limit - minSum[r]) / smallest;
}
}
// minSum[0] is 0, so we counted the empty sum in there — remove it
if (limit >= 0) total -= 1;
return total;
};
// Binary search for the answer.
// We need the smallest value where countUpTo reaches k.
// First figure out a safe upper bound by doubling, then narrow it down.
long long lo = 1;
long long hi = smallest;
while (countUpTo(hi) < (__int128)k) {
if (hi > LLONG_MAX / 2) {
hi = LLONG_MAX;
break;
}
hi *= 2; // keep going until we've gone past the k-th sum
}
long long ans = hi;
while (lo <= hi) {
long long mid = lo + (hi - lo) / 2;
if (countUpTo(mid) >= (__int128)k) {
ans = mid;
hi = mid - 1; // mid works, but let's see if something smaller works too
} else {
lo = mid + 1; // haven't reached k sums yet, go higher
}
}
cout << ans << "\n";
return 0;
}