Problem: Devu wants to decorate his garden with flowers. He has purchased n boxes, where the i-th box contains fi flowers. All flowers in a single box are of the same color (hence they are indistinguishable). Also, no two boxes have flowers of the same color.

Now Devu wants to select exactly s flowers from the boxes to decorate his garden. Devu would like to know, in how many different ways can he select the flowers from each box? Since this number may be very large, he asks you to find the number modulo (109 + 7). 

Devu considers two ways different if there is at least one box from which different number of flowers are selected in these two ways.

Input

The first line of input contains two space-separated integers n and s (1 ≤ n ≤ 20, 0 ≤ s ≤ 1014).

The second line contains n space-separated integers f1, f2, ... fn (0 ≤ fi ≤ 1012).

Output

Output a single integer — the number of ways in which Devu can select the flowers modulo (109 + 7).

Examples

Input

2 3
1 3


Output

2


Input

2 4
2 2


Output

1


Input

3 5
1 3 2


Output

3

Note

Sample 1. There are two ways of selecting 3 flowers: {1, 2} and {0, 3}.

Sample 2. There is only one way of selecting 4 flowers: {2, 2}.

Sample 3. There are three ways of selecting 5 flowers: {1, 2, 2}, {0, 3, 2}, and {1, 3, 1}.

Solution (in JAVA):

Solution:
/**
 * author: derrick20
 * created: 12/7/20 2:45 PM
 */
import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class DevuAndFlowers {
    public static void main(String[] args) {
        FastScanner sc = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);

        int N = sc.nextInt();
        long S = sc.nextLong();
        long[] f = sc.nextLongs(N);

        /*
        long[] a = polyExp(new long[]{1, mod - 1}, N);
        long[][] m = new long[a.length - 1][a.length - 1];
        for (int i = 0; i < a.length - 1; i++) {
            m[0][i] = mod - a[i + 1];
            if (i > 0) {
                m[i][i - 1] = 1;
            }
        }
        mPow = new long[47][m.length][m.length];
        mPow[1] = m;
        for (int k = 2; k < 47; k++) {
            mPow[k] = matrixMult(mPow[k - 1], mPow[k - 1]);
        }
         */

        HashMap<Long, Long> polynomial = new HashMap<>();
        for (int mask = 0; mask < 1 << N; mask++) {
            long coeff = 1;
            long exp = 0;
            for (int k = 0; k < N; k++) {
                if (((1 << k) & mask) > 0) {
                    coeff *= -1;
                    exp += f[k] + 1;
                }
            }
            polynomial.merge(exp, coeff, Long::sum);
        }
//        System.out.println(polynomial.size());
        long ans = 0;
        fact = new long[N];
        fact[0] = 1;
        for (int i = 1; i < N; i++) {
            fact[i] = (long) i * (fact[i - 1]) % mod;
        }
        for (long exp : polynomial.keySet()) {
//            System.out.println("Solving " + exp);
            if (exp <= S) {
                long coeff = polynomial.get(exp);
                ASSERT(coeff <= 184756); // at most 20 choose 10
                if (coeff < 0) coeff += mod;
                long compl = S - exp;
//                System.out.println("Need to get " + compl % mod);
                // We want (n + k - 1) choose n, where we have n - 1 partitions,
                // and k balls, k = compl, n ~ 20. So this is pretty efficient!
                long complCoeff = choose(N + compl - 1, N - 1);
//                System.out.println((N + compl - 1) + " " + (N - 1) + " -> " + complCoeff);

//                long complCoeff = matrixFastExpo(m, compl)[0][0];
//                System.out.println("Ways to get " + compl + " = " + complCoeff);
                long amt = (coeff * complCoeff) % mod;
                ans = (ans + amt) % mod;
            }
        }
        out.println(ans);
        out.close();
    }

    static long mod = (long) 1e9 + 7;
    static long[][][] mPow;
    static long[] fact;

    static long choose(long n, long k) {
        ASSERT(k < mod);
        n %= mod;
        long ans = fastExpo(fact[(int) k], mod - 2);
        while (k > 0) {
            ans = (ans * n) % mod;
            n--; k--;
        }
        return ans;
    }

    static long fastExpo(long x, long k) {
        long ans = 1;
        while (k > 0) {
            if ((k & 1) > 0) {
                ans = (ans * x) % mod;
            }
            x = (x * x) % mod;
            k >>= 1;
        }
        return ans;
    }

    static long[] polyMult(long[] a, long[] b) {
        long[] res = new long[a.length + b.length - 1];
        for (int p = 0; p < res.length; p++) {
            for (int i = 0; i < a.length; i++) {
                int j = p - i;
                if (j < 0 || j >= b.length) continue;
                long amt = (a[i] * b[j]) % mod;
                res[p] = (res[p] + amt) % mod;
            }
        }
        return res;
    }

    static long[] polyExp(long[] x, long k) {
        long[] ans = {1};
        while (k > 0) {
            if ((k & 1) == 1) {
                ans = polyMult(ans, x);
            }
            x = polyMult(x, x);
            k >>= 1;
        }
        return ans;
    }

    static long[][] matrixMult(long[][] a, long[][] b) {
        long[][] res = new long[a.length][b[0].length];
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < b[0].length; j++) {
                for (int k = 0; k < a[i].length; k++) {
                    long amt = (a[i][k] * b[k][j]) % mod;
                    res[i][j] = (res[i][j] + amt) % mod;
                }
            }
        }
        return res;
    }

    static long[][] identity(int n) {
        long[][] res = new long[n][n];
        for (int i = 0; i < n; i++) {
            res[i][i] = 1;
        }
        return res;
    }

    static long[][] matrixFastExpo(long[][] x, long k) {
        long[][] ans = identity(x.length);
        int ptr = 1;
        while (k > 0) {
            if ((k & 1) == 1) {
                ans = matrixMult(ans, mPow[ptr]);
            }
            ptr++;
            k >>= 1;
        }
        return ans;
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        private char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public int[] nextInts(int N) {
            int[] res = new int[N];
            for (int i = 0; i < N; i++) {
                res[i] = (int) nextLong();
            }
            return res;
        }

        public long[] nextLongs(int N) {
            long[] res = new long[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextLong();
            }
            return res;
        }

        public long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        public double nextDouble() {
            double cur = nextLong();
            return c != '.' ? cur : cur + nextLong() / cnt;
        }

        public double[] nextDoubles(int N) {
            double[] res = new double[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextDouble();
            }
            return res;
        }

        public String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }
    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }
    static void ASSERT(boolean assertion) {
        if (!assertion) throw new AssertionError();
    }
}