#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <string>

#include <cstdio>
using namespace std;


int a1();
void a2();
int a3();
int a4();
int a5();
int a6();
int a7();
int a8();
int main()
{
	//cout << a1() << endl;
	//a2();
	//a3();
	//a4();
	a8();
	return 0;
}
//装载货物***************8

int load(long long int w[], int k, long long int p,int n);
int a8()
{
	int n, k;
	long long int w[100000];
	cin >> n >> k;
	for (int i = 0; i < n; i++)
		cin >> w[i];
	long long int p;
	long long int left = 0; long long int right = 10000*100000;
	//cout << load(w, k, 9, n) << endl;
	while (left +1< right)
	{
		p = (left + right) / 2;
		if (load(w, k, p,n) >= n)
			
			right = p;
		else
			left = p;
	}
	cout << right << endl;
	return 0;
			
}
int load(long long int w[], int k, long long int p,int n)//k车，p载重，可以载多少个货物
{
	int i = 0;
	int j = 0;
	while (1)
	{
		if (j == k)
			return i;
		int t = p;
		if (w[i] > t) return i;//这个时候就没必要算了
		while (w[i] <= t)
		{
			//cout << w[i] <<" "<< t << endl;
			t = t - w[i];
			i++;
			
			//cout << i << " " << t << endl;
			if (i == n) return n;//
		}
		j++;
		
	}
	
}
//*********************7***********二分搜索库函数
int a7()
{
	int a[8] = { 1,3,5,22,34,65,88,234 };
	int *pos = lower_bound(a, a + 8, 5);//第一个不小于5的位置
	int index = distance(a, pos);
	int *pos1 = upper_bound(a, a + 8, 5);//第一个大于5的位置（指针）
	int index1 = distance(a, pos1);
	bool bb = binary_search(a, a + 8, 5);//是否找到
	cout << index << " " << *pos << " " << endl;
	cout << index1 << " " << *pos1 << " " << endl;
	cout << bb << endl;
	return 0;
}

//***********************6二分搜索
bool binarysearch(vector<int> v, int val);
int a6()
{
	int n, q;
	vector<int> vn;
	int temp;
	int cnt1 = 0;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> temp;
		vn.push_back(temp);
	}
	cin >> q;
	sort(vn.begin(), vn.end());//排序
	//for (auto a : vn)
	//	cout << a << " ";
	
	for (int i = 0; i < q; i++)
	{
		cin >> temp;
		if (binarysearch(vn, temp)) {
			//cout <<temp<< "true"; 
			cnt1++;
		}
		//cout << cnt1 << endl;
	}
	cout << cnt1 << endl;
	return 0;

}
bool binarysearch(vector<int> v, int val)
{
	
	int left = 0; int right = v.size();
	while (left  < right)
	{
		int mid = (left + right) / 2;
		if (v[mid] == val) {
			//cout << "true";
			return true;
		}
		else if (v[mid] > val) 
		{
			right = mid;
		}
		else
			left = mid+1;
	}
	//cout<<" false";
	return false;
	
}
//**********************5队列任务
int a5()
{
	int t = 0;
	queue<pair<string,int>> que;
	int n, q;
	cin >> n >> q;
	string name; int time;
	for (int i = 0; i < n; i++)
	{
		cin >> name>> time;
		que.push(make_pair(name, time));
	}

	while(!que.empty())
	{
		pair<string, int> u = que.front();
		if (u.second > q)
		{
			u.second -= q;
			que.push(u);
			t = t + q;
		}
		else
		{
			t += u.second;
			cout << u.first << " " << t << endl;
		}
			
		
		//cout << "t=" << t << endl;
		que.pop();
	}
	return 0;
}
//*********************4
//逆波兰表示
int a4()
{
	stack<int> s;
	string str;
	while (cin>>str)//ctrl+c
	{
		//int t = stoi(str);
		//int t=atoi(str.c_str())
		if (str[0] == '+')
		{
			int a = s.top(); s.pop();
			int b = s.top(); s.pop();
			s.push(a + b); //cout << s.top() << endl;
		}
		else if (str[0] == '-')
		{
			int a = s.top(); s.pop();
			int b = s.top(); s.pop();
			s.push(b-a); //cout << s.top() << endl;
		}
		else if (str[0] == '*')
		{
			int a = s.top(); s.pop();
			int b = s.top(); s.pop();
			s.push(a * b); //cout << s.top() << endl;
		}
		else
		{
			//cout << str << endl;
			s.push(stoi(str));
			//cout << s.top() << endl;
		}

	}
	cout << s.top() << endl;
	return 0;
}
//***********3
int cnt = 0;
void insertsort(vector<int> &v, int g);

int a3()
{
	//插入排序的特点：当数据相对有序时效率较高。利用对已经排好的数据进行插入排序，只需比较N次，而不需要移动。
	//希尔排序：利用插入排序的特点。
	//首先生成希尔数列(h = 3 * h + 1)

	//输入数据
	int n;//元素数目
	vector<int> v1;
	cin >> n;
	int temp;
	for (int i = 0; i<n; i++)
	{
		cin >> temp;
		v1.push_back(temp);
	}

	//生成数列
	vector<int> G;//希尔数列
	int h = 1;
	while (h <=n)
	{
		G.push_back(h);
		h = 3 * h + 1;
	}
	
	//间隔插入排序
	
	for (int i = G.size() - 1; i >= 0; i--)
	{
		
		insertsort(v1, G[i]);
	}
	
	//输出
	cout << G.size() << endl;;
	for (int i = G.size()-1; i >=0; i--)
	{
		if (i == G.size() - 1) cout << G[i];
		else cout << " " << G[i];
		cout<< endl;
	}
	
	cout << cnt << endl;
	for (int i = 0; i < v1.size(); i++)
		cout << v1[i] << endl;

	return 0;
}
void insertsort(vector<int> &v, int g)//间隔为g的插入排序
{
	int n = v.size();
	
	//cout << n << endl;
	for (int i = g; i < n; i++)
	{
		int t = v[i];
		int j = i - g;
		while (j >= 0 &&v[j]>t )//实际上只需要把v[i]插入到里面即可，v[j]都是已经排好序的...记住应该首先判断j,
			//对与每个 i 循环代码实际只运行一次
		{
			v[j + g] = v[j];
			j -= g;
			cnt++;//计算交换次数
			//cout << cnt << endl;
			
		}
		v[j + g] = t;
		//for (int i = 0; i < v.size(); i++)
		//	cout << v[i];
		//cout << endl;
	}
}

//**********************************1
int a1()
{
	int n;
	cin >> n;
	vector<int> v;
	int t;
	for (int i = 0; i<n; i++)
	{
		cin >> t;
		v.push_back(t);
	}
	int tmin = v[0];
	int tmax = -1000000000;

	for (int i = 1; i<n; i++)
	{
		tmax = max(tmax, v[i] - tmin);
		tmin = min(tmin, v[i]);
	}
	return tmax;
}

//*************************2
void a2()
{
	cout << "插入排序，冒泡排序，选择排序空间复杂度O（1）,时间复杂度O（N^2）" << endl;
	cout << "插入排序，冒泡排序属于稳定排序" << endl;
	cout << "选择排序属于不稳定排序" << endl;
	cout << "冒泡排序的交换次数又称为逆序数，反映了数据的混乱程度" << endl;
}




Measured memory_bytes: 3876