#include <stdio.h>
#include <vector>
#include <list>
#include <array>
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <unordered_map>
#include <stdexcept>


using std::string;
using std::vector;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// util
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

std::vector<std::string> split(const std::string& input, char delimiter)
{
    std::istringstream stream(input);

    std::string field;
    std::vector<std::string> result;
    while (std::getline(stream, field, delimiter)) {
        result.push_back(field);
    }
    return result;
}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// user func
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void printList(const vector<int>& list) {
    // print
    for(int i = 0; i < list.size(); i++){
        printf("%d", list[i]);
        if(i != list.size() -1){
            printf(" ");
        }
    }
    printf("\n");
}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// logic
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int find(const vector<int> haystack, int needle){
    for(auto& each: haystack){
        if(each == needle) return 1;
    }
    return 0;
}

bool load(const vector<int>& list, int capacity, int numTruck){
    int remainTruck = numTruck - 1;
    int loaded = 0;
    for(int each: list) {
        // printf("capa:%d, load:%d + %d\n", capacity, loaded, each);
        if (loaded + each <= capacity){
            loaded += each;
        } else {
            loaded = each;
            remainTruck--;
            // printf("remain: %d\n", remainTruck);
            if(remainTruck < 0) {
                return false;
            }
        }
    }
    return true;
}

void solve() {
    int numInput;
    scanf("%d", &numInput);
    int numTruck;
    scanf("%d", &numTruck);

    long long sum = 0;
    int max = 0;
    int min = std::numeric_limits<int>::max();
    vector<int> list(numInput);
    for (int i = 0; i < numInput; i++){
        int v;
        scanf("%d", &v);
        sum += v;
        max = std::max(v, max);
        min = std::min(v, min);
        list[i] = v;
    }

    // capaは max ... sum の間にある
    // printf("sum: %lld, max: %d\n", sum, max);
    long long capacity = std::ceil((sum - max) / 2) + max;
    int lastMax = sum;
    int lastMin = max;
    // 半分ずつ狭めたい。前回成功し今回も成功ならその間を大きい方へ探索、前回失敗し今回成功なら小さい方へ探索
    bool last = false;
    while (true) {
        // printf("capa:%lld max:%d min:%d\n", capacity, lastMax, lastMin);
        bool res = load(list, capacity, numTruck);
        // printf("%s\n", res ? "success" : "fail");
        if(lastMax - lastMin == 1) {
            if (load(list, lastMin, numTruck)){
                capacity = lastMin;
            }else{
                capacity = lastMax;
            }
            break;
        }
        // succes goto smaller
        if(res){
            last = true;
            lastMax = capacity;
            capacity = std::ceil((capacity - lastMin) / 2) + lastMin;
        //faile goto larger
        } else {
            last = false;
            lastMin = capacity;
            capacity = std::ceil((lastMax - capacity) / 2) + capacity;
        }


    }
    // res
    printf("%lld\n", capacity);
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// main
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main() {
    solve();
    return 0;
}


Measured memory_bytes: 3220