#include <bits/stdc++.h>

#define rep0(i, n) for(int i=0; i<(int)(n);i++)
#define rep1(i, n) for(int i=1; i<=(int)(n);i++)
#define all(x) (x).begin(), (x).end()
#define debug(a) if(flagdebug){cout << "debug (" #a "):" << endl << (a) << endl;}

using namespace std;

typedef uint64_t ulint;
typedef int64_t lint;

// #include <boost/multiprecision/cpp_int.hpp>
// using bint = boost::multiprecision::cpp_int;

template<class T> lint sum(vector<T> a);
template<class T> double ave(vector<T> a);
template<typename T> ostream& operator << (ostream& s, const vector<T>& v);
ulint gcd(lint a, lint b);
ulint lcm(lint a, lint b);

bool flagdebug = false;





int main(){
//////////////////////////////////////////////////////

    //flagdebug = true; ///本番時削除！！！！！

    //入力

    lint n, k;
    cin >> n >> k;

    vector<lint> v(n + 1);

    rep1(i,n)
    {
        cin >> v[i];
    }

    debug(v);
    //2次元配列
    //vector<vector<lint>> mat(row, vector<lint>(column, 初期値));


    // multiset<lint> lgabage[n];
    // multiset<lint> rgabage[n];

    // lint tmp = 0;
    // rep0(i, n)
    // {
    //     if(i != 0)
    //     {
    //         copy(all(lgabage[i-1]) , back_inserter(lgabage[i] ) ); //コピー
    //     }

    //     cin >> v[i];
    //     if(v[i] >= 0)
    //     {
    //         //ごみでないので普通に加算
    //         tmp += v[i];
    //         lplus[i] = tmp;
    //     } 
    //     else
    //     {
    //         //ごみ;
    //         lgabage[i].insert(v[i]);
    //     }
    // }

    // rep0(i, n)
    // {
    //     if(i != 0)
    //     {
    //         copy(all(rgabage[i-1]) , back_inserter(rgabage[i] ) ); //コピー
    //     }

    //     cin >> v[ n - i - 1 ];
    //     if(v[ n - i - 1 ] >= 0)
    //     {
    //         //ごみでないので普通に加算
    //         tmp += v[ n - i - 1 ];
    //         lplus[i] = tmp;
    //     } 
    //     else
    //     {
    //         //ごみ;
    //         lgabage[i].insert(v[ n - i - 1 ]);
    //     }
    // }


    // vector<lint> lplus(n,0);
    // vector<lint> rplus(n,0);


    lint lp = 0;
    vector<lint> lgabage;
    lint ans = 0;
    for(lint l = 0 ; l <= min(k,n) ; l ++)
    {
        if(l > k)break;
        if(l > 0)
        {
            if(v[l]>=0)
            {
                lp+=v[l];
            }
            else
            {
                lgabage.push_back(v[l]);
            }
        }


        debug(lp);
        //debug(lgabage);
    
        lint rp = 0;
        vector<lint> rgabage;
        copy(all(lgabage), back_inserter(rgabage));
        for ( lint r = 0 ; r <= min(k,n) ; r ++)
        {
            if(l + r > n)break; //筒が空なら
            if(l + r > k)break;

            if(r > 0)
            {
                if(v[n+1-r]>=0)
                {
                    rp+=v[n+1-r];
                }
                else
                {
                    rgabage.push_back(v[n+1-r]);
                }
            }


            lint val = lp + rp; //価値

            if(k - l - r < rgabage.size())
            {
                //行動回数が足りないのでマイナスを一部加算する
                //昇順に並べ替えるとマイナスの絶対値が大きいものが前にくる
                //前の方は捨てるので後ろの方のみ結果に加算する
                sort(all(rgabage));
                for(lint i = k - l - r; i < rgabage.size() ; i++)
                {
                    val += rgabage[i];
                }
            }
            //else//行動回数があるのでマイナスは全て捨てる


            ans = max(val,ans);
        }
    }

    cout << ans << endl;

    //2次元配列
    //vector<vector<lint>> mat(row, vector<lint>(column, 初期値));
    //ペア
    //pair<lint,lint> p = make_pair(1,2);
    //vector<pair<lint,lint>> c(100010, pair<lint,lint>(0,0));
    //タプル
    //tuple<lint,lint,lint> t  = make_tuple(1,2,3);


    //昇順ソート
    //sort(all(a));
    //降順ソート
    //sort(all(a),greater<lint>());
    //特殊なソート（ラムダ式）
    //sort(all(mat), [&i](const vector<lint> &a, const vector<lint> &b){return a[i] < b[i];});
    // //[&i]は参照する変数，いらなければからの大括弧でよし．
    //ソート済集合（順序付き集合）
    //set<lint> st;
    //itr.insert(0);
    //auto itrmin = st.begin(); //最小値の次へアクセス
    //auto itrmax = st.end(); //最大値の次へアクセス（かならずデクリメントが必要）
    //itrmax --; //最大値はst.end()の1つ前
    //st.erase(0);
    //st.find;
    
    //////////////////////////////////////////////////////
    //キュー
    //queue<lint> que;
    //que.push(value);
    //que.front(); //先頭を参照
    //que.top(); //トップを参照（消されないので消したい場合は直後にpop()を使う）
    //que.pop(); //追い出す
    //que.empty(); //空なら1，あれば0
    //優先度付きキュー
    //priority_queue<lint> que;
    //キューにque.push()で入れると最大値順に並べられる．que.pop()で取り出すときは常に最大値が前にくる．
    //最小値から取り出したい時はpriority_queue< lint, std::vector<lint>, std::greater<lint> >
    //////////////////////////////////////////////////////
    //スタック
    //stack<lint> stk;
    //stk.push(value);
    //stk.top(); //先頭を参照（消されないので消したい場合は直後にpop()を使う）
    //stk.pop(); //トップを削除
    //stk.empty(); //空なら1,あれば0
    //stk.size(); //数
    //
    // sort(input.begin() , input.end());
    // uint64_t max = numeric_limits<uint64_t>::max();

//////////////////////////////////////////////////////
// Ctrl + Opt + N to make
    return 0;
}


struct node
{
    node* parent;
    node* firstchild;
    node* lastchild;
    node* olderbrother;
    node* youngerbrother;
    lint childnum;
    lint value;
public:
    node()
    {
        parent = NULL;
        firstchild = NULL;
        lastchild = NULL;
        olderbrother = NULL;
        youngerbrother = NULL;
        childnum = 0;
        value = 0;
    }

    void addchild(node* newchild)
    {
        if(childnum == 0)
        {
            firstchild = newchild;
        }
        else
        {
            lastchild->youngerbrother = newchild;
            newchild->olderbrother = lastchild;
            
        }
        lastchild = newchild;
        newchild->parent = this;
        childnum++;
    }
    void deletechild(node* child)
    {
        if(child->parent != this)return;
        if(child->youngerbrother != NULL)
        {
            child->youngerbrother->olderbrother = child->olderbrother;
        }
        if(child->olderbrother != NULL)
        {
            child->olderbrother->youngerbrother = child->youngerbrother;
        }
        childnum--;
    }

    bool operator<(const node &another) const{return value < another.value;};
    bool operator>(const node &another) const{return value > another.value;};   
};

//vectorprint用
template<typename T> ostream& operator << (ostream& s, const vector<T>& v) {
    s << "[\t";
    for (auto i = v.begin(); i < v.end() - 1; i++){s << *i << "\t";}
    s << *(v.end() - 1) << "\t]\n";
	return s;
}

// 最大公約数
ulint gcd(lint a, lint b){
    if(b!=0){return gcd(b, a % b);}
    return a;    
}

//最小公倍数
ulint lcm(lint a, lint b){
    return a / gcd(a, b) * b;
}



Measured memory_bytes: 256