Problem:
Score : 1200 points

Problem Statement

Let M be a positive integer.

You are given 2 N integers a_1, a_2, \ldots, a_{2 N}, where 0 \leq a_i < M for each i.

Consider dividing the 2 N integers into N pairs.
Here, each integer must belong to exactly one pair.

We define the ugliness of a pair (x, y) as (x + y) \mod M.
Let Z be the largest ugliness of the N pairs. Find the minimum possible value of Z.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq M \leq 10^9

0 \leq a_i < M

Input

Input is given from Standard Input in the following format:

N M
a_1 a_2 \cdots a_{2N}

Output

Print the minimum possible value of Z, where Z is the largest ugliness of the N pairs.

Sample Input 1

3 10
0 2 3 4 5 9

Sample Output 1

5

One solution is to form pairs (0, 5), (2, 3) and (4, 9), with ugliness 5, 5 and 3, respectively.

Sample Input 2

2 10
1 9 1 9

Sample Output 2

0

Pairs (1, 9) and (1, 9) should be formed, with ugliness both 0.

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public class SArray<T> 
{
    public T[] Values;

    public SArray(int size)
    {
        Values = new T[size];
    }

    public SArray(T[] values)
    {
        Values = values;
    }

    public override string ToString()
    {
        return $"{ string.Join(", ", Values) }";
    }

    public override bool Equals(object obj)
    {
        if (obj.GetType() != this.GetType())
            return false;
        var o = (SArray<T>)obj;
        if (Values.Length != o.Values.Length)
            return false;
        for (int i = 0; i < Values.Length; i++)
            if (!Values[i].Equals(o.Values[i]))
                return false;
        return true;
    }

    public override int GetHashCode()
    {
        int code = 1;
        for (int i = 0; i < Values.Length; i++)
            code = code * 17 + Values[i].GetHashCode();
        return code;
    }

    public SArray<T> Clone()
    {
        return new SArray<T>((T[])Values.Clone());
    }
}

class Program
{
    static int N, M;
    static void Main(string[] args)
    {
        var l1 = Console.ReadLine().Split(' ').Select(n => int.Parse(n)).ToArray();
        N = l1[0];
        M = l1[1];
        var l2 = Console.ReadLine().Split(' ').Select(n => int.Parse(n)).ToArray();

        dic = new Dictionary<int, int>();
        foreach (var l in l2)
        {
            if (!dic.ContainsKey(l))
                dic[l] = 0;
            dic[l]++;
        }

        Digits = dic.Keys.ToArray();
        Numbers = dic.Values.ToArray();

        dp[new SArray<int>(new int[Numbers.Length])] = 0;

        var ans = F(new SArray<int>(Numbers));

        Console.WriteLine(ans);
    }

    static Dictionary<int, int> dic;

    static int[] Digits;
    static int[] Numbers;

    static Dictionary<SArray<int>, int> dp = new Dictionary<SArray<int>, int>();

    static int F(SArray<int> array)
    {
        if (dp.ContainsKey(array))
            return dp[array];

        var minz = int.MaxValue;
        for (int i = 0; i < array.Values.Length; i++)
        {
            if (array.Values[i] == 0)
                continue;
            for (int j = i; j < array.Values.Length; j++)
            {
                if (array.Values[j] == 0)
                    continue;
                if (j == i && array.Values[j] < 2)
                    continue;
                var marray = array.Clone();
                marray.Values[i]--;
                marray.Values[j]--;

                var thisZ = (Digits[i] + Digits[j]) % M;
                var prevZ = F(marray);
                var val = Math.Max(thisZ, prevZ);
                if (minz > val)
                    minz = val;
            }
        }

        return dp[array] = minz;
    }
}