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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.io.*;
import java.util.*;

public class Main {
    FastScanner in;
    PrintWriter out;

    boolean ok(int[] a, int mod, int maxSum) {
        int n = a.length;
        int maxCntLeft;
        {
            int l = 0, r = n / 2 + 1;
            while (r - l > 1) {
                int m = (l + r) >> 1;
                boolean ok = true;
                for (int i = 0; i < m; i++) {
                    if (a[i] + a[m * 2 - 1 - i] > maxSum) {
                        ok = false;
                        break;
                    }
                }
                if (ok) {
                    l = m;
                } else {
                    r = m;
                }
            }
            maxCntLeft = l;
        }
        int maxCntOver;
        {
            int l = 0, r = n / 2 + 1;
            while (r - l > 1) {
                int m = (l + r) >> 1;
                boolean ok = true;
                for (int i = 0; i < m; i++) {
                    if (a[n - i - 1] + a[n - m * 2 + i] < mod) {
                        ok = false;
                        break;
                    }
                }
                if (!ok) {
                    r = m;
                } else {
                    l = m;
                }
            }
            maxCntOver = l;
        }
        int minCnt;
        {
            int l = 0, r = n / 2 + 1;
            while (r - l > 1) {
                int m = (l + r) >> 1;
                boolean ok = true;
                for (int i = 0; i < m; i++) {
                    if (a[n - i - 1] + a[n - m * 2 + i] - mod > maxSum) {
                        ok = false;
                        break;
                    }
                }
                if (ok) {
                    r = m;
                } else {
                    l = m;
                }
            }
            minCnt = r;
        }
        if (minCnt > maxCntOver) {
            return false;
        }
        if (maxCntOver + maxCntLeft >= n / 2) {
            return true;
        }
        return false;
    }

    void solve() {
        int n = in.nextInt();
        int m = in.nextInt();
        int[] a = new int[n * 2];
        for (int i = 0; i < a.length; ++i) {
            a[i] = in.nextInt();
        }
        Arrays.sort(a);
//        System.err.println("?? " + ok(a, m, 5));
        int lAns = -1, rAns = m;
        while (rAns - lAns > 1) {
            int ans = (lAns + rAns) >> 1;
            if (ok(a, m, ans)) {
                rAns = ans;
            } else {
                lAns = ans;
            }
        }
        out.println(rAns);
    }

    void run() {
        try {
            in = new FastScanner(new File("Main.in"));
            out = new PrintWriter(new File("Main.out"));

            solve();

            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    void runIO() {

        in = new FastScanner(System.in);
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        public FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }
    }

    public static void main(String[] args) {
        new Main().runIO();
    }
}