/*
* Problem :: 1654 / 랜선 자르기
*
* Kind :: Binary Search
*
* Insight
* - 전형적인 이분탐색 문제다
* + 자르는 랜선의 길이가 길어질수록 개수는 적어지고
* 자르는 랜선의 길이가 짧아질수록 개수는 많아진다
* # 단조감수함수, 한 번 탐색할 때마다 탐색범위를 반으로 줄일 수 있다
* -> 이분탐색으로 풀자
*
* Point
* - 자르는 랜선의 길이가 될 수 있는 최댓값은
* 주어진 랜선들의 길이중 최댓값이다
* + 10, 100, 1000 이 주어졌을 때, 3개를 만들어야 한다면
* 자르는 랜선의 길이를 333 으로 해서 1000 짜리에서 3개를 만들어내면 된다
* 굳이 주어진 랜선들을 모두 잘라서 활용할 필요는 없다
* + 주어진 랜선들의 길이중 최댓값보다 큰 길이로 랜선들을 잘랐을 때
* 만들어지는 랜선의 개수는 0개다
*
* - max(랜선의 길이)가 max(int) 이므로
* 이분탐색에서 중간을 구할 때 Overflow 가 일어날 수 있다
* + long 으로 바꾸어주자
* + 혹은, (l+r)/2 가 아닌 l/2+r/2 로 하여 Overflow 를 피할 수 있다
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <algorithm>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int K, N;
cin >> K >> N;
int L[K];
for (int i=0; i<K; i++) {
cin >> L[i];
}
// Process
long l = 1; /* 자르는 랜선의 길이가 될 수 있는 최솟값 */
long r = *max_element(L, L+K); /* 자르는 랜선의 길이가 될 수 있는 최댓값 */
long ans = -1;
while (l <= r) {
long m = (l + r) / 2;
long cnt = 0;
/* 자르는 랜선의 길이가 m 일 때, 만들어진 랜선의 개수 cnt */
for (int len : L) {
cnt += len / m;
}
if (cnt >= N) { /* 만들어진 랜선의 개수가 N 이상이면 */
ans = m; /* 현재 자른 길이 m 을 답으로 갱신 */
l = m+1; /* 현재 자른 랜선의 길이보다 작거나 같은 길이는 탐색하지 않아도 됨 */
} else { /* 만들어진 랜선의 개수가 N 미만이면 */
r = m-1; /* 현재 자른 랜선의 길이보다 크거나 같은 길이는 탐색하지 않아도 됨 */
}
}
// Control : Output
cout << ans << endl;
}
// Helper Functions
/* None */