#include <bits/stdc++.h>
#include <math.h>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rrep(i, n) for(int i = 0; i <= (n); i++)
using namespace std;
typedef long long ll;
const int MOD = 1000000007;
const ll INF = 1LL<<60;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using Graph = vector<vector<int>>;

typedef pair<int, int> P;
typedef priority_queue<int, vector<int>, greater<int>> PQ;

int main(){
 int N, K; cin >> N >> K;
    int ans = 0;
    deque<int> deq;
    vector<int> v(N,0);
    rep(i,N){
        cin >> v[i];
    }
    // 左から取る個数
    for (int l = 0; l <= K; l++){
        // 右から取る個数
        for (int r = 0; r <= K; r++){
            // 取る回数がKを越した場合はNG
            if (l + r > K) continue;
            int d = K - l - r;
            priority_queue<int, vector<int>, greater<int>> tmp;
            // 左から取る
            rep(i,l){
                // dequeの右端に達した場合
                if (i >= N) break;
                tmp.push(v[i]);
            }
            // 右から取る
            rep(i,r){
                int index = N-1-i;
                // dequeの左端もしくはすでに左から取られている場合
                if (index < 0 || index <= l) break;
                tmp.push(v[index]);
            }
            // 手から宝石をつめる
            rep(i,d){
                // 手に持っていない場合
                if (tmp.empty()) break;
                // 価値は正の場合はつめない
                if (tmp.top() >= 0) break;
                tmp.pop();
            }

            int now = 0;
            while (!tmp.empty()){
                now += tmp.top(); tmp.pop();
            }

            ans = max(now, ans);
        }
    }


    cout << ans << endl;
}
#include <iostream>
#include <iomanip>
#include <map>
#include <list>
#include <set>
#include <vector>
#include <utility>
#include <algorithm>
#include <queue>
#include <cstdint>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

constexpr ll inf = INT64_MAX / 4;
constexpr double pi = asin(1) * 2;
constexpr ll mod = 1000000007;

template<class T>
class set2 : public set<T> {
private:
    typename set<T>::iterator back_itr() {
        auto e = this->end();
        e--;
        return e;
    }

public:
    T front() {
        if (this->empty()) throw;
        return *this->begin();
    }

    T back() {
        if (this->empty()) throw;
        return *this->back_itr();
    }

    void erase_front() {
        if (!this->empty()) this->erase(this->begin());
    }

    void erase_back() {
        if (!this->empty()) this->erase(this->back_itr());
    }
};

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n), b(m);
    for (auto &e:a) cin >> e;
    for (auto &e:b) cin >> e;
    sort(a.begin(), a.end());
    sort(b.begin(), b.end());
    bool f = true;
    for (int i = 1; i < n; i++) if (a[i] == a[i - 1]) f = false;
    for (int i = 1; i < m; i++) if (b[i] == b[i - 1]) f = false;
    if (!f) {
        cout << 0 << endl;
        return 0;
    }
    auto in_r = [](vector<int> r, int e) { return binary_search(r.begin(), r.end(), e); };
    auto in_a = [&in_r, &a](int e) { return in_r(a, e); };
    auto in_b = [&in_r, &b](int e) { return in_r(b, e); };
    ll r = 1;
    for (int i = n * m; i > 0; i--) {
        if (in_a(i) && in_b(i)) {
            r *= 1;
        } else if (in_a(i)) {
            r *= b.end() - lower_bound(b.begin(), b.end(), i);
        } else if (in_b(i)) {
            r *= a.end() - lower_bound(a.begin(), a.end(), i);
        } else {
            r *= (a.end() - lower_bound(a.begin(), a.end(), i)) * (b.end() - lower_bound(b.begin(), b.end(), i)) -
                 (n * m - i);
        }
        r %= mod;
    }
    cout << r << endl;
}
