#include<bits/stdc++.h>
using namespace std;
// PBDS
// #include <ext/pb_ds/assoc_container.hpp> // Common file 
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds; 
// typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_multiset;

#ifndef ONLINE_JUDGE
	#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
	template <typename Arg1>void __f(const char* name, Arg1&& arg1){cerr << name << " : [ " << arg1 <<" ]"<< endl<<flush;}
	template <typename Arg1, typename... Args>void __f(const char* names, Arg1&& arg1, Args&&... args){const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : [ " << arg1 << " ]  "<<flush;__f(comma + 1, args...);}
#else
	#define debug(...) 
#endif

#define ll                      long long 
#define vll                     vector<long long>
#define ld                      long double
#define vpll                    vector<pair<long long, long long >>
#define pll                     pair<long long,long long >
#define all(x)                  x.begin(), x.end()
#define ln                      cout<<"\n";
#define INF                     7000000000000000000
// #define isvowel(a) (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u')

// function def.
void setup(); void sieve(); ll pow(); ll powm(ll x,ll y,ll m); bool isprime(); ll modInverse();

vll prime; //used by sieve
static const ll MOD[2] = {998244353, 1000000007};

void solve(){
	ll n, k ; cin >> n >> k;
	ll ans = 0;
	ll a[n + 1];
	for(ll i = 1 ; i <= n ; i++){
		cin >> a[i];
		ans = max(ans, a[i]);
	}
	ll low = 1, high = ans;
	while(low <= high){
		ll req = 0;
		ll mid = (low + high) >> 1;
		for(ll i = 1 ; i <= n ; i++){
			req += ceil((1.0 * a[i]) / mid) - 1;
		}
		// debug(req,mid);
		if(req > k){
			low = mid + 1;
		}
		else{

			ans = min(ans, mid);
			high = mid - 1;
		}
	}
	cout<<ans;

}

signed main(){
	setup();

	int number_of_testcases = 1;

	// cin >> number_of_testcases; // comment it for single testcase

	while ( number_of_testcases-- )
		solve();
	
	
}

void setup() {
	#ifndef ONLINE_JUDGE
		freopen("input.txt", "r",stdin);freopen("out.txt", "w", stdout);freopen("out.txt", "w", stderr);
	#else
		ios_base::sync_with_stdio(0);cin.tie(0);
	#endif
}

void sieve(ll n) {
	prime.resize(n+5,0);
	for(ll i = 2; i <= n ; i++) {
		if(not prime[i]) {
			prime[i] = i;
			for(ll j = i * i ; j <= n ; j += i)
				if( not prime[j] )
					prime[j] = i;
		}
	}
}

ll pow(ll b,ll e){if(e==0)return 1;else if(e%2==0){ll a=pow(b,e/2);return a*a;}else {ll a=pow(b,e/2);return b*a*a;}}
ll powm(ll x,ll y,ll m){x=x%m;ll res=1;while(y){if(y&1)res=res*x;res%=m;y=y>>1;x=x*x;x%=m;}return res;}
ll gcd(ll a,ll b){if(a<b)return gcd(b,a);else if(b==0)return a;else return gcd(b,a%b);}
ll lcm(ll a,ll b){ return (a*b)/gcd(a,b);}
bool isprime(ll n){for(ll i=2;i*i<=n;i++)if(n%i==0)return 0;return 1;}
ll modInverse(ll a, ll m) { return powm(a, m-2, m);}

template <typename T> ostream& operator << (ostream& os,const vector<T>& v){ for(T e:v) os<<e<<", ";return os;} 
template <typename T> ostream& operator << (ostream& os,const set<T>& v){for(T e:v) os<<e<<", ";return os;} 
template <typename T> ostream& operator << (ostream& os,const multiset<T>& v){for(T e:v) os<<e<<", ";return os;} 
template <typename T, typename Y> ostream& operator << (ostream& os, const pair<T,Y>& v) {os<<'{'<<v.first<<", "<<v.second<<"}";return os;} 
template <typename T, typename S> ostream& operator << (ostream& os, const map<T, S>& v) { for (auto it : v) os <<"{"<< it.first << ", " << it.second << "}, "; return os; }

Measured memory_bytes: 5148