Problem:
Coin Combination Problem

You have 4 bags A, B, C and D each of which includes N coins (there are totally 4N coins). Values of the coins in each bag are ai, bi, ci and di respectively.

Find the number of combinations that result when you choose one coin from each bag (totally 4 coins) in such a way that the total value of the coins is V. You should distinguish the coins in a bag.

Constraints

1 ≤ N ≤ 1000

1 ≤ ai, bi, ci, di ≤ 1016

1 ≤ V ≤ 1016

All input values are given in integers

Input

The input is given in the following format.

N V
a1 a2 ... aN
b1 b2 ... bN
c1 c2 ... cN
d1 d2 ... dN

Output

Print the number of combinations in a line.

Sample Input 1

3 14
3 1 2
4 8 2
1 2 3
7 3 2

Sample Output 1

9

Sample Input 2

5 4
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

Sample Output 2

625

Solution in C# (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Pair = System.Collections.Generic.KeyValuePair<int, int>;

// hanbun-zenrekkyo
class Program
{
    static void Main()
    {
        var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        new Program().solve();
        Console.Out.Flush();
    }
    Scanner cin = new Scanner();

    int N;
    long V;
    void solve()
    {
        N = cin.nextint;
        V = cin.nextlong;

        var A = cin.scanlong;
        var B = cin.scanlong;
        var C = cin.scanlong;
        var D = cin.scanlong;

        var T = new List<long>();
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                var m = A[i] + B[j];
                if (m > V - 2) continue;
                T.Add(m);
            }
        }
        var S = T.ToArray();
        Array.Sort(S);

        long ans = 0;
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                var m = C[i] + D[j];
                if (m > V - S[0]) continue;
                ans += UpperBound(S, V - m) - LowerBound(S, V - m);
            }
        }

        Console.WriteLine(ans);
    }


    int UpperBound(long[] arr, long val)
    {
        int low = 0, high = arr.Length;
        int mid;

        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid] <= val) low = mid + 1;
            else high = mid;
        }
        return low;
    }

    int LowerBound(long[] arr, long val)
    {
        int low = 0, high = arr.Length;
        int mid;

        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid] < val) low = mid + 1;
            else high = mid;
        }
        return low;
    }

}


class Scanner
{
    string[] s; int i;
    char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan { get { return Console.ReadLine().Split(); } }
    public int[] scanint { get { return Array.ConvertAll(scan, int.Parse); } }
    public long[] scanlong { get { return Array.ConvertAll(scan, long.Parse); } }
    public double[] scandouble { get { return Array.ConvertAll(scan, double.Parse); } }
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = Console.ReadLine();
            while (st == "") st = Console.ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint { get { return int.Parse(next); } }
    public long nextlong { get { return long.Parse(next); } }
    public double nextdouble { get { return double.Parse(next); } }
}