Problem:
Score : 400 points

Problem Statement

Your friend gave you a dequeue D as a birthday present.

D is a horizontal cylinder that contains a row of N jewels.

The values of the jewels are V_1, V_2, ..., V_N from left to right. There may be jewels with negative values.

In the beginning, you have no jewel in your hands.

You can perform at most K operations on D, chosen from the following, at most K times (possibly zero):

Operation A: Take out the leftmost jewel contained in D and have it in your hand. You cannot do this operation when D is empty.

Operation B: Take out the rightmost jewel contained in D and have it in your hand. You cannot do this operation when D is empty.

Operation C: Choose a jewel in your hands and insert it to the left end of D. You cannot do this operation when you have no jewel in your hand.

Operation D: Choose a jewel in your hands and insert it to the right end of D. You cannot do this operation when you have no jewel in your hand.

Find the maximum possible sum of the values of jewels in your hands after the operations.

Constraints

All values in input are integers.

1 \leq N \leq 50

1 \leq K \leq 100

-10^7 \leq V_i \leq 10^7

Input

Input is given from Standard Input in the following format:

N K
V_1 V_2 ... V_N

Output

Print the maximum possible sum of the values of jewels in your hands after the operations.

Sample Input 1

6 4
-10 8 2 1 2 6

Sample Output 1

14

After the following sequence of operations, you have two jewels of values 8 and 6 in your hands for a total of 14, which is the maximum result.

Do operation A. You take out the jewel of value -10 from the left end of D.

Do operation B. You take out the jewel of value 6 from the right end of D.

Do operation A. You take out the jewel of value 8 from the left end of D.

Do operation D. You insert the jewel of value -10 to the right end of D.

Sample Input 2

6 4
-6 -100 50 -2 -5 -3

Sample Output 2

44

Sample Input 3

6 3
-6 -100 50 -2 -5 -3

Sample Output 3

0

It is optimal to do no operation.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Math;
using static Math2;
using static Output;

public class CP {
  public void Solve () {
    Input sc = new Input ();
    int n, k;
    sc.mul (out n, out k);
    var v = sc.cinarr<int> ();
    var ma = -INFL;
    for (int i = 0; i <= Min (n, k); ++i) {
      for (int j = 0; i + j <= Min (n, k); ++j) {
        var mine = new List<int> ();
        for (int l = 0; l < i; ++l) mine.Add (v[l]);
        for (int r = 0; r < j; ++r) mine.Add (v[n - 1 - r]);

        mine.Sort ();
        long sum = mine.Sum ();
        for (int m = 0; m < Min (k - (i + j), mine.Count); ++m) {
          if (mine[m] < 0) sum -= mine[m];
        }
        ma = Max (ma, sum);
      }
    }
    Put (ma);
  }
}
public static class Math2 {
  public const int INF = 1 << 29;
  public const long INFL = 1L << 60;
  public const long MOD = 1000000007;
  public const long MOD2 = 998244353;

  public static long Power (long a, long b, long MOD = 1000000007) //i^N
  {
    long res = 1;
    while (b > 0) {
      if ((b & 1) != 0) res = res * a % MOD;
      a = a * a % MOD;
      b >>= 1;
    }
    return res;
  }
  public static long Power2 (long a, long b) //i^N
  {
    long res = 1;
    while (b > 0) {
      if ((b & 1) != 0) res = res * a;
      a = a * a;
      b >>= 1;
    }
    return res;
  }
  public static long GCD (long a, long b) {
    if (a == 0) return b;
    while (b > 0) {
      var r = a % b;
      a = b;
      b = r;
    }
    return a;
  }
  public static long LCM (long a, long b) => (b / GCD (a, b)) * a;
  public static long Comb (long n, long r, int MOD = 1000000007) {
    if (r > n - r) r = n - r;
    long Nume = 1;
    long Deno = 1;

    if (r > n - r) r = n - r;
    for (long i = 1; i <= r; ++i) {
      Deno = (Deno * i) % MOD;
      Nume = Nume * (n - i + 1) % MOD;
    }
    return (Nume * inv (Deno)) % MOD;
  }
  public static long Comb2 (long n, long r) {
    long Nume = 1;
    long Deno = 1;

    if (r > n - r) r = n - r;
    for (long i = 1; i <= r; ++i) {
      Deno *= i;
      Nume *= n - i + 1;
    }
    return Nume / Deno;
  }
  public static long inv (long x, int MOD = 1000000007) {
    return Power (x, MOD - 2, MOD);
  }
}
public static class Utils {
  public static void Swap<T> (ref T A, ref T B) {
    T x = A;
    A = B;
    B = x;
  }
  public static int DigitSum (string N) {

    int ret = 0;
    for (int i = 0; i < N.Length; ++i) ret += N[i] - '0';
    return ret;
  }
  public static string ConvertBase (long N, int K) {
    StringBuilder ret = new StringBuilder ();
    while (N > 0) {
      var r = N % K;
      N /= K;
      ret.Append (r);
    }
    return new string (ret.ToString ().ToCharArray ().Reverse ().ToArray ());
  }
  public static bool NextPermutation<T> (IList<T> lis, Comparison<T> cmp) {
    int n = lis.Count;
    int i = n - 1;
    while (i - 1 >= 0) {
      if (cmp (lis[i - 1], lis[i]) < 0) break;
      --i;
    }
    if (i == 0) return false;
    int j = i;
    while (j + 1 < n) {
      if (cmp (lis[i - 1], lis[j + 1]) > 0) break;
      ++j;
    }
    var _q = lis[j];
    lis[i - 1] = lis[j];
    lis[i - 1] = _q;
    int k = i;
    int l = n - 1;
    while (k < l) {
      var _p = lis[k];
      lis[l] = lis[k];
      lis[l] = _p;

      ++k;
      --l;
    }
    return true;
  }
  public static bool NextPermutation<T> (IList<T> lis) => NextPermutation (lis, Comparer<T>.Default.Compare);
}
public class PriorityQueue<T> {
  List<T> _item;
  public int Count { get { return _item.Count; } }
  bool _isascend { get; set; }
  public T Peek { get { return _item[0]; } }
  Comparison<T> Comp;
  public PriorityQueue (bool IsAscend = true, IEnumerable<T> list = null) : this (Comparer<T>.Default.Compare, IsAscend, list) { }
  public PriorityQueue (Comparison<T> cmp, bool IsAscend = true, IEnumerable<T> list = null) {
    _item = new List<T> ();
    _isascend = IsAscend;
    this.Comp = cmp;
    if (list != null) {
      _item.AddRange (list);
      Build ();
    }
  }

  private int Compare (int i, int j) => (_isascend ? -1 : 1) * Comp (_item[i], _item[j]);
  private void Swap (int i, int j) { var t = _item[i]; _item[i] = _item[j]; _item[j] = t; }
  private int Parent (int i) => (i - 1) >> 1;
  private int Left (int i) => (i << 1) + 1;
  public T Enqueue (T val) {
    int i = _item.Count;
    _item.Add (val);
    while (i > 0) {
      int p = Parent (i);
      if (Compare (i, p) > 0)
        Swap (i, p);
      i = p;
    }
    return val;
  }
  private void Heapify (int index) {
    for (int i = index, j;
      (j = Left (i)) < _item.Count; i = j) {
      if (j != _item.Count - 1 && Compare (j, j + 1) < 0) j++;
      if (Compare (i, j) < 0)
        Swap (i, j);
    }
  }
  public T Dequeue () {
    T val = _item[0];
    _item[0] = _item[_item.Count - 1];
    _item.RemoveAt (_item.Count - 1);
    Heapify (0);
    return val;
  }
  private void Build () {
    for (var i = (_item.Count >> 1) - 1; i >= 0; i--)
      Heapify (i);
  }
  public bool Any () => Count > 0;
}
class Program {
  static void Main (string[] args) {
    var CP = new CP ();
    CP.Solve ();
  }
}
public static class Output {

  public static void Put (string a) => Console.WriteLine (a);
  public static void Put (params object[] i) => Put (string.Join (" ", i));
  // public static void Put<T> (IEnumerable<T> a) => Put (string.Join (" ", a));
  public static void PutV<T> (IEnumerable<T> a) { foreach (var z in a) Put (z); }
  public static void YN (bool i) {
    if (i) Put ("Yes");
    else Put ("No");
  }
}
public class Input {
  public static string Str => Console.ReadLine ();
  public static bool IsTypeEqual<T, U> () => typeof (T).Equals (typeof (U));
  public static T ConvertType<T, U> (U a) => (T) Convert.ChangeType (a, typeof (T));
  public static T Cast<T> (string s) {
    if (IsTypeEqual<T, int> ()) return ConvertType<T, int> (int.Parse (s));
    else if (IsTypeEqual<T, long> ()) return ConvertType<T, long> (long.Parse (s));
    else if (IsTypeEqual<T, double> ()) return ConvertType<T, double> (double.Parse (s));
    else if (IsTypeEqual<T, char> ()) return ConvertType<T, char> (char.Parse (s));
    else return ConvertType<T, string> (s);
  }
  public static T[] Castarr<T> (string[] s) {

    var ret = new T[s.Length];
    int i = 0;
    if (IsTypeEqual<T, char> ()) {
      var list = new List<T> ();
      foreach (var t in s) {
        foreach (var u in t) {
          list.Add (ConvertType<T, char> (char.Parse (u.ToString ())));
        }
      }
      return list.ToArray ();
    }
    foreach (var t in s) {
      if (IsTypeEqual<T, int> ()) ret[i++] = ConvertType<T, int> (int.Parse (t));
      else if (IsTypeEqual<T, long> ()) ret[i++] = ConvertType<T, long> (long.Parse (t));
      else if (IsTypeEqual<T, double> ()) ret[i++] = ConvertType<T, double> (double.Parse (t));
      else ret[i++] = ConvertType<T, string> (t);
    }
    return ret;
  }
  Queue<string> q = new Queue<string> ();
  void next () { var ss = Str.Split (' '); foreach (var item in ss) q.Enqueue (item); }
  public T cin<T> () { if (!q.Any ()) next (); return Cast<T> (q.Dequeue ()); }
  public void mul<T> (out T t) { t = cin<T> (); }
  public void mul<T, U> (out T t, out U u) { t = cin<T> (); u = cin<U> (); }
  public void mul<T, U, V> (out T t, out U u, out V v) { t = cin<T> (); u = cin<U> (); v = cin<V> (); }
  public void mul<T, U, V, W> (out T t, out U u, out V v, out W w) { t = cin<T> (); u = cin<U> (); v = cin<V> (); w = cin<W> (); }
  public void mul<T, U, V, W, X> (out T t, out U u, out V v, out W w, out X x) { t = cin<T> (); u = cin<U> (); v = cin<V> (); w = cin<W> (); x = cin<X> (); }
  public void mul<T, U, V, W, X, Y> (out T t, out U u, out V v, out W w, out X x, out Y y) { t = cin<T> (); u = cin<U> (); v = cin<V> (); w = cin<W> (); x = cin<X> (); y = cin<Y> (); }
  public void mul<T, U, V, W, X, Y, Z> (out T t, out U u, out V v, out W w, out X x, out Y y, out Z z) { t = cin<T> (); u = cin<U> (); v = cin<V> (); w = cin<W> (); x = cin<X> (); y = cin<Y> (); z = cin<Z> (); }
  public T[] cinarr<T> () { return Castarr<T> (Str.Split (' ')); }
}