import std.stdio, std.conv, std.string;
import std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

int DEBUG_LEVEL = 0;
void print()(){ writeln(""); }
void print(T, A ...)(T t, lazy A a){ write(t), print(a); }
void print(int level, T, A ...)(T t, lazy A a){ if(level <= DEBUG_LEVEL) print(t, a); }

void main(string[] args){
	if(args.length > 1 && args[1] == "-debug"){
		if(args.length > 2 && args[2].isNumeric) DEBUG_LEVEL = args[2].to!int;
		else DEBUG_LEVEL = 1;
	}
	
	int n = read.to!int;
	int k = read.to!int;
	
	long[] vs;
	foreach(i; 0 .. n) vs ~= read.to!long;
	print!1("vs:", vs);
	
	long[][][] xs = new long[][][](k + 1, k + 1, 0);
	foreach(i; 0 .. k + 1) foreach(j; 0 .. k + 1 - i){
		if(i + j > n) continue;
		if(j == 0){
			if(i == 0) xs[i][j] = [];
			else xs[i][j] = xs[i - 1][j] ~ vs[i - 1];
		}
		else xs[i][j] = xs[i][j - 1] ~ vs[n - j];
		print!1("i:", i, " j:", j, " x:", xs[i][j]);
	}
	print!1("xs:", xs);
	
	long[] sum = [0];
	foreach(v; vs) sum ~= sum[$ - 1] + v;
	print!1("sum:", sum);
	
	long[][] ys = new long[][](k + 1, k + 1);
	foreach(i; 0 .. k + 1) foreach(j; 0 .. k + 1 - i){
		if(i + j > n) continue;
		ys[i][j] = sum[i] + sum[n] - sum[n - j];
		xs[i][j].sort();
		foreach(t, x; xs[i][j]) if(t < k - i - j) if(x < 0) ys[i][j] -= x;
	}
	print!1("ys:", ys);
	
	long ans = long.min;
	foreach(i; 0 .. k + 1) foreach(j; 0 .. k + 1 - i){
		if(i + j > n) continue;
		print!1("i:", i, " j:", j, " y:", ys[i][j]);
		ans = max(ans, ys[i][j]);
	}
	
	ans.writeln;
	
}


/*
いらない宝石を返す操作は、必ず最後にまとめて行うものとしてよい
その場合左とか右は関係ないのでゴミ箱に捨てると考えてよい
途中でも、いらない宝石はゴミ箱に捨てるものとして考えてよい

xs[i][j] = i回左から取り、j回右から取る場合の手持ち
	= vs[0 .. i] ~ vs[n - j .. n]
	= xs[i] ~ vs[n - j]

ys[i][j] = 
	= sum[i] + sum[n] - sum[n - j] - take(k - i - j)

求めるものは max(i, j) ys[i][j]


*/
