#include <array>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <utility>
#include <tuple>
#include <algorithm>
#include <limits>
#include <fstream>
#include <numeric>
#include <stack>
#include <queue>
#include <list>
#include <cstring>
#include <unordered_set>

namespace
{
	template<int N>
	std::array<int, N> GetValue(std::istream& stream)
	{
		std::string buf;
		std::getline(stream, buf);

		std::stringstream sstr(buf);
		std::array<int, N> retval;

		for (int i = 0; i < N; ++i)
		{
			std::getline(sstr, buf, ' ');
			retval[i] = std::stoi(buf);
		}

		return retval;
	}

	std::vector<int> GetValue(std::istream& stream, int num)
	{
		std::string buf;
		std::getline(stream, buf);
		std::stringstream sstr(buf);

		std::vector<int> retval;
		retval.reserve(num);

		int input;
		for (int i = 0; i < num; ++i)
		{
			sstr >> input;
			retval.push_back(input);
		}

		return retval;
	}

	int GetValue(std::istream& stream)
	{
		int in;
		stream >> in;

		return in;
	}

	std::vector<std::string> GetValueString(std::istream& stream, int num, char delim)
	{
		std::string buf;
		std::vector<std::string> retval;
		retval.reserve(num);

		std::getline(stream, buf);
		std::stringstream sstr(buf);

		for (int i = 0; i < num && std::getline(sstr, buf, delim); ++i)
		{
			retval.push_back(std::move(buf));
		}

		return retval;
	}

	template<typename T>
	void PrintLine(const std::vector<T>& sequence)
	{
		std::cout << sequence[0];

		for (size_t i = 1; i < sequence.size(); ++i)
		{
			std::cout << ' ' << sequence[i];
		}

		std::cout << std::endl;
	}

	template<typename T>
	void Print(const std::vector<T>& sequence)
	{
		for (const auto& e : sequence)
		{
			std::cout << e << '\n';
		}

		std::cout << std::flush;
	}

	int GetFirst(const std::vector<int>& weight, int track)
	{
		int per_track = weight.size() / track;
		if (0 != weight.size() % track)
		{
			++per_track;
		}

		int content = 0;

		for (int i = 0; i < track; ++i)
		{
			int c = 0;
			for (int j = 0; j < per_track; ++j)
			{
				try
				{
					c += weight.at(i * per_track + j);
				}
				catch (...)
				{
					break;
				}
			}
			content = std::max(content, c);
		}

		return content;
	}

	bool Check(int content, int track_num, const std::vector<int>& weight)
	{
		int track = 0;
		int left = content;
		for (size_t i = 0; i < weight.size(); )
		{
			if (track == track_num)
			{
				return false;
			}

			left -= weight[i];

			if (0 < left)
			{
				++i;
			}
			else if(0 == left)
			{
				++i;
				++track;
				left = content;
			}
			else
			{
				++track;
				left = content;
			}
		}

		return true;
	}
}

int main(int argc, char* argv[])
{
	auto file = (argc == 1) ? std::ifstream() : std::ifstream(argv[1]);
	std::istream& stream = (argc == 1) ? std::cin : file;
	if (argc == 1)
	{
		std::cin.tie(0);
		std::ios::sync_with_stdio(false);
	}

	auto line1 = GetValue<2>(stream);
	int burden = line1[0];
	int track = line1[1];

	std::vector<int> weight;
	weight.reserve(burden);
	for (std::string buf; std::getline(stream, buf); )
	{
		weight.push_back(std::stoi(buf));
	}

	int max_value = GetFirst(weight, track);
	int min_value = *std::max_element(weight.begin(), weight.end());
	if (max_value == min_value)
	{
		std::cout << max_value << std::endl;
		return 0;
	}

	while (true)
	{
		int mid = (max_value + min_value) / 2;

		bool result = Check(mid, track, weight);

		if (max_value - min_value == 1)
		{
			if (result)
			{
				std::cout << min_value << std::endl;
				break;
			}
			else
			{
				std::cout << max_value << std::endl;
				break;
			}
		}

		if (result)
		{
			max_value = mid;
		}
		else
		{
			min_value = mid;
		}
	}
}



Measured memory_bytes: 3416