#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
#pragma GCC diagnostic ignored "-Wunused-variable"

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds;
using namespace std;
using namespace std::chrono; 

typedef long long ll;
typedef uint64_t ull;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef set<ll> sl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template<class key_type, class cont = vl, class comp = less<key_type>>
using p_queue = priority_queue<key_type, cont, comp>;
template<class key_type, class comp = less<key_type>>
using my_set = tree<key_type, null_type, comp, rb_tree_tag, tree_order_statistics_node_update>;
template<class key_type, class value_type, class comp = less<key_type>>
using my_map = tree<key_type, value_type, comp, rb_tree_tag, tree_order_statistics_node_update>;

const ll INF = (ll)9e18;
const ll mod1 = 998244353;
const ll mod2 = 1000000007; //10^9 + 7
#define sz(v) ll((v).size())
#define all(v) v.begin(), v.end()
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define mp make_pair
#define mt make_tuple
#define rep1(i, a, b) for (ll i = a; i < b; i++)
#define rep2(i, a, b) for (ll i = a; i <= b; i++)
#define rep3(i, a, b) for (ll i = a; i > b; i--)
#define rep4(i, a, b) for (ll i = a; i >= b; i--)
#define rep(type, i, a, op, b, change) for (type i = a; i op b; i += change)
#define SQ(a) ll(a) * (a)
#define nl cout << '\n'
#define yes cout << "YES\n"
#define no cout<< "NO\n"
#define out2(a, b) cout << a << ' ' << b << '\n'
#define in2(a, b) cin >> a >> b
#define out3(a, b, c) cout << a << ' ' << b << ' ' << c << '\n'
#define in3(a, b, c) cin >> a >> b >> c
#define out4(a, b, c, d) cout << a << ' ' << b << ' ' << c <<  ' ' << d << '\n'
#define in4(a, b, c, d) cin >> a >> b >> c >> d
#define google(x, y) cout << "Case #" << x << ": " << y << '\n'
#define clk_start auto start = steady_clock::now()
#define clk_finish auto finish = steady_clock::now()
#define clk_dur duration_cast<milliseconds>(finish - start).count()

template<typename T>
ostream& operator<<(ostream& stream, const vector<T>& vec)
{
    ll n = vec.size();
	for (ll i = 0; i < n; i++)
	{
		stream << vec[i] << ' ';
	}
	stream << '\n';
	return stream;
}

template<class T>
istream& operator>>(istream& stream, vector<T>& vec)
{
    ll n = vec.size();
	for (ll j = 0; j < n; j++)
	{
		stream >> vec[j];
	}
	return stream;
}

istream& operator>>(istream& stream, pll& p)
{
	stream >> p.first >> p.second;
	return stream;
}

ll log(ll base, ll n)
{
	ll prod = base;
	ll p = 0;
	while (1)
	{
		if (n < prod)
		{
			return p;
		}
		prod *= base;
		p++;
	}
}

ll power(ll x, ll y)
{
	ll res = 1;
	while (y > 0)
	{
		if (y & 1)
			res = (res * x);
		y = y >> 1;
		x = (x * x);
	}
	return res;
}

vl numinverse;
void InverseofNumbers(ll n, ll p) //p is prime
{ 
    numinverse.resize(n + 1);
    numinverse[0] = numinverse[1] = 1; 
    for (ll i = 2; i <= n; i++) 
        numinverse[i] = numinverse[p % i] * (p - p / i) % p; 
} 

vl factorial_inverse;
void InverseofFactorial(ll n, ll p) 
{ 
    factorial_inverse.resize(n + 1);
    factorial_inverse[0] = factorial_inverse[1] = 1; 
    for (int i = 2; i <= n; i++) 
        factorial_inverse[i] = (numinverse[i] * factorial_inverse[i - 1]) % p; 
}

vl fact; 
//fact[i] = factorial(i) % p //O(n)
void factorialmod(ll n, ll p)
{
	fact.resize(n + 1);
    ll ans = 1;
    rep2(i, 0, n)
    {
        fact[i] = ans;
        ans = (ans * (i + 1)) % p;
    }
}

ll ncrmod(ll n, ll r, ll p)
{ 
    ll ans = ((fact[n] * factorial_inverse[r]) 
              % p * factorial_inverse[n - r]) 
             % p; 
    return ans; 
}

ll ncr(ll n, ll r)
{
    if (n < r)
        return 0;
	ll res = 1;
	if (r > n - r)
		r = n - r;
	rep1(i, 0, r)
	{
		res *= (n - i);
		res /= (i + 1);
	}
	return res;
}

tuple<ll, ll, ll> euclid(ll a, ll b)
{
	ll d1, x1, y1;
	if (b == 0)
		return { a, 1, 0 };
	else
	{
		tie(d1, x1, y1) = euclid(b, a % b);
	}
	ll d = d1, x = y1, y = x1 - a / b * y1;
	return { d, x, y };
}

ll power_mod(ll x, ll y, ll p)
{
	ll res = 1;
	x = x % p;
	while (y > 0)
	{
		if (y & 1)
			res = (res * x) % p;
		y = y >> 1;
		x = (x * x) % p;
	}
	return res;
}

ll modInverse(ll n, ll p)
{
	return power_mod(n, p - 2, p);
}

ll phi(ll n) {
	ll result = n;
	for (ll i = 2; i * i <= n; i++) {
		if (n % i == 0) {
			while (n % i == 0)
				n /= i;
			result -= result / i;
		}
	}
	if (n > 1)
		result -= result / n;
	return result;
}

vector<bool> is_prime;
vector<ll> primes;
void prime_generator(ll n)
{
	is_prime = vector<bool>(n + 1, false);
	vector<bool> a(n + 1, true);
	for (ll i = 2; i * i <= n; i++)
	{
		if (a[i])
		{
			for (ll j = i * i; j <= n; j += i)
			{
				a[j] = false;
			}
		}
	}
	for (ll i = 2; i <= n; i++)
	{
		if (a[i])
		{
			is_prime[i] = true;
			primes.pub(a[i]);
		}
	}
}

vector<ll> spf;
void sieve(ll n)
{
	spf = vl(n + 1);
	spf[1] = 1;
	for (ll i = 2; i <= n; i++)
		spf[i] = i;
	for (ll i = 4; i <= n; i += 2)
		spf[i] = 2;

	for (ll i = 3; i * i <= n; i++)
	{
		if (spf[i] == i)
		{
			for (ll j = i * i; j <= n; j += i)
				if (spf[j] == j)
					spf[j] = i;
		}
	}
}

vector<ll> getFactorization(ll x)
{
	vector<ll> ret;
	while (x != 1)
	{
		ret.push_back(spf[x]);
		x = x / spf[x];
	}
	return ret;
}

vl subset;
void naive_subset_search(ll k, vl& arr)
{
	if (k == arr.size())
	{
		//Process subset
		//for eg we can do cout << subset
	}
	else
	{
		naive_subset_search(k + 1, arr);
		subset.pub(arr[k]);
		naive_subset_search(k + 1, arr);
		subset.pob();
	}
}

void radix_sort(vector<ll>& arr)
{
	ll d = 0;
	for (const auto& i : arr)
	{
		d = max(d, log(10, i) + 1);
	}
	ll n = arr.size();
	vector<queue<ll> > digits(10);
	ll prod = 10;
	vector<ll> tmp = arr;
	while (d--)
	{
		for (ll i = 0; i < n; i++)
		{
			digits[tmp[i] % 10].push(arr[i]);
		}
		ll index = 0;
		for (ll i = 0; i < 10; i++)
		{
			while (!digits[i].empty())
			{
				arr[index] = digits[i].front();
				tmp[index] = arr[index] / prod;
				digits[i].pop();
				index++;
			}
		}
		prod *= 10;
	}
}

ll tc = 1;
void solve();

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	ll t = 1;
	//cin >> t;
	//clk_start;
	for (tc = 1; tc <= t; tc++) solve();
	//clk_finish;
	//cout << clk_dur << '\n';
	return 0;
}

ll cut(vl& logs, ll l)
{
    ll ans = 0;
    for (auto& i : logs)
    {
        ans += (i - 1) / l;
    }
    return ans;
}

void solve()
{
	ll n, k;
    in2(n, k);
    vl logs(n);
    cin >> logs;
    ll left = 1, right = *max_element(all(logs));
    ll ans = INF;
    while (left <= right)
    {
        ll mid = left + (right - left) / 2;
        if (cut(logs, mid) <= k)
        {
            ans = mid;
            right = mid - 1;
        }
        else
        {
            left = mid + 1;
        }
    }
    cout << ans << '\n';
}

//#pragma GCC diagnostic pop

Measured memory_bytes: 4728