using System;
using System.Collections.Generic;
using System.Text;
using System.Numerics;
using System.IO;


namespace SolutionCS
{
    class Program
    {
        public class TestElem : IComparable
        {
            public int value;
            public int num;

            public TestElem(int v, int n)
            {
                value = v;
                num = n;
            }

            public int CompareTo(object obj)
            {
                TestElem other = (TestElem)obj;

                return -value.CompareTo(other.value);
            }
        }

        public class PriorityQueue<T> where T : IComparable
        {
            T[] heap;
            int count = 0;

            public PriorityQueue(int maxSize)
            {
                heap = new T[maxSize];
                count = 0;
            }

            public void Push(T elem)
            {
                // 要素をPushするインデックス(枝の末尾部分)
                int i = count;

                // 要素数を増やす
                count++;

                // 親(i=0)に向かってたどる
                while (i > 0)
                {
                    // 親のインデックス
                    int p = (i - 1) / 2;

                    // elemのほうが大きいか同一の場合、Pushするインデックス確定
                    if (heap[p].CompareTo(elem) <= 0)
                    {
                        break;
                    }

                    // 親→子にコピーして再度親との比較を行う
                    heap[i] = heap[p];
                    i = p;
                }

                // 要素を決まったインデックスに入れる
                heap[i] = elem;
            }

            public T Pop()
            {
                // 要素なしの場合、Exception
                if (count == 0)
                {
                    throw new InvalidOperationException();
                }

                // 要素数減らす
                count--;

                // 返す要素を保存
                T result = heap[0];

                // 一番末端の要素(これを親から比較して配列に配置する)
                T x = heap[count];

                // 親から末尾に向かって子→親入れ替えを行う
                int i = 0;
                while (i * 2 + 1 < count)
                {
                    int l = i * 2 + 1;      // 子の左枝のインデックス
                    int r = i * 2 + 2;      // 子の右枝のインデックス

                    // 右が範囲外ではない、右のほうが小さいか検証
                    if (r < count && heap[r].CompareTo(heap[l]) < 0)
                    {
                        // 右のほうが小さい場合、上に上がっていくのは右のインデックス
                        l = r;
                    }

                    // x(配列の一番最後の要素)と比べて、大きければおわり
                    if (heap[l].CompareTo(x) >= 0)
                    {
                        break;
                    }

                    // 一個親側に繰り上げ
                    heap[i] = heap[l];

                    // 処理した枝のインデックスを与え、再度入れ替え
                    i = l;
                }

                // 一番末尾の要素を新たに保存
                heap[i] = x;

                // 最初に保存していた結果を返す
                return result;
            }

            public int Count { get { return count; } }
            public T Peek { get { return heap[0]; } }
        }

        static int N;
        static int K;
        static int[] v;
        static int[] g;

        static void Main(string[] args)
        {
            string[] s = Console.ReadLine().Split(' ');

            N = int.Parse(s[0]);
            K = int.Parse(s[1]);
            v = new int[N];
            g = new int[K];

            s = Console.ReadLine().Split(' ');
            for (int i = 0; i < N; i++)
            {
                v[i] = int.Parse(s[i]);
            }

            int ans = 0;
            for (int i = 1; i <= K; i++)
            {
                ans = Math.Max(ans, Solve(i));
            }

            Console.WriteLine(ans);
        }

        // k回の手順での最大値を求める
        static int Solve(int k)
        {
            int ans = 0;

            // 取得する数を１～kまで試行する(N個までしかできない）
            for (int i = 1; i <= Math.Min(k, N); i++)
            {
                // 取得する数：i
                // 戻す数：k-i
                // 残る数：i-(k-i) = 2i-k

                // 残る数がない場合、試行しない
                if ( i * 2 - k <= 0)
                {
                    continue;
                }

                // 左側から取るのを0～iまで試行する
                for (int left = 0; left <= i; left++)
                {
                    Get(left, i - left);

                    Array.Sort(g, 0, i);
                    Array.Reverse(g, 0, i);

                    int ans0 = 0;
                    for (int t = 0; t < i * 2 - k; t++)
                    {
                        ans0 += g[t];
                    }

                    ans = Math.Max(ans, ans0);
                }
            }

            return ans;
        }

        static void Get(int left, int right)
        {
            for (int i = 0; i < left; i++)
            {
                g[i] = v[i];
            }
            for (int i = 0; i < right; i++)
            {
                g[left + i] = v[N - i - 1];
            }
        }
    }
}


Measured memory_bytes: 11220