//package round258;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		long s = nl();
		long[] a = new long[n];
		for(int i = 0;i < n;i++)a[i] = nl();
		int mod = 1000000007;
		long ret = 0;
		for(int i = 0;i < 1<<n;i++){ // used
			long sum = 0;
			for(int j = 0;j < n;j++){
				if(i<<31-j<0)sum += a[j]+1;
			}
			long rem = s-sum;
			if(rem < 0)continue;
			long val = 1;
			long N = rem+n-1, R = n-1;
			for(int j = 1;j <= R;j++){
				val = val * ((N-j+1)%mod) % mod * invl(j, mod) % mod;
			}
			if(Integer.bitCount(i) % 2 == 0){
				ret += val;
			}else{
				ret += mod-val;
			}
		}
		out.println(ret%mod);
	}

	public static long invl(long a, long mod) {
		long b = mod;
		long p = 1, q = 0;
		while (b > 0){
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.util.Scanner;

public class cf258e {
static int mod=1000000007;
static long a[];
static long b[];
private static long gao(long x,int r)
{
    long y=1;
    while(r>0)
    {
        if(r%2!=0)
        {
            y=y*x%mod;
            r--;
        }
        else
        {
            x=x*x%mod;
            r/=2;
        }
    }
    return y;
}
public static void main(String[] args) {
    Scanner scanner=new Scanner(System.in);
    int n=scanner.nextInt();
    long s=scanner.nextLong();
    a=new long[50];
    for(int i=1;i<=n;i++)
    {
        a[i]=scanner.nextLong();
    }
    b=new long [50];
    for(int i=1;i<=40;i++)
    {
        b[i]=gao(i,mod-2);
    }
    long sum=0;
    for(int i=0;i<(1<<n);i++)
    {
        int p=0;
        long ns=s;
        for(int j=0;j<n;j++)
        {
            if(((i>>j)&1)>0)
            {
                p++;
                ns-=(a[j+1]+1);
            }
        }
        if(ns<0)
            continue;
        long y=1;
        for(int k=1;k<=n-1;k++)
        {
            y=y*b[k]%mod;
            y=(y*((ns+n-k)%mod))%mod;
        }
        if(p%2==0)
        {
            sum=(sum+y)%mod;
        }
        else {
            sum=(sum-y+mod)%mod;
        }

    }
    System.out.println(sum);

}
}

import java.io.PrintWriter;
import java.util.Scanner;

public class E451 {

	static class Solver {

		int N;
		long S, MOD = 1_000_000_007, cookie;
		long[] boxes;

		long modPow(long k, long exp) {
			if (exp == 0)
				return 1;
			if (exp == 1)
				return k;
			long hs = (k * k) % MOD;
			if ((exp & 1) == 1)
				return (k * modPow(hs, exp / 2)) % MOD;
			return modPow(hs, exp / 2) % MOD;
		}

		long modInv(long k) {
			return modPow(k, MOD - 2);
		}

		void bakeACookie() {
			long h = 1;
			for (int i = 2; i < N; i++) {
				h *= i;
				h %= MOD;
			}
			cookie = modInv(h);
		}

		long chooseMod(long n, long k) {
			if (n < k)
				return 0;
			if (n == k)
				return 1;
			long top = 1;
			for (int i = 0; i < k; i++) {
				top *= (n - i) % MOD;
				top %= MOD;
			}
			// if (Math.random() < 0.00001)
			// System.out.println(n + " " + k + " --> " + top + ", " + modInv(k) + " --> " +
			// ((top * modInv(k)) % MOD));
			return (top * cookie) % MOD;

		}

		// @SuppressWarnings("unchecked")
		public void solve(int testNumber, Scanner s, PrintWriter out) {

			N = s.nextInt();
			bakeACookie();
			S = s.nextLong();
			boxes = new long[N];
			for (int i = 0; i < N; i++)
				boxes[i] = s.nextLong();

			long ways = 0;
			for (int i = 0; i < 1 << N; i++) {
				// overcounting on bits
				long over = 0;
				for (int c = 0; c < N; c++) {
					if ((i & (1 << c)) > 0)
						over += boxes[c] + 1;
				}
				if ((Integer.bitCount(i) & 1) == 1)
					ways -= chooseMod(S - over + N - 1, N - 1);
				else
					ways += chooseMod(S - over + N - 1, N - 1);
				// if (Math.random() < 0.0001)
				// out.printf("%d choose %d = %d\n", S - over + N - 1, N - 1, chooseMod(S - over
				// + N - 1, N - 1));

			}

			out.println(Math.floorMod(ways, MOD));

		}

	}

	public static void main(String[] args) {

//		 Scanner s = new Scanner("2 3\n" + "1 3\n");
//		 Scanner s = new Scanner("2 4\n" + "2 2\n");
//		 Scanner s = new Scanner("3 5\n" + "1 3 2\n");
//		Scanner s = new Scanner("20 4385085334307\n"
//				+ "273634411136 208521328637 450482376435 844118010709 197241285878 472126475472 2414038897 672334205413 809269727018 409013884362 739986692075 953956651947 462216461906 388007176838 245504550965 527140291750 632844435887 550532123833 757200390348 944901802640\n");
		 Scanner s = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		Solver solver = new Solver();
		solver.solve(1, s, out);

		out.close();
		s.close();

	}
}

import java.util.ArrayList;
import java.util.Scanner;

public class e {
	static final long MOD = (long)1e9+7;
	static int n;
	static long s;
	static long[] fs;
	static long[] invs;
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		invs = new long[25];
		invs[1] = 1;
		for (int i = 2; i < invs.length; ++i)
			invs[i] = (MOD - (MOD / i) * invs[((int) (MOD % i))] % MOD) % MOD;
		n = in.nextInt();
		s = in.nextLong();
		fs = new long[n];
		for(int i=0;i<n;i++)
			fs[i] = in.nextLong();
		long ans = genList(0, 1, 0);
		if(ans < 0) ans += MOD;
		System.out.println(ans);
	}
	static long genList(int idx, long c, long pow) {
		if(idx == n) {
			pow = s - pow;
			if(pow < 0)
				return 0;
			pow = pow % MOD;
			long choose = 1;
			for(int i=0;i<n-1;i++) {
				choose *= pow+n-1-i;
				choose %= MOD;
				choose *= invs[i+1];
				choose %= MOD;
			}
			return (c * choose) % MOD;
		}
		long ans = 0;
		ans += genList(idx+1, c, pow);
		ans += genList(idx+1, -c, pow+fs[idx]+1);
		return ans % MOD;
	}
}

import java.util.ArrayList;
import java.util.Scanner;

public class e {
	static final long MOD = (long)1e9+7;
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		long[] invs = new long[25];
		invs[1] = 1;
		for (int i = 2; i < invs.length; ++i)
			invs[i] = (MOD - (MOD / i) * invs[((int) (MOD % i))] % MOD) % MOD;
		int n = in.nextInt();
		long s = in.nextLong();
		long[] fs = new long[n];
		for(int i=0;i<n;i++)
			fs[i] = in.nextLong();
		ArrayList<Term> ans = new ArrayList<>();
		ArrayList<ArrayList<Term>> eqList = new ArrayList<>();
		for(int i=0;i<n;i++) {
			ArrayList<Term> cur = new ArrayList<>();
			cur.add(new Term(1,0));
			cur.add(new Term(-1,fs[i]+1));
			eqList.add(cur);
		}
		multiply(ans, eqList, 0, new Term(1, 0));
		long sum = 0;
		for(Term t : ans) {
			long pow = s - t.pow;
			if(pow < 0) continue;
			long choose = 1;
			for(int i=0;i<n-1;i++) {
				choose *= (pow+n-1-i) % MOD;
				choose %= MOD;
				choose *= invs[i+1];
				choose %= MOD;
			}
			sum += t.c * choose;
			sum %= MOD;
		}
		if(sum < 0) sum += MOD;
		System.out.println(sum);
	}
	static void multiply(ArrayList<Term> ans, ArrayList<ArrayList<Term>> list, int idx, Term current) {
		if(idx == list.size()) {
			ans.add(current);
			return;
		}
		for(Term t : list.get(idx)) {
			Term nt = new Term((t.c * current.c) % MOD, t.pow + current.pow);
			multiply(ans, list, idx+1, nt);
		}
	}
	static class Term {
		long c;
		long pow;
		public Term(long c, long pow) {
			this.c = c;
			this.pow = pow;
		}
	}
}

import java.util.ArrayList;
import java.util.Scanner;

public class e {
	static final long MOD = (long)1e9+7;
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		long[] invs = new long[25];
		invs[1] = 1;
		for (int i = 2; i < invs.length; ++i)
			invs[i] = (MOD - (MOD / i) * invs[((int) (MOD % i))] % MOD) % MOD;
		int n = in.nextInt();
		long s = in.nextLong();
		long[] fs = new long[n];
		for(int i=0;i<n;i++)
			fs[i] = in.nextLong();
		ArrayList<Term> ans = new ArrayList<>();
		ans.add(new Term(1, 0));
		for(int i=0;i<n;i++) {
			ArrayList<Term> cur = new ArrayList<>();
			cur.add(new Term(1,0));
			cur.add(new Term(-1,fs[i]+1));
			ans = multiply(ans, cur);
		}
		long sum = 0;
		for(Term t : ans) {
			long pow = s - t.pow;
			if(pow < 0) continue;
			long choose = 1;
			for(int i=0;i<n-1;i++) {
				choose *= (pow+n-1-i) % MOD;
				choose %= MOD;
				choose *= invs[i+1];
				choose %= MOD;
			}
			sum += t.c * choose;
			sum %= MOD;
		}
		if(sum < 0) sum += MOD;
		System.out.println(sum);
	}
	static ArrayList<Term> multiply(ArrayList<Term> eq1, ArrayList<Term> eq2) {
		ArrayList<Term> ans = new ArrayList<>();
		for(Term t1 : eq1)
			for(Term t2 : eq2)
				ans.add(new Term((t1.c * t2.c) % MOD, t1.pow + t2.pow));
		return ans;
	}
	static class Term {
		long c;
		long pow;
		public Term(long c, long pow) {
			this.c = c;
			this.pow = pow;
		}
	}
}

import java.util.ArrayList;
import java.util.Scanner;

public class e {
	static final long MOD = (long)1e9+7;
	static int n;
	static long s;
	static long[] fs;
	static long[] invs;
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		invs = new long[25];
		invs[1] = 1;
		for (int i = 2; i < invs.length; ++i)
			invs[i] = (MOD - (MOD / i) * invs[((int) (MOD % i))] % MOD) % MOD;
		n = in.nextInt();
		s = in.nextLong();
		fs = new long[n];
		for(int i=0;i<n;i++)
			fs[i] = in.nextLong();
		long ans = genList(0, 1, 0);
		if(ans < 0) ans += MOD;
		System.out.println(ans);
	}
	static long genList(int idx, long c, long pow) {
		if(idx == n) {
			pow = s - pow;
			if(pow < 0)
				return 0;
			long choose = 1;
			for(int i=0;i<n-1;i++) {
				choose *= (pow+n-1-i) % MOD;
				choose %= MOD;
				choose *= invs[i+1];
				choose %= MOD;
			}
			return (c * choose) % MOD;
		}
		long ans = 0;
		ans += genList(idx+1, c, pow);
		ans += genList(idx+1, -c, pow+fs[idx]+1);
		return ans % MOD;
	}
}

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

public class CODEFORCES {
	private InputStream is;
	private PrintWriter out;

	long fact[] = new long[21];
	long mod = (long) 1e9 + 7;
	long fi[] = new long[21];

	long pow(long a, long b) {
		long ans = 1;
		if (a == 0)
			return 0;
		while (b > 0) {
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	long ni;

	long nCr(long a) {
		long ans = 1;
		long mi = Math.min(a, ni - 1);
		long ma = mi;
		while (mi-- > 0)
			ans = (ans * ((ni + (--a)) % mod)) % mod;
		return (ans * fi[(int) ma]) % mod;
	}

	void solve() {
		int n = ni();
		ni = n;
		long s = nl();
		long val[] = new long[n];
		for (int i = 0; i < n; i++)
			val[i] = nl();
		fact[0] = 1;
		fi[0] = pow(fact[0], mod - 2);
		for (int i = 1; i <= 20; i++) {
			fact[i] = (fact[i - 1] * i) % mod;
			fi[i] = pow(fact[i], mod - 2);
		}
		HashMap<Long, Long> map = new HashMap<Long, Long>();
		map.put((long) 0, (long) 1);
		for (int i = 0; i < n; i++) {
			HashMap<Long, Long> tmp = new HashMap<Long, Long>();
			for (long p : map.keySet())
				tmp.put(p, map.get(p));
			for (long p : map.keySet()) {
				long add = p + val[i] + 1;
				if (add > s)
					continue;
				if (tmp.containsKey(add))
					tmp.put(add, (mod + tmp.get(add) - map.get(p)) % mod);
				else
					tmp.put(add, mod - map.get(p));
			}
			map = tmp;
		}
		long ans = 0;
		for (long a : map.keySet()) {
			// out.println(a + " " + map.get(a));
			ans = (ans + nCr(s - a) * map.get(a) % mod) % mod;
		}
		out.println(ans);
	}

	void soln() throws Exception {
		is = System.in;
		out = new PrintWriter(System.out);
		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new CODEFORCES().soln();
	}

	// To Get Input
	// Some Buffer Methods
	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n && !(isSpaceChar(b))) {
			buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

	private void tr(Object... o) {
		if (!oj)
			System.out.println(Arrays.deepToString(o));
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	public static final long MOD = (long) (1e9 + 7);
	public static long[] fac, inv, a;
	public static final int MAX = 20;
	public static long M;
	public static int N;

	public static void main(String[] args) throws IOException {
		fac = new long[MAX + 1];
		inv = new long[MAX + 1];
		fac[0] = 1;
		inv[0] = 1;
		for (int i = 1; i <= MAX; i++) {
			fac[i] = (fac[i - 1] * i) % MOD;
			inv[i] = qpow(fac[i], MOD - 2, MOD);
		}
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(f.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Long.parseLong(st.nextToken());
		a = new long[N];
		st = new StringTokenizer(f.readLine());
		for (int i = 0; i < N; i++) {
			a[i] = Long.parseLong(st.nextToken());
		}
		System.out.println(solve());
	}

	public static long solve() {
		long res = C(N + M - 1, N - 1);
		for (int x = 1; x < 1 << N; x++) {
			long t = N + M;
			int p = 0;
			for (int i = 0; i < N; i++) {
				if (((x >> i) & 1) == 1) {
					p++;
					t -= a[i];
				}
			}
			t -= (p + 1);
			if (p % 2 == 1) {
				res = (res + MOD - C(t, N - 1)) % MOD;
			} else {
				res = (res + C(t, N - 1)) % MOD;
			}
		}
		return res;
	}

	public static long C(long y, int x) {
		if (y < 0 || x < 0 || y < x)
			return 0;
		y %= MOD;
		if (y == 0 || x == 0)
			return 1;
		long res = inv[x];
		for (int i = 0; i < x; i++) {
			res = res * (y - i) % MOD;
		}
		return res;
	}

	public static long qpow(long a, long b, long p) {
		long res = 1 % p;
		for (; b > 0; b >>= 1) {
			if ((b & 1) == 1) {
				res *= a;
				res %= p;
			}
			a *= a;
			a %= p;
		}
		return res;
	}
}

import java.util.*;

public class devuflowers {

	public static long MOD = 1000000007L;

	public static long[] modInv;

	public static void main(String[] args) {

		modInv = new long[21];
		modInv[1] = 1;
		for (int i=2; i<=20; i++)
			modInv[i] = fastModExpo(i, MOD-2);

		// Get n and s.
		Scanner stdin = new Scanner(System.in);
		int n = stdin.nextInt();
		long sum = stdin.nextLong();

		// Read in each individual value.
		long[] vals = new long[n];
		long total = 0;
		for (int i=0; i<n; i++) {
			vals[i] = stdin.nextLong();
			total += vals[i];
		}

		// Screen out this case.
		if (total < sum)
			System.out.println(0);

		// Do real work here.
		else {

			// Store subset sums here.
			long[] subsumplusone = new long[1<<n];

			long res = 0;

			// Run I/E here.
			for (int i=0; i<(1<<n); i++) {

				// Set up sign for I/E.
				int sign = Integer.bitCount(i)%2 == 0 ? 1 : -1;

				// Set the sum of this subset.
				if (i > 0) {
					int loc = 0;
					while ((i & (1<<loc)) == 0) loc++;
					subsumplusone[i] = subsumplusone[i-(1<<loc)] + vals[loc] + 1;
				}

				// Add in term.
				res = (res + sign*choosewithrep(sum-subsumplusone[i], n) + MOD)%MOD;
			}

			System.out.println(res);
		}
	}

	// Returns n+k-1 choose k-1.
	public static long choosewithrep(long n, int k) {

		if (n < 0) return 0;

		// Numerator.
		long res = 1;
		for (int i=1; i<k; i++)
			res = (res * ((n+k-i)%MOD))%MOD;

		for (int i=2; i<=k-1; i++)
			res = (res*modInv[i])%MOD;

		return res;
	}

	public static long fastModExpo(long base, long exp) {
		if (exp == 0) return 1L;
		if (exp%2 == 0) {
			long tmp = fastModExpo(base, exp/2);
			return (tmp*tmp)%MOD;
		}
		return (fastModExpo(base, exp-1)*base)%MOD;
	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DevuAndFlowers solver = new DevuAndFlowers();
        solver.solve(1, in, out);
        out.close();
    }

    static class DevuAndFlowers {
        long MOD = (long) (1e9) + 7;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            Poly p = new Poly();
            int N = in.nextInt();
            long s = in.nextLong();
            for (int i = 0; i < N; i++) {
                if (N == 1) {
                    long a = in.nextLong();
                    if (a >= s) {
                        out.println(1);
                    } else {
                        out.println(0);
                    }
                    return;
                }
                p.mult(in.nextLong() + 1);
            }
            long inv = 1;
            for (int i = 1; i <= N - 1; i++) {
                inv *= i;
                inv %= MOD;
            }
            inv = MathUtils.inverse(inv, MOD);
            long res = 0;
            for (long l : p.poly.keySet()) {
                long i = s - l;
                if (i < 0) {
                    continue;
                } else {
                    long num = 1;
                    for (long j = N + i - 1; j >= i + 1; j--) {
                        num *= j % MOD;
                        num %= MOD;
                    }
                    num *= inv;
                    num %= MOD;
                    num *= p.poly.get(l);
                    num %= MOD;
                    res += num;
                    if (res >= MOD) {
                        res -= MOD;
                    }
                    if (res < 0) {
                        res += MOD;
                    }
                }
            }
            out.println(res);
        }

        class Poly {
            HashMap<Long, Long> poly;

            Poly() {
                poly = new HashMap<>();
                poly.put(0L, 1L);
            }

            void mult(long i) {
                HashMap<Long, Long> toAdd = new HashMap<>();
                for (long l : poly.keySet()) {
                    toAdd.putIfAbsent(l + i, 0L);
                    toAdd.replace(l + i, -poly.get(l));
                }
                for (long l : toAdd.keySet()) {
                    poly.putIfAbsent(l, 0L);
                    long next = poly.get(l) + toAdd.get(l);
                    if (next < 0) {
                        next += MOD;
                    }
                    if (next >= MOD) {
                        next -= MOD;
                    }
                    poly.replace(l, next);
                }
            }

        }

    }

    static class MathUtils {
        public static long inverse(long a, long mod) {
            long[] inv = extended_gcd(a, mod);
            if (inv[0] != 1) {
                return 0;
            } else {
                return (inv[1] + 2 * mod) % mod;
            }
        }

        public static long[] extended_gcd(long a, long b) {
            //three numbers, first is gcd, second is x, third is y
            if (a == 0) {
                return new long[]{b, 0, 1};
            }
            long[] next = extended_gcd(b % a, a);
            long tempX = next[1];
            next[1] = next[2] - (b / a) * next[1];
            next[2] = tempX;
            return next;
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

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

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

    }
}

import java.io.*;
import java.lang.*;
import static java.lang.Math.*;
import java.lang.reflect.*;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.security.CodeSource;
import java.security.KeyStore;
import java.util.*;
import static java.util.Arrays.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;

// https://netbeans.org/kb/73/java/editor-codereference_ru.html#display

public class Main {

    final long mod = (long)1e9 + 7;
    int n;
    long s;
    long[] f;
    long[] invFact = new long[1000];
    {
        invFact[0] = 1;
        long f = 1;
        for (int i = 1; i < invFact.length; i++) {
            f = (f * i) % mod;
            invFact[i] = valueOf(f).modInverse(valueOf(mod)).longValue();
        }
    }

    long C( int l, long b ){
        long ans = 1;
        for( long x = b-l+1; x <= b; ++x ){
            ans = (x%mod * ans) % mod;
        }
        ans = (ans * invFact[l]) % mod;
        return ans;
    }

    void solve(){
        for( int n = 0; n <= 10; ++n ){
            for (int m = 0; m <= n; m++) {
                err.print( " " + C(m,n) );
            }
            err.println();
        }

        n = sc.nextInt();
        s = sc.nextLong();
        f = new long[n];
        for (int i = 0; i < f.length; i++) {
            f[i] = sc.nextLong();
        }

        long ans = 0;
        for (int msk = 0; msk < (1<<n); msk++) {
            long curS = s;
            for (int i = 0; i < n; i++) {
                if( ((msk>>i)&1) == 1 ){
                    curS -= f[i] + 1;
                }
            }
            if( 0 <= curS ){
                long comb = C(n-1, curS+n-1);
                //err.println( msk +") "+ comb );
                if( Integer.bitCount(msk) % 2 == 0 )
                    ans = (ans + comb) % mod;
                else
                    ans = (ans - comb + mod) % mod;
            }
        }
        ans = (ans%mod + mod) % mod;
        out.println(ans);
    }

    //------------------------------------------------------------------//

    private void run(){
        err = System.err;
        boolean oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }

        if( oj ){
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        }
        else{
            try {
                sc = new FastScanner(new FileReader("input.txt"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch ( IOException e) {
                MLE();
            }
        }
        solve();

        out.flush();
    }

    FastScanner sc;
    PrintWriter out;
    PrintStream err;

    void MLE(){
        int[][] arr = new int[1024*1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024*1024];
        }
    }

    class FastScanner {

        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStreamReader reader) {
            br = new BufferedReader(reader);
            st = new StringTokenizer("");
        }

        String next() {
            while( !st.hasMoreElements() )
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException ex) {
                    MLE();
                }
            return st.nextToken();
        }

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

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

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

}

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
import java.util.Vector;
public class Main {
	static final long mod=1000000007;
	public static void main(String[] args) {
		long a[]=new long[20];
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		long s=sc.nextLong();
		for(int i=0;i<n;i++)
				a[i]=sc.nextLong();
		int len=(1<<n);
		long ans=0;
		for(int i=0;i<len;i++){
			long x=s;
			int flag=1;
			for(int j=0;j<n;j++)
				if(((i>>j)&1)==1){
					flag*=-1;
					x-=a[j]+1;
				}
			if(x<0)
				continue;
			ans=(ans+flag*lucas(x+n-1,n-1))%mod;
			ans=(ans+mod)%mod;
		}
		System.out.println(ans);
	}
	static long lucas(long a,long b){
		if(b==0)
			return 1;
		return getc(a%mod,b%mod)*lucas(a/mod,b/mod)%mod;
	}
	static long getc(long a,long b){
		if(a<b)
			return 0;
		long ans=1;
		for(long i=a-b+1;i<=a;i++)
			ans=ans*i%mod;
		long t=1;
		for(long i=1;i<=b;i++)
			t=t*i%mod;
		return ans*qpow(t,mod-2)%mod;
	}
	static long qpow(long a,long b){
		long ans=1;
		while(b!=0){
			if((b&1)==1){
				ans=a*ans%mod;
			}
			a=a*a%mod;
			b>>=1;
		}
		return ans;
	}
}

import java.io.*;
import java.lang.*;
import static java.lang.Math.*;
import java.lang.reflect.*;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.security.CodeSource;
import java.security.KeyStore;
import java.util.*;
import static java.util.Arrays.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;

// https://netbeans.org/kb/73/java/editor-codereference_ru.html#display

public class Main {

    final long mod = (long)1e9 + 7;
    int n;
    long s;
    long[] f;
    long[] invFact = new long[25];
    {
        invFact[0] = 1;
        long f = 1;
        for (int i = 1; i < invFact.length; i++) {
            f = (f * i) % mod;
            invFact[i] = valueOf(f).modInverse(valueOf(mod)).longValue();
        }
    }

    long C( int l, long b ){
        long ans = 1;
        for( long x = b-l+1; x <= b; ++x ){
            ans = (x%mod * ans) % mod;
        }
        ans = (ans * invFact[l]) % mod;
        return ans;
    }

    void solve(){
//        for( int n = 0; n <= 10; ++n ){
//            for (int m = 0; m <= n; m++) {
//                err.print( " " + C(m,n) );
//            }
//            err.println();
//        }

        n = sc.nextInt();
        s = sc.nextLong();
        f = new long[n];
        for (int i = 0; i < f.length; i++) {
            f[i] = sc.nextLong();
        }

        long ans = 0;
        for (int msk = 0; msk < (1<<n); msk++) {
            long curS = s;
            for (int i = 0; i < n; i++) {
                if( ((msk>>i)&1) == 1 ){
                    curS -= f[i] + 1;
                }
            }
            if( 0 <= curS ){
                long comb = C(n-1, curS+n-1);
                //err.println( msk +") "+ comb );
                if( Integer.bitCount(msk) % 2 == 0 )
                    ans = (ans + comb) % mod;
                else
                    ans = (ans - comb + mod) % mod;
            }
        }
        ans = (ans%mod + mod) % mod;
        out.println(ans);
    }

    //------------------------------------------------------------------//

    private void run(){
        err = System.err;
        boolean oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }

        if( oj ){
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        }
        else{
            try {
                sc = new FastScanner(new FileReader("input.txt"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch ( IOException e) {
                MLE();
            }
        }
        solve();

        out.flush();
    }

    FastScanner sc;
    PrintWriter out;
    PrintStream err;

    void MLE(){
        int[][] arr = new int[1024*1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024*1024];
        }
    }

    class FastScanner {

        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStreamReader reader) {
            br = new BufferedReader(reader);
            st = new StringTokenizer("");
        }

        String next() {
            while( !st.hasMoreElements() )
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException ex) {
                    MLE();
                }
            return st.nextToken();
        }

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

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

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

}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Main {

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

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	private void run() throws IOException {
		if (new File("input.txt").exists())
			in = new BufferedReader(new FileReader("input.txt"));
		else
			in = new BufferedReader(new InputStreamReader(System.in));
		if (new File("output.txt").exists())
			out = new PrintWriter("output.txt");
		else
			out = new PrintWriter(System.out);

		solve();

		in.close();
		out.close();
	}

	final int maxn = 22;
	final int p = 1000 * 1000 * 1000 + 7;

	int n;
	long s;
	long f[] = new long[maxn];
	long ans;

	long inv[] = new long[maxn];
	long finv[] = new long[maxn];

	TreeMap<Long, Long> polynom = new TreeMap<>();

	void rec(int index, long a, long pow) {
		if (index == n) {
			if (polynom.containsKey(pow))
				polynom.put(pow, (polynom.get(pow) + a) % p);
			else
				polynom.put(pow, a);
		} else {
			rec(index + 1, a, pow);
			rec(index + 1, (p - a) % p, pow + f[index] + 1);
		}
	}

	long getC(long n, int m) {
		n %= p;
		long c = 1;
		for (long i = n - m + 1; i <= n; i++)
			c = (c * i) % p;
		c = (c * finv[m]) % p;
		return c;
	}

	void precalc() {
		inv[1] = 1;
		for (int i = 2; i < maxn; i++)
			inv[i] = (p - ((p / i) * inv[p % i]) % p) % p;
		finv[0] = 1;
		for (int i = 1; i < maxn; i++)
			finv[i] = (finv[i - 1] * inv[i]) % p;
	}

	void solve() throws IOException {
		precalc();
		n = nextInt();
		s = nextLong();
		for (int i = 0; i < n; i++)
			f[i] = nextLong();

		rec(0, 1, 0);
		ans = 0;
		for (long pow : polynom.keySet()) {
			long k = s - pow;
			if (k >= 0) {
				long c = getC(n + k - 1, n - 1);
				// System.err.println(k + " " + c);
				ans = (ans + c * polynom.get(pow)) % p;
			}
		}

		out.println(ans);
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	String nextToken() throws IOException {
		while (!st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String str = in.readLine();
			if (str == null)
				return true;
			st = new StringTokenizer(str);
		}
		return false;
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Task451E {

	private static final long MOD = 1000000007;

	private FastScanner in;
	private PrintWriter out;

	private long inverseNMinusOneFactorial;
	private long nMinusOne;

	public Task451E(InputStream in, OutputStream out) {
		this.in = new FastScanner(in);
		this.out = new PrintWriter(out);
	}

	public void solve() throws IOException {
		int n = nextInt();
		long s = nextLong();
		long f[] = new long[n];
		for (int i = 0; i < n; ++i) {
			f[i] = nextLong();
		}
		preCalc(n);
		long result = 0;
		mask:
		for (int mask = 0; mask < (1 << n); ++mask) {
			long restS = s;
			boolean subtract = false;
			for (int bit = 0; bit < n; ++bit) {
				if (((1 << bit) & mask) != 0) {
					restS -= f[bit] + 1;
					if (restS < 0) {
						continue mask;
					}
					subtract = !subtract;
				}
			}
			if (subtract) {
				result = (result + (MOD - c(restS))) % MOD;
			}
			else {
				result = (result + c(restS)) % MOD;
			}
		}
		out.println(result);
	}

	private void preCalc(int n) {
		long factorial = 1;
		for (int i = 1; i < n; ++i) {
			factorial = (factorial * i) % MOD;
		}
		nMinusOne = n - 1;
		inverseNMinusOneFactorial = powerMod(factorial, MOD - 2);
	}

	private long powerMod(long n, long power) {
		long result = 1;
		n = n % MOD;
		for (int bit = 1; bit <= power; bit <<= 1) {
			if ((power & bit) != 0) {
				result = (result * n) % MOD;
			}
			n = (n * n) % MOD;
		}
		return result;
	}

	public long c(long restS) {
		long result = 1;
		for (long i = restS + 1; i <= (restS + nMinusOne); ++i) {
			result = (result * (i % MOD)) % MOD;
		}
		return (result * inverseNMinusOneFactorial) % MOD;
	}

	public void run() {
		try {
			solve();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

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

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

	}

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

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

	public static void main(String[] arg) {
		new Task451E(System.in, System.out).run();
	}
}

// practice with rainboy
import java.io.*;
import java.util.*;

public class CF451E extends PrintWriter {
	CF451E() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF451E o = new CF451E(); o.main(); o.flush();
	}

	static final int MD = 1000000007;
	int d_, x_, y_;
	void gcd_(int a, int b) {
		if (b == 0) {
			d_ = a;
			x_ = 1; y_ = 0;
		} else {
			gcd_(b, a % b);
			int t = x_ - a / b * y_; x_ = y_; y_ = t;
		}
	}
	int[] inv;
	void init(int n) {
		inv = new int[n];
		for (int k = 1; k < n; k++) {
			gcd_(k, MD);
			if (x_ < 0)
				x_ += MD;
			inv[k] = x_;
		}
	}
	long ch(long n, int k) {
		return k == 0 ? 1 : ch(n - 1, k - 1) * (n % MD) % MD * inv[k] % MD;
	}
	void main() {
		int n = sc.nextInt();
		init(n);
		long s = sc.nextLong();
		long[] ff  = new long[n];
		for (int i = 0; i < n; i++)
			ff[i] = sc.nextLong();
		int ans = 0;
		for (int b = 0; b < 1 << n; b++) {
			int k = 0;
			long t = s;
			for (int i = 0; i < n; i++)
				if ((b & 1 << i) != 0) {
					k++;
					t -= ff[i] + 1;
				}
			if (t >= 0) {
				int cnt = (int) ch(t + n - 1, n - 1);
				ans = (k % 2 == 0 ? ans + cnt : ans - cnt) % MD;
			}
		}
		if (ans < 0)
			ans += MD;
		println(ans);
	}
}

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

public class DevuAndFlowers {

	static long mod = 1000000007;
	static long modInv[];
	static int N;
	static long S;
	static long f[];
	static long fact[];
	public static void main(String[] args) {
		JS in = new JS();
		N = in.nextInt();
		S = in.nextLong();
		f = new long[N];
		for(int i = 0; i < N; i++) f[i] = in.nextLong();
		modInv = new long[N+5];
		for(int i = 0; i <= N+4; i++) modInv[i] = pow(i, mod-2);

		long ans = 0;
		for(int i = 0; i < (1<<N); i++) {
			long over = S;
			for(int j = 0; j < N; j++) {
				if((i & (1<<j)) > 0) {
					over -= f[j]+1;
				}
			}
			if(over < 0) continue;
			long v = sumTo(over, N);
			if(Integer.bitCount(i)%2==1) ans -= v;
			else ans += v;
			while(ans < 0) ans+=mod;
			while(ans >= mod)ans-=mod;
		}
		System.out.println(ans);
	}

	static long sumTo(long sum, long n) {
		return choose(sum+n-1, n-1);
	}
	static long choose(long n, long k) {
		long prev = 1;
		for(int c = 1; c <= k; c++)
			prev = (((prev*(n%mod-c+1))%mod)*modInv[c])%mod;
		while(prev < 0) prev += mod;
		while(prev >= mod) prev -= mod;
		return prev;
	}

	static long pow(long base, long power) {
		if(power == 0) return 1;
		if(power == 1) return base;
		if((power%2)==0) {
			long r = pow(base, power/2);
			return (r*r)%mod;
		}
		else {
			return (base * pow(base,power-1))%mod;
		}
	}

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

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

		public JS(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			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 long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

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

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

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

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int []nia(int n){
			int r[] = new int[n];
			for(int i = 0; i < n; i++) r[i] = nextInt();
			return r;
		}
		public double []nda(int n){
			double r[] = new double[n];
			for(int i = 0; i < n; i++) r[i] = nextDouble();
			return r;
		}
		public long []nla(int n){
			long r[] = new long[n];
			for(int i = 0; i < n; i++) r[i] = nextLong();
			return r;
		}
	}

}

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

import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class Main{

	// ArrayList<Integer> lis = new ArrayList<Integer>();
	// ArrayList<String> lis = new ArrayList<String>();
	//  PriorityQueue<P> que = new PriorityQueue<P>();
	// PriorityQueue<Integer> que = new PriorityQueue<Integer>();
	//  Stack<Integer> que = new Stack<Integer>();
    //	static long sum=0;
	// 1000000007 (10^9+7)
	static int mod = 1000000007;
	//static int mod = 1000000009,r=0; ArrayList<Integer> l[]= new ArrayList[n];
   // static int dx[]={1,-1,0,0};
//	static int dy[]={0,0,1,-1};
//	static int dx[]={1,-1,0,0,1,1,-1,-1};
//  static int dy[]={0,0,1,-1,1,-1,1,-1};
	//static Set<Integer> set = new HashSet<Integer>();p

public  static void main(String[] args)   throws Exception, IOException{
   //String line=""; throws Exception, IOException
   //(line=br.readLine())!=null
	//Scanner sc =new Scanner(System.in);
	// !!caution!! int long //
	Reader sc = new Reader(System.in);

 //,a=sc.nextInt(),b=sc.nextInt();
 	 int n=sc.nextInt();
    long f[]=new long[n],s=sc.nextLong()+n-1;

	for (int i = 0; i <n ; i++){
		f[i]=sc.nextLong();
	}

	long a[]=new long [2];
	long d[]=new long[22];
      d[0]++;

	for (int i = 1; i <=20 ; i++){
		d[i]=exGCD(i, mod)[1];d[i]+=mod; d[i]%=mod;
		d[i]*=d[i-1];
        d[i]%=mod;
	}

	//db(d);

	long r=0;

	for(int i=0,c=1;i<1<<n;i++){
	  long 	x=s,k=0;
	    for(int t=0;t<n;t++){
	    	if( bit(i,t) ){ k++;  x-=f[t]+1;      }
	    }
	   if( k%2==0 )c=1 ; else c=-1;
	   if(x<0)continue;
	    x%=mod;
	  r+=c*com( x,n-1,d[n-1] );
	  r+=mod;
	  r%=mod;
	 // db(i,x,r);
	}

	System.out.println(r);

}

static boolean bit(int x,int k){
	// weather k-th bit (from right) be one or zero
	return  ( 0 < ( (x>>k) & 1 )  )  ? true:false;
}

static long com( long n, int m ,long d) {//beware n<m�I

	if( n<m )return 0;

  long r=1;
	 for(int i=0;i<m;i++){
		 r*=n--; r%=mod;
	 }

	 r*=d; r%=mod;
	return r;
}

 static long[] exGCD(long a, long b)
{
	if(a == 0 || b == 0)return null;
	int as = Long.signum(a);
	int bs = Long.signum(b);
	a = Math.abs(a); b = Math.abs(b);
	long p = 1, q = 0, r = 0, s = 1;
	while(b > 0){
		long c = a / b;
		long d;
		d = a; a = b; b = d % b;
		d = p; p = q; q = d - c * q;
		d = r; r = s; s = d - c * s;
	}
	// can be minus!
	return new long[]{a, p * as, r * bs};
}

static void db(Object... os){
    System.err.println(Arrays.deepToString(os));

}

}

  /*
   * class P implements Comparable<P>{
//		implements Comparable<Pair>
		int id; long d;
		P(int id,long d){
			this.id=id;
			this.d=d;
		}
		public int compareTo(P x){
		   	 return  0<=d-x.d?1:-1 ;  //ascend
		   }

 }

class Pair implements Comparable<Pair>{
//	implements Comparable<Pair>
	int a,b;
	Pair(int a,int b){
		this.a=a;
		this.b=b;
	}
	public int compareTo(Pair x){
	   	 return a-x.a; //descend
	   }
}*/

class Reader
{
	private BufferedReader x;
	private StringTokenizer st;

	public Reader(InputStream in)
	{
		x = new BufferedReader(new InputStreamReader(in));
		st = null;
	}
	public String nextString() throws IOException
	{
		while( st==null || !st.hasMoreTokens() )
			st = new StringTokenizer(x.readLine());
		return st.nextToken();
	}
	public int nextInt() throws IOException
	{
		return Integer.parseInt(nextString());
	}
	public long nextLong() throws IOException
	{
		return Long.parseLong(nextString());
	}
	public double nextDouble() throws IOException
	{
		return Double.parseDouble(nextString());
	}
}

import java.io.*;
import java.util.*;
public class Main {

    public static void main(String[] args)
    {
        InputStream inputstream = System.in;
        OutputStream outputstream = System.out;
        InputReader in = new InputReader(inputstream);
        OutputWriter out = new OutputWriter(outputstream);
        mysolver mysol = new mysolver();
        mysol.solve(in, out);
        out.close();
    }

}

class mysolver {
	public long mod = 1000000007;
	public long MOD = 1_000_000_007;
	long inv[] = new long[26];
    public void solve(InputReader in,OutputWriter out)
    {
    	PrintWriter pout = new PrintWriter(new BufferedOutputStream(System.out));
    	int n = in.readInt();
    	long s = Long.parseLong(in.readString());
    	long f[] = new long[n];
    	for(int i=0;i<n;i++)
    		f[i] = Long.parseLong(in.readString());
    	long ans = 0;
    	for(int i=1;i<=25;i++)
    		inv[i] = inverse(i);
    	for(int i=0 ;i< 1<<n ; i++)
    	{
    		int bit = Long.bitCount(i);
    		String str = Long.toBinaryString(i);
    		str = ("00000000000000000000000000000000").concat(str);
    		int sign = 0;

    		if(bit%2==0)
    			sign = 1;
    		else
    			sign = -1;

    		char[] ch = str.toCharArray();
    		long val = s;
    		for(int j=ch.length-1;j>ch.length-n-1;j--)
    		{
    			if(ch[j]=='1')
    			{
    				val = val - f[ch.length-1-j]-1;
    			}
    		}
    		val = val+n-1;
    		if(val < 0)
    			continue;
    		ans = ans + sign * C(val,n-1);
    		ans = ans%mod;
    		//System.out.println(ans);
    	}
    	while(ans < 0)
    		ans = ans+mod;
    	System.out.println(ans);
    	pout.close();
    }

    public long C(long n, long k) {
        long r = 1;
        for (long i = n; i > n - k; i--)
            r = (r * (i % MOD)) % MOD;
        long d = 1;
        for (long i = 1; i <= k; i++)
            d = (d * i) % MOD;
        return (r * inverse(d)) % MOD;
    }

    public long inverse(long a)
    {
    	long val = mod-2;
    	long ans = 1;
    	long mul = a;
    	while(val!=0)
    	{
    		if(val%2==1)
    		{
    			ans = (ans*mul)%mod;
    		}
    		mul = (mul*mul)%mod;
    		val = val/2;
    	}
    	return ans;
    }
}
class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public String readString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public String next() {
        return readString();
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void close() {
        writer.close();
    }

    public void printLine(int i) {
        writer.println(i);
    }
}

class IOUtils {

    public static void readIntArrays(InputReader in, int[]... arrays) {
        for (int i = 0; i < arrays[0].length; i++) {
            for (int j = 0; j < arrays.length; j++)
                arrays[j][i] = in.readInt();
        }
    }

    }

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

public class DevuAndFlowers {

	static long mod = 1000000007;
	static long modInv[];
	static int N;
	static long S;
	static long f[];
	static long fact[];
	public static void main(String[] args) {
		JS in = new JS();
		N = in.nextInt();
		S = in.nextLong();
		f = new long[N];
		fact = new long[1000000];
		fact[0]=1;
		fact[1]=1;
		for(int i = 2; i < 1000000; i++) fact[i] = (fact[i-1]*i)%mod;
		for(int i = 0; i < N; i++) f[i] = in.nextLong();
		modInv = new long[N+1];
		for(int i = 0; i <= N; i++) modInv[i] = pow(i, mod-2);

		long ans = 0;
		for(int i = 0; i < (1<<N); i++) {
			long over = S;
			for(int j = 0; j < N; j++) {
				if((i & (1<<j)) > 0) {
					over -= f[j]+1;
				}
			}
			if(over < 0) continue;
			long v = sumTo(over, N);
			long vs = c(over+N-1, N-1, mod);
			if(Integer.bitCount(i)%2==1) ans -= vs;
			else ans += vs;
			while(ans < 0) ans+=mod;
			while(ans >= mod)ans-=mod;
		}
		System.out.println(ans);
	}

	static long sumTo(long sum, long n) {
		return choose(sum+n-1, n-1);
	}
	static long choose(long n, long k) {
		long prev = 1;
		for(int c = 1; c <= k; c++)
			prev = (((prev*(n-c+1))%mod)*modInv[c])%mod;
		return prev;
	}
	static long c(long n, long k, long p) {
		if(cf(n,p) > cf(k,p) + cf(n-k,p)) return 0;
		long ans = 1;
		for(long i = n-k+1; i <= n; i++) {
			ans = ((ans%mod)*(i%mod))%mod;
		}
		ans = ((ans%mod)*inverse(fact[(int)k],mod))%mod;
		return ans;
	}
	static long inverse(long n, long p) {
		return pow(n, p-2);
	}
	static long cf(long n, long p) {
		long k = 0;
		while(n >= p) {
			k+=n/p;
			n/=p;
		}
		return k;
	}

	static long pow(long base, long power) {
		if(power == 0) return 1;
		if(power == 1) return base;
		if((power%2)==0) {
			long r = pow(base, power/2);
			return (r*r)%mod;
		}
		else {
			return (base * pow(base,power-1))%mod;
		}
	}

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

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

		public JS(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			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 long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

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

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

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

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int []nia(int n){
			int r[] = new int[n];
			for(int i = 0; i < n; i++) r[i] = nextInt();
			return r;
		}
		public double []nda(int n){
			double r[] = new double[n];
			for(int i = 0; i < n; i++) r[i] = nextDouble();
			return r;
		}
		public long []nla(int n){
			long r[] = new long[n];
			for(int i = 0; i < n; i++) r[i] = nextLong();
			return r;
		}
	}

}

import java.io.PrintWriter;
import java.util.Scanner;

public class devuandflowers {

	final int MOD = (int) 1e9 + 7;

	public int add(long a, long b) {
		return (int)((a + b) % MOD);
	}

	public int sub(long a, long b) {
		return (int)((a - b + MOD) % MOD);
	}

	public int mult(long a, long b) {
		return (int)(((a % MOD) * (b % MOD) % MOD));
	}

	public int power(long n, long k) {
		int ans = 1;
		while(k > 0) {
			if(k % 2 == 0) {
				k /= 2;
				n = mult(n, n);
			} else {
				k--;
				ans = mult(ans, n);
			}
		}
		return ans;
	}

	public int inv(int n) {
		return power(n, MOD - 2);
	}

	public int choose(long n, long k) {
		if(n - k > k) {
			k = n - k;
		}
		int top = 1;
		for(long i = k + 1; i <= n; ++i) {
			top = mult(top, i);
		}

		int bottom = 1;
		for(long i = n - k; i >= 1; --i) {
			bottom = mult(bottom, i);
		}

		return mult(top, inv(bottom));
	}

	public void solve(Scanner in, PrintWriter out) {
		int n = in.nextInt();
		long s = in.nextLong();
		long[] a = new long[n];
		long tot = 0;
		for(int i = 0; i < n; ++i) {
			a[i] = in.nextLong();
			tot += a[i];
		}
		if(s > tot) {
			out.println(0);
			return;
		}
		if(s == tot) {
			out.println(1);
			return;
		}

//		System.out.println(choose(1000000000000L, 20));
		int ans = 0;

		for(int mask = 0; mask < (1 << n); ++mask) {
			long cursum = s;
			for(int i = 0; i < n; ++i) {
				if((mask & (1<<i)) == 0) continue;
				cursum -= a[i] + 1;
			}
			if(cursum < 0) continue;
			if(Integer.bitCount(mask) % 2 == 0) {
				ans = add(ans, choose(cursum + n - 1, n - 1));
			} else {
				ans = sub(ans, choose(cursum + n - 1, n - 1));
			}
		}

		out.println(ans);

	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		new devuandflowers().solve(in, out);

		in.close();
		out.close();
	}
}

import java.util.*;
public class b {
public static void main(String[] args)
{
	Scanner input = new Scanner(System.in);
	n = input.nextInt();
	s = input.nextLong();
	data = new long[n];
	invs = new long[21];
	for(int i = 1; i<=20; i++) invs[i] = invmod(i);
	for(int i = 0; i<n; i++) data[i] = input.nextLong();
	long res = 0;
	for(int i = 0; i<(1<<n); i++)
	{
		long cur = go(i);
		if(Integer.bitCount(i)%2 == 1) cur *= -1;
		res += cur;
		res %= mod;
	}
	System.out.println((res+mod)%mod);
}
static long[] invs;
static int n;
static long s;
static long[] data;
static long mod = (long)1e9+7;
static long go(int mask)
{
	long sum = s;
	for(int i = 0; i<n; i++)
	{
		if((mask & (1<<i)) > 0) sum -= 1 + data[i];
	}
	if(sum < 0) return 0;
	long num = sum + n - 1;
	long denom = n-1;
	long res = 1;
	for(int i = 0; i<denom; i++)
	{
		res = (res * ((num-i)%mod))%mod;
		res = (res * invs[i+1])%mod;
	}
	return res;
}
public static long[] gcd(long p, long q)
{
	if(q==0) return new long[] {p, 1, 0};
	long[] vals = gcd(q, p%q);
	return new long[] {vals[0], vals[2], vals[1] - (p/q)*vals[2]};
}
public static long invmod(long x)
{
	long[] vals = gcd(x, mod);
	if(vals[0]>1) return -1;
	if(vals[1]>0) return vals[1];
	return mod + vals[1];
}
}

import java.util.*;
import java.text.*;
import java.io.*;
import java.math.*;
public class code5 {
	InputStream is;
	PrintWriter out;
	static long mod=pow(10,9)+7;
	static int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
 	void solve() throws Exception
	{
 		int n=ni();
 		long sum=nl();
 		long a[]=nl(n);
 		long ans=ncr(sum+n-1,n-1);
 		for(int i=1;i<(1<<n);i++)
 		{
 			long temp=0,count=0;
 			for(int j=0;j<n;j++)
 			{
 				if((i&(1<<j))!=0)
 				{
 					count++;
 					temp+=(a[j]+1);
 				}
 			}
 			if(count%2==0)
 			{
 				ans+=(ncr(sum-temp+n-1,n-1));
 				ans%=mod;
 			}else {
 				ans=(ans-ncr(sum-temp+n-1,n-1)+mod)%mod;
 			}
 		}
 		out.print(ans%mod);
	}
 	long ncr(long n,long r)
 	{
 		long nom=1;
 		if(n<0||n<r)
 			return 0;
 		for(long i=n;i>=(n-r+1);i--)
 		{
 			nom*=(i%mod);
 			nom%=mod;
 		}
 		long dom=1;
 		for(long i=r;i>=1;i--)
 		{
 			dom*=(i%mod);
 			dom%=mod;
 		}
 		return (nom*pow(dom,mod-2,mod))%mod;
 	}
 	/*void take(int n)
 	{
 		al=new ArrayList[n];
 		for(int i=0;i<n;i++)
 			al[i]=new ArrayList<Integer>();
 		for(int i=0;i<n-1;i++)
 		{
 			int x=ni()-1;
 			int y=ni()-1;
 			al[x].add(y);
 			al[y].add(x);
 		}
 	}*/

 	int check(long n)
 	{
 		int count=0;
 		while(n!=0)
 		{
 			if(n%10!=0)
 				break;
 			n/=10;
 			count++;
 		}
 		return count;
 	}
	public static int count(int x)
	{
		int num=0;
		while(x!=0)
		{
			x=x&(x-1);
			num++;
		}
		return num;
	}
	static long d, x, y;
	void extendedEuclid(long A, long B) {
	    if(B == 0) {
	        d = A;
	        x = 1;
	        y = 0;
	    }
	    else {
	        extendedEuclid(B, A%B);
	        long temp = x;
	        x = y;
	        y = temp - (A/B)*y;
	    }
	}
	long modInverse(long A,long M) //A and M are coprime
	{
	    extendedEuclid(A,M);
	    return (x%M+M)%M;    //x may be negative
	}
	public static void mergeSort(int[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(int arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		int left[] = new int[n1];
		int right[] = new int[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	public static void mergeSort(long[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(long arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		long left[] = new long[n1];
		long right[] = new long[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	 static class Pair implements Comparable<Pair>{

	       int x,y,k;
	       int i,dir;
		Pair (int xx,int yy){
			this.x=xx;
			this.y=yy;
		}
		public int compareTo(Pair o) {
			if(this.x!=o.x)
				return this.x-o.x;
			return this.y-o.y;
		}

		public String toString(){
			return x+" "+y+" "+k+" "+i;}
		public boolean equals(Object o) {
			if (o instanceof Pair) {
				Pair p = (Pair)o;
				return p.x == x && p.y == y;
			}
			return false;
		}
		public int hashCode() {
			return new Long(x).hashCode()*31 + new Long(y).hashCode() ;
		}
	}

	    public static boolean isPal(String s){
	        for(int i=0, j=s.length()-1;i<=j;i++,j--){
	                if(s.charAt(i)!=s.charAt(j)) return false;
	        }
	        return true;
	    }
	    public static String rev(String s){
			StringBuilder sb=new StringBuilder(s);
			sb.reverse();
			return sb.toString();
	    }

	    public static long gcd(long x,long y){
		if(y==0)
			return x;
		else
			return gcd(y,x%y);
	    }

	    public static int gcd(int x,int y){
	    	if(y==0)
	    		return x;
	    	return gcd(y,x%y);
	    }

	    public static long gcdExtended(long a,long b,long[] x){

	        if(a==0){
	            x[0]=0;
	            x[1]=1;
	            return b;
	        }
	        long[] y=new long[2];
	        long gcd=gcdExtended(b%a, a, y);

	        x[0]=y[1]-(b/a)*y[0];
	        x[1]=y[0];

	        return gcd;
	    }

	    public static int abs(int a,int b){
		return (int)Math.abs(a-b);
	    }

	    public static long abs(long a,long b){
		return (long)Math.abs(a-b);
	    }

	    public static int max(int a,int b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static int min(int a,int b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long max(long a,long b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static long min(long a,long b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long pow(long n,long p,long m){
		 long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    if(result>=m)
		    result%=m;
		    p >>=1;
		    n*=n;
		    if(n>=m)
		    n%=m;
		}
		return result;
	    }

	    public static long pow(long n,long p){
		long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    p >>=1;
		    n*=n;
		}
		return result;
	    }
	    public static void debug(Object... o) {
			System.out.println(Arrays.deepToString(o));
		}
	    void run() throws Exception {
			is = System.in;
			out = new PrintWriter(System.out);
			solve();
			out.flush();
		}

	    public static void main(String[] args) throws Exception {
			new Thread(null, new Runnable() {
				public void run() {
					try {
						new code5().run();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}, "1", 1 << 26).start();

	    	//new code5().run();
		}
	    private byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		private int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		private boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		private int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b));
			return b;
		}

		private double nd() {
			return Double.parseDouble(ns());
		}

		private char nc() {
			return (char) skip();
		}

		private String ns() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		private char[] ns(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		private char[][] nm(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = ns(m);
			return map;
		}

		private int[] na(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = ni();
			return a;
		}
		private long[] nl(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nl();
			return a;
		}

		private int ni() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		private long nl() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

}

import java.util.Scanner;

public class E {

    static int n;
    static long MOD = 1_000_000_007;
    static long LIM = MOD * MOD;

    public static long modPower(long base, long exponent) {
        long r = 1;
        while (exponent > 0) {
            if (exponent % 2 == 1)
                r = (r * base) % MOD;
            base = (base * base) % MOD;
            exponent /= 2;
        }
        return r;
    }

    public static long C(long n, long k) {
        if (n - k < k)
            return C(n, n - k);
        long r = 1;
        for (long i = n; i > n - k; i--)
            r = (r * (i % MOD)) % MOD;
        long d = 1;
        for (long i = 1; i <= k; i++)
            d = (d * i) % MOD;
        return (r * modPower(d, MOD - 2)) % MOD;
    }

    public static long S(long n, long k) {
        return C(n + k - 1, k);
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        long k = in.nextLong();
        long[] f = new long[n];
        for (int i = 0; i < n; i++)
            f[i] = in.nextLong();
        long sum = 0;
        for (int i = 0; i < 1 << n; i++) {
            int sign = Integer.bitCount(i) % 2 == 0 ? 1 : -1;
            long kleft = k;
            for (int j = 0; j < n; j++)
                if ((i & 1 << j) != 0)
                    kleft -= f[j] + 1;
            if (kleft >= 0) {
                sum = ((sum + sign * S(n, kleft)) % MOD + MOD) % MOD;
            }
        }
        System.out.println(sum);
    }
}

//package codeforces;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class E {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(System.out);
    StringTokenizer stringTokenizer;

    String next() throws IOException {
        while (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
            stringTokenizer = new StringTokenizer(reader.readLine());
        }
        return stringTokenizer.nextToken();
    }

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

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

    void solve() throws IOException {
        int n = nextInt();
        long s = nextLong();
        long[] f = new long[n];
        for(int i = 0; i < n; i++) {
            f[i] = nextLong();
        }
        int ans = 0;
        int inverseFK = 1;
        for(int i = 1; i < n; i++) {
            inverseFK = product(inverseFK, inverse(i));
        }
        for(int mask = 0; mask < 1 << n; mask++) {
            long m = s;
            int bitCount = 0;
            for(int i = 0; i < n; i++) {
                if((mask >> i) % 2 == 1) {
                    bitCount++;
                    m -= f[i] + 1;
                }
            }
            if(m >= 0) {
                ans = sum(ans, bitCount % 2 == 0 ? c(m + n - 1, n - 1, inverseFK) : MOD - c(m + n - 1, n - 1, inverseFK));
            }
        }
        writer.println(ans);
        writer.close();
    }

    final int MOD = 1000 * 1000 * 1000 + 7;

    int sum(int a, int b) {
        a += b;
        return a >= MOD ? a - MOD : a;
    }

    int product(int a, int b) {
        return (int)(1l * a * b % MOD);
    }

    int power(int x, int k) {
        int ret = 1;
        while(k > 0) {
            if(k % 2 == 1) {
                ret = product(ret, x);
            }
            x = product(x, x);
            k /= 2;
        }
        return ret;
    }

    int inverse(int x) {
        return power(x, MOD - 2);
    }

    int c(long n, int k, int inverseFK) {
        int m = (int)(n % MOD);
        int ret = 1;
        for(int i = 0; i < k; i++) {
            ret = product(ret, m + MOD - i);
        }
        ret = product(ret, inverseFK);
        return ret;
    }

    public static void main(String[] args) throws IOException {
        new E().solve();
    }
}

import java.util.Scanner;

public class Solution {

    private static final long MOD = 1000000007;
    private static long FACT[] = new long[25];

    private static long modPow(long a, long x, long m) {
        long res = 1;
        while (x > 0) {
            if (x % 2 != 0) {
                res = (res * a) % m;
            }
            a = (a * a) % m;
            x /= 2;
        }
        return res % m;
    }

    private static long modInverse(long a, long p) {
        // p doit être premier
        return modPow(a, p - 2, p);
    }

    private static long nCr(long n, int r) {
        if (n < r) return 0;
        long ret = 1;
        for (long x = n; x >= n - r + 1; x--) {
            ret = (ret * (x % MOD)) % MOD;
        }
        ret = (ret * modInverse(FACT[r], MOD)) % MOD;
        return ret;
    }

    public static void main(String[] args) {
        FACT[0] = 1;
        for (int i = 1; i < 25; i++) {
            FACT[i] = (FACT[i - 1] * i) % MOD;
        }

        Scanner in = new Scanner(System.in);
        int n;
        long s, N;
        n = in.nextInt();
        s = in.nextLong();
        long f[] = new long[n];
        for (int i = 0; i < n; i++) {
            f[i] = in.nextLong();
        }

        N = 1 << n;

        long res = 0;
        for (int i = 0; i < N; i++) {
            long count = 0;
            int p = 0;
            for (int j = 0; j < n; j++) {
                if ((i & (1 << j)) > 0) {
                    count += f[j] + 1;
                    p++;
                }
            }
            if (count > s) continue;
            long C = nCr(s + n - 1 - count, n - 1);
            if (p % 2 == 1) C = -C;
            res = (res + C) % MOD;
            if (res < 0) res += MOD;
        }

        System.out.println(res);
    }
}

//package round258;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E2 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		long s = nl();
		long[] a = new long[n];
		for(int i = 0;i < n;i++)a[i] = nl();
		int mod = 1000000007;
		long ret = 0;

		long invf = 1;
		for(int j = 1;j <= n-1;j++){
			invf = invf * j % mod;
		}
		invf = invl(invf, mod);

		for(int i = 0;i < 1<<n;i++){ // used
			long sum = 0;
			for(int j = 0;j < n;j++){
				if(i<<31-j<0)sum += a[j]+1;
			}
			long rem = s-sum;
			if(rem < 0)continue;
			long val = 1;
			long N = rem+n-1, R = n-1;
			N = N%mod;
			for(int j = 1;j <= R;j++){
				val = val * (N--) % mod;
			}
			if(Integer.bitCount(i) % 2 == 0){
				ret += val;
			}else{
				ret += mod-val;
			}
		}
		ret = ret%mod*invf%mod;
		out.println(ret);
	}

	public static long invl(long a, long mod) {
		long b = mod;
		long p = 1, q = 0;
		while (b > 0){
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E2().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.util.Map;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Mahmoud Aladdin <aladdin3>
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {

    public static final Long MOD = (long)(1e9 + 7);

    public void solve(int testNumber, InputReader jin, OutputWriter jout) {
        int n = jin.int32();
        long s = jin.int64();

        long[] f = new long[n];
        long[] inv = new long[1 + (n << 1)];

        Polynomial p = new Polynomial();
        p.add(0, 1);

        for(int i = 0; i < n; i++) {
            f[i] = jin.int64();
            inv[2 * i + 1] = modpow(2 * i + 1, MOD - 2, MOD);
            inv[2 * i + 2] = modpow(2 * i + 2, MOD - 2, MOD);
            Polynomial temp = new Polynomial();
            temp.add(0, 1);
            temp.add(f[i] + 1, -1);
            p = Polynomial.multiply(p, temp);
        }

        long ans = 0;
        Iterator<Long> it = p.iterPowers();
        while(it.hasNext()) {
            long power = it.next();
            long coeff = (p.getTerm(power) + MOD) % MOD;
            long rem = s - power;
            if(rem >= 0) {
                long temp = comb(n + rem - 1, rem, inv) * coeff;
                ans = (ans % MOD + temp % MOD) % MOD;
            }
        }
        jout.println(ans);
    }

    private long comb(long n, long r, long[] inv) {
        if(r > n) return 0;
        if(n - r < r) r = n - r;
        n %= MOD;
        long ans = 1;
        for(int i = 0; i < r; i++) {
            ans = (ans * (n - i)) % MOD;
            ans = (ans * inv[i + 1]) % MOD;
        }
        return ans;
    }

    private long modpow(long a, long b, long mod) {
        long res = 1;
        while (b > 0) {
            if (b % 2 == 1) {
                res = (res * a) % mod;
            }
            a = (a * a) % mod;
            b >>= 1;
        }
        return res;
    }
}

class Polynomial {
    Map<Long, Long> terms;
    public static long MOD = Long.MAX_VALUE;

    public Polynomial() {
        terms = new HashMap<Long, Long>();
    }

    public Iterator<Long> iterPowers() {
        return terms.keySet().iterator();
    }

    public Long getTerm(Long power) {
        if(terms.containsKey(power))
            return terms.get(power);
        return 0L;
    }

    public void add(long power, long value) {
        long oldVal = terms.containsKey(power)? terms.get(power) : 0;
        terms.put(power, oldVal + value);
    }

    public static Polynomial multiply(Polynomial p1, Polynomial p2) {
        Polynomial result = new Polynomial();
        for(Long pow1: p1.terms.keySet()) {
            long val1 = p1.terms.get(pow1);
            for(Long pow2: p2.terms.keySet()) {
                long val2 = p2.terms.get(pow2);
                result.add(pow1 + pow2, (val1 * val2) % MOD);
            }
        }
        return result;
    }
}

class InputReader {
    private static final int bufferMaxLength = 1024;
    private InputStream in;
    private byte[] buffer;
    private int currentBufferSize;
    private int currentBufferTop;
    private static final String tokenizers = " \t\r\f\n";

    public InputReader(InputStream stream) {
        this.in = stream;
        buffer = new byte[bufferMaxLength];
        currentBufferSize = 0;
        currentBufferTop = 0;
    }

    private boolean refill() {
        try {
            this.currentBufferSize = this.in.read(this.buffer);
            this.currentBufferTop = 0;
        } catch(Exception e) {}
        return this.currentBufferSize > 0;
    }

    private Byte readChar() {
        if(currentBufferTop < currentBufferSize) {
            return this.buffer[this.currentBufferTop++];
        } else {
            if(!this.refill()) {
                return null;
            } else {
                return readChar();
            }
        }
    }

    public String token()  {
        StringBuffer tok = new StringBuffer();
        Byte first;
        while((first = readChar()) != null && (tokenizers.indexOf((char) first.byteValue()) != -1));
        if(first == null) return null;
        tok.append((char)first.byteValue());
        while((first = readChar()) != null && (tokenizers.indexOf((char) first.byteValue()) == -1)) {
            tok.append((char)first.byteValue());
        }
        return tok.toString();
    }

    public Integer int32() throws NumberFormatException {
        String tok = token();
        return tok == null? null : Integer.parseInt(tok);
    }

    public Long int64() throws NumberFormatException {
        String tok = token();
        return tok == null? null : Long.parseLong(tok);
    }

    }

class OutputWriter {
    private final int bufferMaxOut = 1024;
    private PrintWriter out;
    private StringBuilder output;
    private boolean forceFlush = false;

    public OutputWriter(OutputStream outStream) {
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outStream)));
        output = new StringBuilder(2 * bufferMaxOut);
    }

    public OutputWriter(Writer writer) {
        forceFlush = true;
        out = new PrintWriter(writer);
        output = new StringBuilder(2 * bufferMaxOut);
    }

    private void autoFlush() {
        if(forceFlush || output.length() >= bufferMaxOut) {
            flush();
        }
    }

    public void print(Object... tokens) {
        for(int i = 0; i < tokens.length; i++) {
            if(i != 0) output.append(' ');
            output.append(tokens[i]);
        }
        autoFlush();
    }

    public void println(Object... tokens) {
        print(tokens);
        output.append('\n');
        autoFlush();
    }

    public void flush() {
        out.print(output);
        output.setLength(0);
    }

    public void close() {
        flush();
        out.close();
    }
}

import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Set;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Praveen Dhinwa
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		CodeforcesE solver = new CodeforcesE();
		solver.solve(1, in, out);
		out.close();
	}
}

class CodeforcesE {
    long f[] = new long[22];
    int n;
    HashMap<Long, Long> map;
    private long mod = (long) 1e9 + 7;
    long inv[] = new long[55];

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        pre();
        //System.out.println("h " + comb(5, 3));
        n = in.nextInt();
        long s = in.nextLong();
        map = new HashMap<Long, Long>();
        for (int i = 0; i < n; i++) {
            f[i] = in.nextLong();
        }
        gen(0, 0, 1);
        long ans = 0;
        for (long power: map.keySet()) {
            //System.out.println(power);
            long coeff = map.get(power);
            long rem = s - power;
            if (rem >= 0) {
                ans += comb(n + rem - 1, rem) * coeff;
                ans %= mod;
            }
        }
        out.println(ans);
    }

    private void pre() {
        for (int i = 1; i <= 50; i++) {
            inv[i] = modpow(i, mod - 2, mod);
        }
    }

    private long modpow(long a, long b, long mod) {
        long res = 1;
        while (b > 0) {
            if (b % 2 == 1) {
                res = (res * a) % mod;
            }
            a = (a * a) % mod;
            b >>= 1;
        }
        return res;
    }

    private long comb(long n, long r) {
        if (r > n)
            return 0;
        if (n - r < r)
            r = n - r;
        n %= mod;
        long ans = 1;
        for (int i = 0; i < r; i++) {
            ans = (ans * (n - i)) % mod;
            ans = (ans * inv[i + 1]) % mod;
        }
        return ans;
    }

    private void gen(int id, long power, long coeff) {
        if (id == n) {
            long val = 0;
            if (map.containsKey(power)) {
                val = map.get(power);
                map.remove(power);
            }
            val += coeff;
            if (val >= mod)
                val -= mod;
            map.put(power, val);
        } else {
            gen(id + 1, power, coeff);
            long ncoeff = coeff * -1;
            if (ncoeff < 0)
                ncoeff += mod;
            gen(id + 1, power + f[id] + 1, ncoeff);
        }
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

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

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

import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.IOException;
import java.util.Arrays;
import java.io.InputStream;
import java.io.OutputStreamWriter;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int n=in.readInt(), MOD=1000000007;
        long s=in.readLong(), ret=0;
        long[] F= IOUtils.readLongArray(in, n), revFac=IntegerUtils.generateReverseFactorials(n, MOD);
        for (int mask=0; mask<1<<n; mask++) {
            long used=0;
            for (int i=0; i<n; i++) if ((mask&(1<<i))>0)  used+=F[i]+1;
            if (used>s) continue;
            long s2=s-used, x=revFac[n-1];
            for (int i=1; i<n; i++) x=(s2+n-i)%MOD*x%MOD;
            ret=(ret+(Integer.bitCount(mask)%2==0?1:-1)*x+MOD)%MOD;
        }
        out.printLine(ret);
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public long readLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public void close() {
        writer.close();
    }

    public void printLine(long i) {
        writer.println(i);
    }

}

class IOUtils {

    public static long[] readLongArray(InputReader in, int size) {
        long[] array = new long[size];
        for (int i = 0; i < size; i++)
            array[i] = in.readLong();
        return array;
    }

}

class IntegerUtils {

    public static long[] generateReverse(int upTo, long module) {
        long[] result = new long[upTo];
        if (upTo > 1)
            result[1] = 1;
        for (int i = 2; i < upTo; i++)
            result[i] = (module - module / i * result[((int) (module % i))] % module) % module;
        return result;
    }

    public static long[] generateReverseFactorials(int upTo, long module) {
        long[] result = generateReverse(upTo, module);
        if (upTo > 0)
            result[0] = 1;
        for (int i = 1; i < upTo; i++)
            result[i] = result[i] * result[i - 1] % module;
        return result;
    }

}

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

public class Main{
    FastScanner in;
    PrintWriter out;

    public long mod = 1000000000+7;
    long[] fact;

    public long bin_pow(long d, long step) {
        if (step == 0) return 1;
        if (step == 1) return d % mod;
        long x = bin_pow(d, step/2);
        x = (x * x) % mod;
        if (step % 2 == 1)
            x = (x * d) % mod;
        return x;
    }

    public long bC(int n, int k) {
        long res = fact[n];
        res *= bin_pow(fact[k], mod-2);
        res %= mod;
        res *= bin_pow(fact[n-k], mod-2);
        res %= mod;
        return res;
    }

    public long C(long n, int k) {
        if (n <= k)
            return bC((int)n, k);

        long res = 1;
        for (int p = 0; p < k ; p++) {
            res *= (n-p) % mod;
            res %= mod;
        }

        res *= bin_pow(fact[k], mod-2);
        res %= mod;

        return res;
    }

    public void solve()
    {
        int n = in.nextInt();
        long s = in.nextLong();
        long[] f = new long[n];
        long sum = 0;
        for (int i = 0; i < n; i++) {
            f[i] = in.nextLong();
            sum += f[i];
        }

        fact = new long[n+10];
        fact[0] = 1;
        for (int i = 1; i < n+10; i++) {
            fact[i] = i * fact[i-1];
            fact[i] %= mod;
        }

        long ans = 0;
        long sg;
        for(int mask = 0; mask < (1<<n); mask++) {
            int cnt = 0;
            sum = s;
            for (int i = 0; i < n; i++)
            if ((mask >> i) % 2 == 1)
            {
                cnt++;
                sum -= f[i]+1;
            }

            if (sum < 0) continue;

            if (cnt % 2 == 1)
                sg = -1;
            else
                sg = 1;

            long tmp_ans = 0;

            tmp_ans = C(sum + n - 1, n - 1);

            ans += sg * tmp_ans;
            ans += 2*mod;
            ans %= mod;
        }

        out.println(ans);
    }

    public void run()
    {
        in = new FastScanner();
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

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

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

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

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

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

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class e {
	static final long MOD = (long)1e9+7;
	public static void main(String[] args) {
		long[] invs = new long[300];
		invs[1] = 1;
		for (int i = 2; i < invs.length; ++i)
			invs[i] = (MOD - (MOD / i) * invs[((int) (MOD % i))] % MOD) % MOD;

		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		long s = in.nextLong();
		long[] fs = new long[n];
		for(int i=0;i<n;i++)
			fs[i] = in.nextLong();
		ArrayList<Term> ans = new ArrayList<>();
		ans.add(new Term(1, 0));
		for(int i=0;i<n;i++) {
			ArrayList<Term> cur = new ArrayList<>();
			cur.add(new Term(1,0));
			cur.add(new Term(-1,fs[i]+1));
			ans = multiply(ans, cur);
		}
		Collections.sort(ans);
//		System.out.println(ans);
		long sum = 0;
		for(Term t : ans) {
			long pow = s - t.pow;
			if(pow < 0) continue;
			long choose = 1;
			for(int i=0;i<n-1;i++) {
				choose *= (pow+n-1-i) % MOD;
				choose %= MOD;
				choose *= invs[i+1];
				choose %= MOD;
//				System.out.println(" * " + (pow-i) + " / " + (i+1));
			}
//			System.out.println("(" + (pow+n-1) + " choose " + (n-1) + ") = " + choose);
			sum += t.c * choose;
			sum %= MOD;
		}
		if(sum < 0) sum += MOD;
		System.out.println(sum);
	}
	static ArrayList<Term> multiply(ArrayList<Term> eq1, ArrayList<Term> eq2) {
		ArrayList<Term> ans = new ArrayList<>();
		for(Term t1 : eq1) {
			for(Term t2 : eq2) {
				ans.add(new Term((t1.c * t2.c) % MOD, t1.pow + t2.pow));
			}
		}
		return ans;
	}
	static class Term implements Comparable<Term>{
		long c;
		long pow;
		public Term(long c, long pow) {
			this.c = c;
			this.pow = pow;
		}
		@Override
		public int compareTo(Term o) {
			return Long.compare(pow, o.pow);
		}
		@Override
		public String toString() {
			return c + "x^(" + pow + ")";
		}
	}
}

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.Set;

public class Main
{
	private final int MOD = (int)(1e9 + 7);

	public long quickMod(long x, long p)
	{
		long ans = 1;
		x %= MOD;
		while(p > 0)
		{
			if(1 == p % 2)
			{
				ans = ans * x % MOD;
			}
			p >>= 1;
			x = x * x % MOD;
		}
		return ans;
	}

	public long cnm(long n, long m)
	{
		if(n < m)
		{
			return 0;
		}
		if(m > n - m)
		{
			m = n - m;
		}
		long a = 1, b = 1;
		for(long i = 0;i < m;++i)
		{
			a = a * (n - i) % MOD;
			b = b * (i + 1) % MOD;
		}
		return a * quickMod(b, MOD - 2) % MOD;
	}

	public long lucas(long n, long m)
	{
		long ans = 1;
		while(n > 0 && m > 0)
		{
			long a = n % MOD, b = m % MOD;
			if(a < b)
			{
				return 0;
			}
			ans = ans * cnm(a, b) % MOD;
			n /= MOD;
			m /= MOD;
		}
		return ans;
	}

	public void foo()
	{
		MyScanner scan = new MyScanner();
		int n = scan.nextInt();
		long s = scan.nextLong();
		long[] a = new long[n];
		for(int i = 0;i < n;++i)
		{
			a[i] = scan.nextLong();
		}
		long ans = 0;
		int m = 1 << n;
		for(int i = 0;i < m;++i)
		{
			int sign = 1;
			long sum = s;
			for(int j = 0;j < n;++j)
			{
				if((i & (1 << j)) > 0)
				{
					sum -= a[j] + 1;
					sign *= -1;
				}
			}
			if(sum >= 0)
			{
				ans += sign * lucas(sum + n - 1, n - 1);
				ans %= MOD;
			}
		}
		System.out.println((ans + MOD) % MOD);
	}

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

	class MyScanner
	{
	    private byte[] buf = new byte[1024];
	    private int curChar;
	    private int numChars;
	    BufferedInputStream bis = new BufferedInputStream(System.in);

	    public int read()
	    {
	        if (-1 == numChars)
	        {
	        	throw new InputMismatchException();
	        }
	        if (curChar >= numChars)
	        {
	            curChar = 0;
	            try
	            {
	                numChars = bis.read(buf);
	            }
	            catch (IOException e)
	            {
	                throw new InputMismatchException();
	            }
	            if (numChars <= 0)
	            {
	            	return -1;
	            }
	        }
	        return buf[curChar++];
	    }

	    public int nextInt()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        int sgn = 1;
	        if (c == '-')
	        {
	            sgn = -1;
	            c = read();
	        }
	        int res = 0;
	        do
	        {
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c - '0';
	            c = read();
	        } while (!isSpaceChar(c));
	        return res * sgn;
	    }

	    public long nextLong()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        int sgn = 1;
	        if (c == '-')
	        {
	            sgn = -1;
	            c = read();
	        }
	        long res = 0;
	        do
	        {
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c - '0';
	            c = read();
	        } while (!isSpaceChar(c));
	        return res * sgn;
	    }

	    public String next()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        StringBuilder res = new StringBuilder();
	        do
	        {
	            res.appendCodePoint(c);
	            c = read();
	        } while (!isSpaceChar(c));
	        return res.toString();
	    }

	    private boolean isSpaceChar(int c)
	    {
	        return ' ' == c || '\n' == c || '\r' == c || '\t' == c || -1 == c;
	    }
	}
}

import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Niyaz Nigmatullin
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		FastPrinter out = new FastPrinter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {

    static final int MOD = 1000000007;

    static int mul(int a, int b) {
        return (int) ((long) a * b % MOD);
    }

    static int[] REV;
    static {
        REV = new int[25];
        for (int i = 1; i < REV.length; i++) {
            REV[i] = MathUtils.modPow(i, MOD - 2, MOD);
        }
    }

    static int f(long n_, int k) {
        --k;
        n_ += k;
        if (k > n_ || k < 0 || n_ < 0) return 0;
        int ans = 1;
        int n = (int) (n_ % MOD + MOD);
        for (int i = 0; i < k; i++) {
            ans = mul(ans, (n - i));
            ans = mul(ans, REV[i + 1]);
        }
        return ans;
    }

    public void solve(int testNumber, FastScanner in, FastPrinter out) {
        int n = in.nextInt();
        long s = in.nextLong();
        long[] f = new long[n];
        for (int i = 0; i < n; i++) {
            f[i] = in.nextLong();
        }
        int ans = 0;
        for (int mask = 0; mask < 1 << n; mask++) {
            long cs = 0;
            for (int i = 0; i < n; i++) {
                if (((mask >> i) & 1) == 1) {
                    cs += f[i] + 1;
                }
            }
            if (cs > s) {
                continue;
            }
            if ((Integer.bitCount(mask) & 1) == 1) {
                ans -= f(s - cs, n);
                if (ans < 0) ans += MOD;
            } else {
                ans += f(s - cs, n);
                if (ans >= MOD) ans -= MOD;
            }
        }
        out.println(ans);
    }
}

class MathUtils {

    public static int modPow(int a, int b, int mod) {
        int ret = 1;
        a = (a % mod + mod) % mod;
        while (b > 0) {
            if ((b & 1) == 1) {
                ret = (int) ((long) ret * a % mod);
            }
            a = (int) ((long) a * a % mod);
            b >>= 1;
        }
        return ret;
    }

    }

class FastScanner extends BufferedReader {

    public FastScanner(InputStream is) {
        super(new InputStreamReader(is));
    }

    public int read() {
        try {
            int ret = super.read();
//            if (isEOF && ret < 0) {
//                throw new InputMismatchException();
//            }
//            isEOF = ret == -1;
            return ret;
        } catch (IOException e) {
            throw new InputMismatchException();
        }
    }

    public String next() {
        StringBuilder sb = new StringBuilder();
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        if (c < 0) {
            return null;
        }
        while (c >= 0 && !isWhiteSpace(c)) {
            sb.appendCodePoint(c);
            c = read();
        }
        return sb.toString();
    }

    static boolean isWhiteSpace(int c) {
        return c >= 0 && c <= 32;
    }

    public int nextInt() {
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int ret = 0;
        while (c >= 0 && !isWhiteSpace(c)) {
            if (c < '0' || c > '9') {
                throw new NumberFormatException("digit expected " + (char) c
                        + " found");
            }
            ret = ret * 10 + c - '0';
            c = read();
        }
        return ret * sgn;
    }

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

    public String readLine() {
        try {
            return super.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    }

class FastPrinter extends PrintWriter {

    public FastPrinter(OutputStream out) {
        super(out);
    }

    public FastPrinter(Writer out) {
        super(out);
    }

}

import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

public final class devu_and_flowers
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long mod=(long)(1e9+7);

	static long C(long n,long diff)
	{
		long ret=1,upper=n+diff-1;

		for(long x=upper;x>diff;x--)
		{
			long now=x%mod;

			ret=(ret*now)%mod;
		}

		return (ret*pow(fact(n-1),mod-2))%mod;
	}

	static long fact(long n)
	{
		long ret=1;

		for(long i=1;i<=n;i++)
		{
			ret=(ret*i)%mod;
		}

		return ret;
	}

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

	static Map<Long,Long> merge(Map<Long,Long> m1,long now)
	{
		Map<Long,Long> m2=new HashMap<>(),ret=new HashMap<>();

		m2.put(0L,1L);m2.put(now,(-1L+mod)%mod);

		for(Map.Entry<Long,Long> en1:m1.entrySet())
		{
			for(Map.Entry<Long,Long> en2:m2.entrySet())
			{
				long add=en1.getKey()+en2.getKey(),mul=(en1.getValue()*en2.getValue())%mod;

				ret.put(add,(ret.getOrDefault(add,0L)+mul)%mod);
			}
		}

		return ret;
	}

    public static void main(String args[]) throws Exception
    {
		int n=sc.nextInt();long s=sc.nextLong();

		long[] a=new long[n];

		for(int i=0;i<n;i++)
		{
			a[i]=sc.nextLong();
		}

		// 1-x^a[i]+1..

		Map<Long,Long> m1=new HashMap<>();m1.put(0L,1L);

		for(int i=0;i<n;i++)
		{
			m1=merge(m1,a[i]+1);
		}

		long res=0;

		for(Map.Entry<Long,Long> en:m1.entrySet())
		{
			long curr=en.getKey();

			if(curr<=s)
			{
				long diff=s-curr;

				long now=C(n,diff);

				long mul=(en.getValue()*now)%mod;

				res=(res+mul)%mod;
			}
		}

		out.println(res);out.close();
    }

	private static class Pair
	{
		long pow,cof;

		public Pair(long pow,long cof)
		{
			this.pow=pow;this.cof=cof;
		}
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class E_Round_258_Div2 {

	public static long MOD = 1000000007;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		long s = in.nextLong();
		long[] data = new long[n];
		for (int i = 0; i < n; i++) {
			data[i] = in.nextLong();
		}
		long result = cal(s, data);

		out.println(result);
		out.close();
	}

	public static long cal(long need, long[] data) {
		// System.out.println("CALL " + need + " " + total);

		long result = 0;
		for (int i = 0; i < (1 << data.length); i++) {
			long v = need;
			for (int j = 0; j < data.length; j++) {
				if (((1 << j) & i) != 0) {
					v -= (data[j] + 1);
				}
			}
			if (v >= 0) {
				result += (Integer.bitCount(i) % 2 == 0 ? 1 : -1)
						* numberOfWay(v, data.length);
				result = (result + MOD) % MOD;
			}
		}
		// System.out.println(result + " " + need + " " + total + " " +
		// data.length);

		return result;
	}

	public static long numberOfWay(long v, int n) {
		if (v == 0) {
			return 1;
		}
		long x = 1;
		for (long i = v + n - 1; i > v; i--) {
			x *= (i % MOD);
			x %= MOD;
		}
		long y = 1;
		for (long i = 2; i < n; i++) {
			y *= i;
			y %= MOD;
		}
		BigInteger result = BigInteger
				.valueOf(x)
				.multiply(
						BigInteger.valueOf(y).modInverse(
								BigInteger.valueOf(MOD)))
				.mod(BigInteger.valueOf(MOD));
		return result.longValue();
	}

	public static int[] KMP(String val) {
		int i = 0;
		int j = -1;
		int[] result = new int[val.length() + 1];
		result[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(j) != val.charAt(i)) {
				j = result[j];
			}
			j++;
			i++;
			result[i] = j;
		}
		return result;

	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	public static int digit(long n) {
		int result = 0;
		while (n > 0) {
			n /= 10;
			result++;
		}
		return result;
	}

	public static double dist(long a, long b, long x, long y) {
		double val = (b - a) * (b - a) + (x - y) * (x - y);
		val = Math.sqrt(val);
		double other = x * x + a * a;
		other = Math.sqrt(other);
		return val + other;

	}

	public static class Point implements Comparable<Point> {

		int x, y;

		public Point(int start, int end) {
			this.x = start;
			this.y = end;
		}

		@Override
		public int hashCode() {
			int hash = 5;
			hash = 47 * hash + this.x;
			hash = 47 * hash + this.y;
			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			final Point other = (Point) obj;
			if (this.x != other.x) {
				return false;
			}
			if (this.y != other.y) {
				return false;
			}
			return true;
		}

		@Override
		public int compareTo(Point o) {
			return x - o.x;
		}
	}

	public static class FT {

		long[] data;

		FT(int n) {
			data = new long[n];
		}

		public void update(int index, long value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public long get(int index) {
			long result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	public static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static long pow(long a, long b) {
		if (b == 0) {
			return 1;
		}
		if (b == 1) {
			return a;
		}
		long val = pow(a, b / 2);
		if (b % 2 == 0) {
			return val * val % MOD;
		} else {
			return val * (val * a % MOD) % MOD;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

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

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

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

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}
}

import java.awt.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.List;

import static java.lang.Math.max;
import static java.lang.Math.min;

public class E implements Runnable{

    // SOLUTION!!!
    // HACK ME PLEASE IF YOU CAN!!!
    // PLEASE!!!
    // PLEASE!!!
    // PLEASE!!!

    private final static Random rnd = new Random();
    private final static String fileName = "";

    final static long MODULO = 1000 * 1000 * 1000 + 7;

    long inverseNMinus1Factorial;

    private void solve() {
        int n = readInt();
        long s = readLong();

        long[] f = readLongArray(n);

        Map<Long, Long> coeffs = new HashMap<>();
        coeffs.put(0L, 1L);

        for (long size : f) {
            Map<Long, Long> nextCoeffs = new HashMap<>(coeffs);
            for (Map.Entry<Long, Long> coeffEntry : coeffs.entrySet()) {
                long power = coeffEntry.getKey();
                long coeff = coeffEntry.getValue();

                long nextPower = power + size + 1;
                nextCoeffs.put(nextPower,
                        add(nextCoeffs.getOrDefault(nextPower, 0L), -coeff)
                );
            }

            coeffs = nextCoeffs;
        }

        long nMinus1Factorial = multSequence(1, n - 1);
        this.inverseNMinus1Factorial = inverse(nMinus1Factorial);

        long answer = 0;
        for (Map.Entry<Long, Long> coeffEntry : coeffs.entrySet()) {
            long power = coeffEntry.getKey();
            long coeff = coeffEntry.getValue();

            if (s >= power) {
                long need = s - power;
                answer = add(answer, mult(binom(n + need - 1, need), coeff));
            }
        }

        out.println(answer);
    }

    long multSequence(long start, long end) {
        long res = 1;
        for (long i = start; i <= end; ++i) {
            res = mult(res, i);
        }

        return res;
    }

    long inverse(long x) {
        return binpow(x, MODULO - 2);
    }

    long binpow(long base, long power) {
        if (power == 0) return 1;

        if ((power & 1) == 0) {
            long half = binpow(base, power >> 1);
            return mult(half, half);
        } else {
            long prev = binpow(base, power - 1);
            return mult(prev, base);
        }
    }

    long binom(long n, long k) {
        return mult(
                multSequence(k + 1, n),
                inverseNMinus1Factorial
        );
    }

    long add(long a, long b) {
        return ((a % MODULO + b % MODULO) % MODULO + MODULO) % MODULO;
    }

    long mult(long a, long b) {
        return (a % MODULO) * (b % MODULO) % MODULO;
    }

    /////////////////////////////////////////////////////////////////////

    private final static boolean FIRST_INPUT_STRING = false;
    private final static boolean MULTIPLE_TESTS = true;
    private final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

    private final static int MAX_STACK_SIZE = 128;

    private final static boolean OPTIMIZE_READ_NUMBERS = true;

    /////////////////////////////////////////////////////////////////////

    public void run(){
        try{
            timeInit();
            Locale.setDefault(Locale.US);

            init();

            if (ONLINE_JUDGE) {
                solve();
            } else {
                do {
                    try {
                        timeInit();
                        solve();
                        time();

                        out.println();
                    } catch (NumberFormatException e) {
                        break;
                    } catch (NullPointerException e) {
                        if (FIRST_INPUT_STRING) break;
                        else throw e;
                    }
                } while (MULTIPLE_TESTS);
            }

            out.close();
            time();
        }catch (Exception e){
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private BufferedReader in;
    private OutputWriter out;
    private StringTokenizer tok = new StringTokenizer("");

    public static void main(String[] args){
        new Thread(null, new E(), "", MAX_STACK_SIZE * (1L << 20)).start();
    }

    /////////////////////////////////////////////////////////////////////

    private void init() throws FileNotFoundException{
        Locale.setDefault(Locale.US);

        if (ONLINE_JUDGE){
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new OutputWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new OutputWriter(fileName + ".out");
            }
        }else{
            in = new BufferedReader(new FileReader("input.txt"));
            out = new OutputWriter("output.txt");
        }
    }

    ////////////////////////////////////////////////////////////////

    private long timeBegin;

    private void timeInit() {
        this.timeBegin = System.currentTimeMillis();
    }

    private void time(){
        long timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    private void debug(Object... objects){
        if (ONLINE_JUDGE){
            for (Object o: objects){
                System.err.println(o.toString());
            }
        }
    }

    /////////////////////////////////////////////////////////////////////

    private String delim = " ";

    private String readLine() {
        try {
            return in.readLine();
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private String readString() {
        try {
            while(!tok.hasMoreTokens()){
                tok = new StringTokenizer(readLine());
            }

            return tok.nextToken(delim);
        } catch (NullPointerException e) {
            return null;
        }
    }

    /////////////////////////////////////////////////////////////////

    private final char NOT_A_SYMBOL = '\0';

    private char readChar() {
        try {
            int intValue = in.read();

            if (intValue == -1){
                return NOT_A_SYMBOL;
            }

            return (char) intValue;
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private char[] readCharArray() {
        return readLine().toCharArray();
    }

    private char[][] readCharField(int rowsCount) {
        char[][] field = new char[rowsCount][];
        for (int row = 0; row < rowsCount; ++row) {
            field[row] = readCharArray();
        }

        return field;
    }

    /////////////////////////////////////////////////////////////////

    private long optimizedReadLong() {
        int sign = 1;
        long result = 0;
        boolean started = false;
        while (true) {
            try {
                int j = in.read();
                if (-1 == j) {
                    if (started) return sign * result;
                    throw new NumberFormatException();
                }

                if (j == '-') {
                    if (started) throw new NumberFormatException();
                    sign = -sign;
                }

                if ('0' <= j && j <= '9') {
                    result = result * 10 + j - '0';
                    started = true;
                } else if (started) {
                    return sign * result;
                }
            } catch (IOException e) {
                throw new RuntimeIOException(e);
            }
        }
    }

    private int readInt() {

        if (!OPTIMIZE_READ_NUMBERS) {
            return Integer.parseInt(readString());
        } else {
            return (int) optimizedReadLong();
        }
    }

    private int[] readIntArray(int size) {
        int[] array = new int[size];

        for (int index = 0; index < size; ++index){
            array[index] = readInt();
        }

        return array;
    }

    private int[] readSortedIntArray(int size) {
        Integer[] array = new Integer[size];

        for (int index = 0; index < size; ++index) {
            array[index] = readInt();
        }
        Arrays.sort(array);

        int[] sortedArray = new int[size];
        for (int index = 0; index < size; ++index) {
            sortedArray[index] = array[index];
        }

        return sortedArray;
    }

    private int[] readIntArrayWithDecrease(int size) {
        int[] array = readIntArray(size);

        for (int i = 0; i < size; ++i) {
            array[i]--;
        }

        return array;
    }

    ///////////////////////////////////////////////////////////////////

    private int[][] readIntMatrix(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArray(columnsCount);
        }

        return matrix;
    }

    private int[][] readIntMatrixWithDecrease(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArrayWithDecrease(columnsCount);
        }

        return matrix;
    }

    ///////////////////////////////////////////////////////////////////

    private long readLong() {
        if (!OPTIMIZE_READ_NUMBERS) {
            return Long.parseLong(readString());
        } else {
            return optimizedReadLong();
        }
    }

    private long[] readLongArray(int size) {
        long[] array = new long[size];

        for (int index = 0; index < size; ++index){
            array[index] = readLong();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private double readDouble() {
        return Double.parseDouble(readString());
    }

    private double[] readDoubleArray(int size) {
        double[] array = new double[size];

        for (int index = 0; index < size; ++index){
            array[index] = readDouble();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private BigInteger readBigInteger() {
        return new BigInteger(readString());
    }

    private BigDecimal readBigDecimal() {
        return new BigDecimal(readString());
    }

    /////////////////////////////////////////////////////////////////////

    private Point readPoint() {
        int x = readInt();
        int y = readInt();
        return new Point(x, y);
    }

    private Point[] readPointArray(int size) {
        Point[] array = new Point[size];

        for (int index = 0; index < size; ++index){
            array[index] = readPoint();
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    @Deprecated
    private List<Integer>[] readGraph(int vertexNumber, int edgeNumber) {
        @SuppressWarnings("unchecked")
        List<Integer>[] graph = new List[vertexNumber];

        for (int index = 0; index < vertexNumber; ++index){
            graph[index] = new ArrayList<>();
        }

        while (edgeNumber-- > 0){
            int from = readInt() - 1;
            int to = readInt() - 1;

            graph[from].add(to);
            graph[to].add(from);
        }

        return graph;
    }

    private static class GraphBuilder {

        final int size;
        final List<Integer>[] edges;

        static GraphBuilder createInstance(int size) {
            List<Integer>[] edges = new List[size];
            for (int v = 0; v < size; ++v) {
                edges[v] = new ArrayList<>();
            }

            return new GraphBuilder(edges);
        }

        private GraphBuilder(List<Integer>[] edges) {
            this.size = edges.length;
            this.edges = edges;
        }

        public void addEdge(int from, int to) {
            addDirectedEdge(from, to);
            addDirectedEdge(to, from);
        }

        public void addDirectedEdge(int from, int to) {
            edges[from].add(to);
        }

        public int[][] build() {
            int[][] graph = new int[size][];
            for (int v = 0; v < size; ++v) {
                List<Integer> vEdges = edges[v];
                graph[v] = castInt(vEdges);
            }

            return graph;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IntIndexPair {

        static Comparator<IntIndexPair> increaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return value1 - value2;

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        static Comparator<IntIndexPair> decreaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return -(value1 - value2);

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        int value, index;

        IntIndexPair(int value, int index) {
            super();
            this.value = value;
            this.index = index;
        }

        int getRealIndex() {
            return index + 1;
        }
    }

    private IntIndexPair[] readIntIndexArray(int size) {
        IntIndexPair[] array = new IntIndexPair[size];

        for (int index = 0; index < size; ++index) {
            array[index] = new IntIndexPair(readInt(), index);
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    private static class OutputWriter extends PrintWriter {

        final int DEFAULT_PRECISION = 12;

        private int precision;
        private String format, formatWithSpace;

        {
            precision = DEFAULT_PRECISION;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        OutputWriter(OutputStream out) {
            super(out);
        }

        OutputWriter(String fileName) throws FileNotFoundException {
            super(fileName);
        }

        int getPrecision() {
            return precision;
        }

        void setPrecision(int precision) {
            precision = max(0, precision);
            this.precision = precision;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        String createFormat(int precision){
            return "%." + precision + "f";
        }

        @Override
        public void print(double d){
            printf(format, d);
        }

        void printWithSpace(double d){
            printf(formatWithSpace, d);
        }

        void printAll(double...d){
            for (int i = 0; i < d.length - 1; ++i){
                printWithSpace(d[i]);
            }

            print(d[d.length - 1]);
        }

        @Override
        public void println(double d){
            printlnAll(d);
        }

        void printlnAll(double... d){
            printAll(d);
            println();
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class RuntimeIOException extends RuntimeException {

        /**
         *
         */
        private static final long serialVersionUID = -6463830523020118289L;

        RuntimeIOException(Throwable cause) {
            super(cause);
        }
    }

    /////////////////////////////////////////////////////////////////////
    //////////////// Some useful constants and functions ////////////////
    /////////////////////////////////////////////////////////////////////

    private static final int[][] steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    private static final int[][] steps8 = {
            {-1, 0}, {1, 0}, {0, -1}, {0, 1},
            {-1, -1}, {1, 1}, {1, -1}, {-1, 1}
    };

    private static boolean checkCell(int row, int rowsCount, int column, int columnsCount) {
        return checkIndex(row, rowsCount) && checkIndex(column, columnsCount);
    }

    private static boolean checkIndex(int index, int lim){
        return (0 <= index && index < lim);
    }

    /////////////////////////////////////////////////////////////////////

    private static boolean checkBit(int mask, int bit){
        return (mask & (1 << bit)) != 0;
    }
    private static boolean checkBit(long mask, int bit){
        return (mask & (1L << bit)) != 0;
    }

    /////////////////////////////////////////////////////////////////////

    private static long getSum(int[] array) {
        long sum = 0;
        for (int value: array) {
            sum += value;
        }

        return sum;
    }

    private static Point getMinMax(int[] array) {
        int min = array[0];
        int max = array[0];

        for (int index = 0, size = array.length; index < size; ++index, ++index) {
            int value = array[index];

            if (index == size - 1) {
                min = min(min, value);
                max = max(max, value);
            } else {
                int otherValue = array[index + 1];

                if (value <= otherValue) {
                    min = min(min, value);
                    max = max(max, otherValue);
                } else {
                    min = min(min, otherValue);
                    max = max(max, value);
                }
            }
        }

        return new Point(min, max);
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] getPrimes(int n) {
        boolean[] used = new boolean[n];
        used[0] = used[1] = true;

        int size = 0;
        for (int i = 2; i < n; ++i) {
            if (!used[i]) {
                ++size;
                for (int j = 2 * i; j < n; j += i) {
                    used[j] = true;
                }
            }
        }

        int[] primes = new int[size];
        for (int i = 0, cur = 0; i < n; ++i) {
            if (!used[i]) {
                primes[cur++] = i;
            }
        }

        return primes;
    }

    /////////////////////////////////////////////////////////////////////

    private static long lcm(long a, long b) {
        return a / gcd(a, b) * b;
    }

    private static long gcd(long a, long b) {
        return (a == 0 ? b : gcd(b % a, a));
    }

    /////////////////////////////////////////////////////////////////////

    private static class MultiSet<ValueType> {

        public static <ValueType> MultiSet<ValueType> createMultiSet() {
            Map<ValueType, Integer> multiset = new HashMap<>();
            return new MultiSet<>(multiset);
        }

        private final Map<ValueType, Integer> multiset;
        private int size;

        public MultiSet(Map<ValueType, Integer> multiset) {
            this.multiset = multiset;
            this.size = 0;
        }

        public int size() {
            return size;
        }

        public void inc(ValueType value) {
            int count = get(value);
            multiset.put(value, count + 1);

            ++size;
        }

        public void dec(ValueType value) {
            int count = get(value);
            if (count == 0) return;

            if (count == 1) multiset.remove(value);
            else multiset.put(value, count - 1);

            --size;
        }

        public int get(ValueType value) {
            Integer count = multiset.get(value);
            return (count == null ? 0 : count);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IdMap<KeyType> extends HashMap<KeyType, Integer> {

        /**
         *
         */
        private static final long serialVersionUID = -3793737771950984481L;

        public IdMap() {
            super();
        }

        int getId(KeyType key) {
            Integer id = super.get(key);
            if (id == null) {
                super.put(key, id = size());
            }

            return id;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] castInt(List<Integer> list) {
        int[] array = new int[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }

    private static long[] castLong(List<Long> list) {
        long[] array = new long[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }
}

import java.awt.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.List;

import static java.lang.Math.max;
import static java.lang.Math.min;

public class E implements Runnable{

    // SOLUTION!!!
    // HACK ME PLEASE IF YOU CAN!!!
    // PLEASE!!!
    // PLEASE!!!
    // PLEASE!!!

    private final static Random rnd = new Random();
    private final static String fileName = "";

    final static long MODULO = 1000 * 1000 * 1000 + 7;

    long inverseNMinus1Factorial;

    private void solve() {
        int n = readInt();
        long s = readLong();

        long[] f = readLongArray(n);

        Map<Long, Long> coeffs = new HashMap<>();
        coeffs.put(0L, 1L);

        class Pair {
            long power, coeff;

            public Pair(long power, long coeff) {
                this.power = power;
                this.coeff = coeff;
            }
        }

        for (long size : f) {
            List<Pair> coeffEntries = new ArrayList<>();
            for (Map.Entry<Long, Long> coeffEntry : coeffs.entrySet()) {
                long power = coeffEntry.getKey();
                long coeff = coeffEntry.getValue();

                long nextPower = power + size + 1;
                coeffEntries.add(
                    new Pair(
                        nextPower, -coeff
                    )
                );
            }

            for (Pair coeffEntry : coeffEntries) {
                coeffs.put(coeffEntry.power,
                        add(coeffs.getOrDefault(coeffEntry.power, 0L), coeffEntry.coeff)
                );
            }
        }

        long nMinus1Factorial = multSequence(1, n - 1);
        this.inverseNMinus1Factorial = inverse(nMinus1Factorial);

        long answer = 0;
        for (Map.Entry<Long, Long> coeffEntry : coeffs.entrySet()) {
            long power = coeffEntry.getKey();
            long coeff = coeffEntry.getValue();

            if (s >= power) {
                long need = s - power;
                answer = add(answer, mult(binom(n + need - 1, need), coeff));
            }
        }

        out.println(answer);
    }

    long multSequence(long start, long end) {
        long res = 1;
        for (long i = start; i <= end; ++i) {
            res = mult(res, i);
        }

        return res;
    }

    long inverse(long x) {
        return binpow(x, MODULO - 2);
    }

    long binpow(long base, long power) {
        if (power == 0) return 1;

        if ((power & 1) == 0) {
            long half = binpow(base, power >> 1);
            return mult(half, half);
        } else {
            long prev = binpow(base, power - 1);
            return mult(prev, base);
        }
    }

    long binom(long n, long k) {
        return mult(
                multSequence(k + 1, n),
                inverseNMinus1Factorial
        );
    }

    long add(long a, long b) {
        return ((a % MODULO + b % MODULO) % MODULO + MODULO) % MODULO;
    }

    long mult(long a, long b) {
        return (a % MODULO) * (b % MODULO) % MODULO;
    }

    /////////////////////////////////////////////////////////////////////

    private final static boolean FIRST_INPUT_STRING = false;
    private final static boolean MULTIPLE_TESTS = true;
    private final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

    private final static int MAX_STACK_SIZE = 128;

    private final static boolean OPTIMIZE_READ_NUMBERS = true;

    /////////////////////////////////////////////////////////////////////

    public void run(){
        try{
            timeInit();
            Locale.setDefault(Locale.US);

            init();

            if (ONLINE_JUDGE) {
                solve();
            } else {
                do {
                    try {
                        timeInit();
                        solve();
                        time();

                        out.println();
                    } catch (NumberFormatException e) {
                        break;
                    } catch (NullPointerException e) {
                        if (FIRST_INPUT_STRING) break;
                        else throw e;
                    }
                } while (MULTIPLE_TESTS);
            }

            out.close();
            time();
        }catch (Exception e){
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private BufferedReader in;
    private OutputWriter out;
    private StringTokenizer tok = new StringTokenizer("");

    public static void main(String[] args){
        new Thread(null, new E(), "", MAX_STACK_SIZE * (1L << 20)).start();
    }

    /////////////////////////////////////////////////////////////////////

    private void init() throws FileNotFoundException{
        Locale.setDefault(Locale.US);

        if (ONLINE_JUDGE){
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new OutputWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new OutputWriter(fileName + ".out");
            }
        }else{
            in = new BufferedReader(new FileReader("input.txt"));
            out = new OutputWriter("output.txt");
        }
    }

    ////////////////////////////////////////////////////////////////

    private long timeBegin;

    private void timeInit() {
        this.timeBegin = System.currentTimeMillis();
    }

    private void time(){
        long timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    private void debug(Object... objects){
        if (ONLINE_JUDGE){
            for (Object o: objects){
                System.err.println(o.toString());
            }
        }
    }

    /////////////////////////////////////////////////////////////////////

    private String delim = " ";

    private String readLine() {
        try {
            return in.readLine();
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private String readString() {
        try {
            while(!tok.hasMoreTokens()){
                tok = new StringTokenizer(readLine());
            }

            return tok.nextToken(delim);
        } catch (NullPointerException e) {
            return null;
        }
    }

    /////////////////////////////////////////////////////////////////

    private final char NOT_A_SYMBOL = '\0';

    private char readChar() {
        try {
            int intValue = in.read();

            if (intValue == -1){
                return NOT_A_SYMBOL;
            }

            return (char) intValue;
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private char[] readCharArray() {
        return readLine().toCharArray();
    }

    private char[][] readCharField(int rowsCount) {
        char[][] field = new char[rowsCount][];
        for (int row = 0; row < rowsCount; ++row) {
            field[row] = readCharArray();
        }

        return field;
    }

    /////////////////////////////////////////////////////////////////

    private long optimizedReadLong() {
        int sign = 1;
        long result = 0;
        boolean started = false;
        while (true) {
            try {
                int j = in.read();
                if (-1 == j) {
                    if (started) return sign * result;
                    throw new NumberFormatException();
                }

                if (j == '-') {
                    if (started) throw new NumberFormatException();
                    sign = -sign;
                }

                if ('0' <= j && j <= '9') {
                    result = result * 10 + j - '0';
                    started = true;
                } else if (started) {
                    return sign * result;
                }
            } catch (IOException e) {
                throw new RuntimeIOException(e);
            }
        }
    }

    private int readInt() {

        if (!OPTIMIZE_READ_NUMBERS) {
            return Integer.parseInt(readString());
        } else {
            return (int) optimizedReadLong();
        }
    }

    private int[] readIntArray(int size) {
        int[] array = new int[size];

        for (int index = 0; index < size; ++index){
            array[index] = readInt();
        }

        return array;
    }

    private int[] readSortedIntArray(int size) {
        Integer[] array = new Integer[size];

        for (int index = 0; index < size; ++index) {
            array[index] = readInt();
        }
        Arrays.sort(array);

        int[] sortedArray = new int[size];
        for (int index = 0; index < size; ++index) {
            sortedArray[index] = array[index];
        }

        return sortedArray;
    }

    private int[] readIntArrayWithDecrease(int size) {
        int[] array = readIntArray(size);

        for (int i = 0; i < size; ++i) {
            array[i]--;
        }

        return array;
    }

    ///////////////////////////////////////////////////////////////////

    private int[][] readIntMatrix(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArray(columnsCount);
        }

        return matrix;
    }

    private int[][] readIntMatrixWithDecrease(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArrayWithDecrease(columnsCount);
        }

        return matrix;
    }

    ///////////////////////////////////////////////////////////////////

    private long readLong() {
        if (!OPTIMIZE_READ_NUMBERS) {
            return Long.parseLong(readString());
        } else {
            return optimizedReadLong();
        }
    }

    private long[] readLongArray(int size) {
        long[] array = new long[size];

        for (int index = 0; index < size; ++index){
            array[index] = readLong();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private double readDouble() {
        return Double.parseDouble(readString());
    }

    private double[] readDoubleArray(int size) {
        double[] array = new double[size];

        for (int index = 0; index < size; ++index){
            array[index] = readDouble();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private BigInteger readBigInteger() {
        return new BigInteger(readString());
    }

    private BigDecimal readBigDecimal() {
        return new BigDecimal(readString());
    }

    /////////////////////////////////////////////////////////////////////

    private Point readPoint() {
        int x = readInt();
        int y = readInt();
        return new Point(x, y);
    }

    private Point[] readPointArray(int size) {
        Point[] array = new Point[size];

        for (int index = 0; index < size; ++index){
            array[index] = readPoint();
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    @Deprecated
    private List<Integer>[] readGraph(int vertexNumber, int edgeNumber) {
        @SuppressWarnings("unchecked")
        List<Integer>[] graph = new List[vertexNumber];

        for (int index = 0; index < vertexNumber; ++index){
            graph[index] = new ArrayList<>();
        }

        while (edgeNumber-- > 0){
            int from = readInt() - 1;
            int to = readInt() - 1;

            graph[from].add(to);
            graph[to].add(from);
        }

        return graph;
    }

    private static class GraphBuilder {

        final int size;
        final List<Integer>[] edges;

        static GraphBuilder createInstance(int size) {
            List<Integer>[] edges = new List[size];
            for (int v = 0; v < size; ++v) {
                edges[v] = new ArrayList<>();
            }

            return new GraphBuilder(edges);
        }

        private GraphBuilder(List<Integer>[] edges) {
            this.size = edges.length;
            this.edges = edges;
        }

        public void addEdge(int from, int to) {
            addDirectedEdge(from, to);
            addDirectedEdge(to, from);
        }

        public void addDirectedEdge(int from, int to) {
            edges[from].add(to);
        }

        public int[][] build() {
            int[][] graph = new int[size][];
            for (int v = 0; v < size; ++v) {
                List<Integer> vEdges = edges[v];
                graph[v] = castInt(vEdges);
            }

            return graph;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IntIndexPair {

        static Comparator<IntIndexPair> increaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return value1 - value2;

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        static Comparator<IntIndexPair> decreaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return -(value1 - value2);

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        int value, index;

        IntIndexPair(int value, int index) {
            super();
            this.value = value;
            this.index = index;
        }

        int getRealIndex() {
            return index + 1;
        }
    }

    private IntIndexPair[] readIntIndexArray(int size) {
        IntIndexPair[] array = new IntIndexPair[size];

        for (int index = 0; index < size; ++index) {
            array[index] = new IntIndexPair(readInt(), index);
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    private static class OutputWriter extends PrintWriter {

        final int DEFAULT_PRECISION = 12;

        private int precision;
        private String format, formatWithSpace;

        {
            precision = DEFAULT_PRECISION;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        OutputWriter(OutputStream out) {
            super(out);
        }

        OutputWriter(String fileName) throws FileNotFoundException {
            super(fileName);
        }

        int getPrecision() {
            return precision;
        }

        void setPrecision(int precision) {
            precision = max(0, precision);
            this.precision = precision;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        String createFormat(int precision){
            return "%." + precision + "f";
        }

        @Override
        public void print(double d){
            printf(format, d);
        }

        void printWithSpace(double d){
            printf(formatWithSpace, d);
        }

        void printAll(double...d){
            for (int i = 0; i < d.length - 1; ++i){
                printWithSpace(d[i]);
            }

            print(d[d.length - 1]);
        }

        @Override
        public void println(double d){
            printlnAll(d);
        }

        void printlnAll(double... d){
            printAll(d);
            println();
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class RuntimeIOException extends RuntimeException {

        /**
         *
         */
        private static final long serialVersionUID = -6463830523020118289L;

        RuntimeIOException(Throwable cause) {
            super(cause);
        }
    }

    /////////////////////////////////////////////////////////////////////
    //////////////// Some useful constants and functions ////////////////
    /////////////////////////////////////////////////////////////////////

    private static final int[][] steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    private static final int[][] steps8 = {
            {-1, 0}, {1, 0}, {0, -1}, {0, 1},
            {-1, -1}, {1, 1}, {1, -1}, {-1, 1}
    };

    private static boolean checkCell(int row, int rowsCount, int column, int columnsCount) {
        return checkIndex(row, rowsCount) && checkIndex(column, columnsCount);
    }

    private static boolean checkIndex(int index, int lim){
        return (0 <= index && index < lim);
    }

    /////////////////////////////////////////////////////////////////////

    private static boolean checkBit(int mask, int bit){
        return (mask & (1 << bit)) != 0;
    }
    private static boolean checkBit(long mask, int bit){
        return (mask & (1L << bit)) != 0;
    }

    /////////////////////////////////////////////////////////////////////

    private static long getSum(int[] array) {
        long sum = 0;
        for (int value: array) {
            sum += value;
        }

        return sum;
    }

    private static Point getMinMax(int[] array) {
        int min = array[0];
        int max = array[0];

        for (int index = 0, size = array.length; index < size; ++index, ++index) {
            int value = array[index];

            if (index == size - 1) {
                min = min(min, value);
                max = max(max, value);
            } else {
                int otherValue = array[index + 1];

                if (value <= otherValue) {
                    min = min(min, value);
                    max = max(max, otherValue);
                } else {
                    min = min(min, otherValue);
                    max = max(max, value);
                }
            }
        }

        return new Point(min, max);
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] getPrimes(int n) {
        boolean[] used = new boolean[n];
        used[0] = used[1] = true;

        int size = 0;
        for (int i = 2; i < n; ++i) {
            if (!used[i]) {
                ++size;
                for (int j = 2 * i; j < n; j += i) {
                    used[j] = true;
                }
            }
        }

        int[] primes = new int[size];
        for (int i = 0, cur = 0; i < n; ++i) {
            if (!used[i]) {
                primes[cur++] = i;
            }
        }

        return primes;
    }

    /////////////////////////////////////////////////////////////////////

    private static long lcm(long a, long b) {
        return a / gcd(a, b) * b;
    }

    private static long gcd(long a, long b) {
        return (a == 0 ? b : gcd(b % a, a));
    }

    /////////////////////////////////////////////////////////////////////

    private static class MultiSet<ValueType> {

        public static <ValueType> MultiSet<ValueType> createMultiSet() {
            Map<ValueType, Integer> multiset = new HashMap<>();
            return new MultiSet<>(multiset);
        }

        private final Map<ValueType, Integer> multiset;
        private int size;

        public MultiSet(Map<ValueType, Integer> multiset) {
            this.multiset = multiset;
            this.size = 0;
        }

        public int size() {
            return size;
        }

        public void inc(ValueType value) {
            int count = get(value);
            multiset.put(value, count + 1);

            ++size;
        }

        public void dec(ValueType value) {
            int count = get(value);
            if (count == 0) return;

            if (count == 1) multiset.remove(value);
            else multiset.put(value, count - 1);

            --size;
        }

        public int get(ValueType value) {
            Integer count = multiset.get(value);
            return (count == null ? 0 : count);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IdMap<KeyType> extends HashMap<KeyType, Integer> {

        /**
         *
         */
        private static final long serialVersionUID = -3793737771950984481L;

        public IdMap() {
            super();
        }

        int getId(KeyType key) {
            Integer id = super.get(key);
            if (id == null) {
                super.put(key, id = size());
            }

            return id;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] castInt(List<Integer> list) {
        int[] array = new int[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }

    private static long[] castLong(List<Long> list) {
        long[] array = new long[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }
}

import java.awt.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.List;

import static java.lang.Math.max;
import static java.lang.Math.min;

public class E implements Runnable{

    // SOLUTION!!!
    // HACK ME PLEASE IF YOU CAN!!!
    // PLEASE!!!
    // PLEASE!!!
    // PLEASE!!!

    private final static Random rnd = new Random();
    private final static String fileName = "";

    final static long MODULO = 1000 * 1000 * 1000 + 7;

    long inverseNMinus1Factorial;

    void generate(long[] f, Map<Long, Long> coeffs, int index, long power, long coeff) {
        if (index == f.length) {
            coeffs.put(
                    power,
                    add(coeffs.getOrDefault(power, 0L), coeff)
            );
        } else {
            generate(f, coeffs, index + 1, power, coeff);
            generate(f, coeffs, index + 1, power + f[index] + 1, -coeff);
        }
    }

    private void solve() {
        int n = readInt();
        long s = readLong();

        long[] f = readLongArray(n);

        Map<Long, Long> coeffs = new HashMap<>();

        generate(f, coeffs, 0, 0, 1);

        long nMinus1Factorial = multSequence(1, n - 1);
        this.inverseNMinus1Factorial = inverse(nMinus1Factorial);

        long answer = 0;
        for (Map.Entry<Long, Long> coeffEntry : coeffs.entrySet()) {
            long power = coeffEntry.getKey();
            long coeff = coeffEntry.getValue();

            if (s >= power) {
                long need = s - power;
                answer = add(answer, mult(binom(n + need - 1, need), coeff));
            }
        }

        out.println(answer);
    }

    long multSequence(long start, long end) {
        long res = 1;
        for (long i = start; i <= end; ++i) {
            res = mult(res, i);
        }

        return res;
    }

    long inverse(long x) {
        return binpow(x, MODULO - 2);
    }

    long binpow(long base, long power) {
        if (power == 0) return 1;

        if ((power & 1) == 0) {
            long half = binpow(base, power >> 1);
            return mult(half, half);
        } else {
            long prev = binpow(base, power - 1);
            return mult(prev, base);
        }
    }

    long binom(long n, long k) {
        return mult(
                multSequence(k + 1, n),
                inverseNMinus1Factorial
        );
    }

    long add(long a, long b) {
        return ((a % MODULO + b % MODULO) % MODULO + MODULO) % MODULO;
    }

    long mult(long a, long b) {
        return (a % MODULO) * (b % MODULO) % MODULO;
    }

    /////////////////////////////////////////////////////////////////////

    private final static boolean FIRST_INPUT_STRING = false;
    private final static boolean MULTIPLE_TESTS = true;
    private final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

    private final static int MAX_STACK_SIZE = 128;

    private final static boolean OPTIMIZE_READ_NUMBERS = true;

    /////////////////////////////////////////////////////////////////////

    public void run(){
        try{
            timeInit();
            Locale.setDefault(Locale.US);

            init();

            if (ONLINE_JUDGE) {
                solve();
            } else {
                do {
                    try {
                        timeInit();
                        solve();
                        time();

                        out.println();
                    } catch (NumberFormatException e) {
                        break;
                    } catch (NullPointerException e) {
                        if (FIRST_INPUT_STRING) break;
                        else throw e;
                    }
                } while (MULTIPLE_TESTS);
            }

            out.close();
            time();
        }catch (Exception e){
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private BufferedReader in;
    private OutputWriter out;
    private StringTokenizer tok = new StringTokenizer("");

    public static void main(String[] args){
        new Thread(null, new E(), "", MAX_STACK_SIZE * (1L << 20)).start();
    }

    /////////////////////////////////////////////////////////////////////

    private void init() throws FileNotFoundException{
        Locale.setDefault(Locale.US);

        if (ONLINE_JUDGE){
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new OutputWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new OutputWriter(fileName + ".out");
            }
        }else{
            in = new BufferedReader(new FileReader("input.txt"));
            out = new OutputWriter("output.txt");
        }
    }

    ////////////////////////////////////////////////////////////////

    private long timeBegin;

    private void timeInit() {
        this.timeBegin = System.currentTimeMillis();
    }

    private void time(){
        long timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    private void debug(Object... objects){
        if (ONLINE_JUDGE){
            for (Object o: objects){
                System.err.println(o.toString());
            }
        }
    }

    /////////////////////////////////////////////////////////////////////

    private String delim = " ";

    private String readLine() {
        try {
            return in.readLine();
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private String readString() {
        try {
            while(!tok.hasMoreTokens()){
                tok = new StringTokenizer(readLine());
            }

            return tok.nextToken(delim);
        } catch (NullPointerException e) {
            return null;
        }
    }

    /////////////////////////////////////////////////////////////////

    private final char NOT_A_SYMBOL = '\0';

    private char readChar() {
        try {
            int intValue = in.read();

            if (intValue == -1){
                return NOT_A_SYMBOL;
            }

            return (char) intValue;
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private char[] readCharArray() {
        return readLine().toCharArray();
    }

    private char[][] readCharField(int rowsCount) {
        char[][] field = new char[rowsCount][];
        for (int row = 0; row < rowsCount; ++row) {
            field[row] = readCharArray();
        }

        return field;
    }

    /////////////////////////////////////////////////////////////////

    private long optimizedReadLong() {
        int sign = 1;
        long result = 0;
        boolean started = false;
        while (true) {
            try {
                int j = in.read();
                if (-1 == j) {
                    if (started) return sign * result;
                    throw new NumberFormatException();
                }

                if (j == '-') {
                    if (started) throw new NumberFormatException();
                    sign = -sign;
                }

                if ('0' <= j && j <= '9') {
                    result = result * 10 + j - '0';
                    started = true;
                } else if (started) {
                    return sign * result;
                }
            } catch (IOException e) {
                throw new RuntimeIOException(e);
            }
        }
    }

    private int readInt() {

        if (!OPTIMIZE_READ_NUMBERS) {
            return Integer.parseInt(readString());
        } else {
            return (int) optimizedReadLong();
        }
    }

    private int[] readIntArray(int size) {
        int[] array = new int[size];

        for (int index = 0; index < size; ++index){
            array[index] = readInt();
        }

        return array;
    }

    private int[] readSortedIntArray(int size) {
        Integer[] array = new Integer[size];

        for (int index = 0; index < size; ++index) {
            array[index] = readInt();
        }
        Arrays.sort(array);

        int[] sortedArray = new int[size];
        for (int index = 0; index < size; ++index) {
            sortedArray[index] = array[index];
        }

        return sortedArray;
    }

    private int[] readIntArrayWithDecrease(int size) {
        int[] array = readIntArray(size);

        for (int i = 0; i < size; ++i) {
            array[i]--;
        }

        return array;
    }

    ///////////////////////////////////////////////////////////////////

    private int[][] readIntMatrix(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArray(columnsCount);
        }

        return matrix;
    }

    private int[][] readIntMatrixWithDecrease(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArrayWithDecrease(columnsCount);
        }

        return matrix;
    }

    ///////////////////////////////////////////////////////////////////

    private long readLong() {
        if (!OPTIMIZE_READ_NUMBERS) {
            return Long.parseLong(readString());
        } else {
            return optimizedReadLong();
        }
    }

    private long[] readLongArray(int size) {
        long[] array = new long[size];

        for (int index = 0; index < size; ++index){
            array[index] = readLong();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private double readDouble() {
        return Double.parseDouble(readString());
    }

    private double[] readDoubleArray(int size) {
        double[] array = new double[size];

        for (int index = 0; index < size; ++index){
            array[index] = readDouble();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private BigInteger readBigInteger() {
        return new BigInteger(readString());
    }

    private BigDecimal readBigDecimal() {
        return new BigDecimal(readString());
    }

    /////////////////////////////////////////////////////////////////////

    private Point readPoint() {
        int x = readInt();
        int y = readInt();
        return new Point(x, y);
    }

    private Point[] readPointArray(int size) {
        Point[] array = new Point[size];

        for (int index = 0; index < size; ++index){
            array[index] = readPoint();
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    @Deprecated
    private List<Integer>[] readGraph(int vertexNumber, int edgeNumber) {
        @SuppressWarnings("unchecked")
        List<Integer>[] graph = new List[vertexNumber];

        for (int index = 0; index < vertexNumber; ++index){
            graph[index] = new ArrayList<>();
        }

        while (edgeNumber-- > 0){
            int from = readInt() - 1;
            int to = readInt() - 1;

            graph[from].add(to);
            graph[to].add(from);
        }

        return graph;
    }

    private static class GraphBuilder {

        final int size;
        final List<Integer>[] edges;

        static GraphBuilder createInstance(int size) {
            List<Integer>[] edges = new List[size];
            for (int v = 0; v < size; ++v) {
                edges[v] = new ArrayList<>();
            }

            return new GraphBuilder(edges);
        }

        private GraphBuilder(List<Integer>[] edges) {
            this.size = edges.length;
            this.edges = edges;
        }

        public void addEdge(int from, int to) {
            addDirectedEdge(from, to);
            addDirectedEdge(to, from);
        }

        public void addDirectedEdge(int from, int to) {
            edges[from].add(to);
        }

        public int[][] build() {
            int[][] graph = new int[size][];
            for (int v = 0; v < size; ++v) {
                List<Integer> vEdges = edges[v];
                graph[v] = castInt(vEdges);
            }

            return graph;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IntIndexPair {

        static Comparator<IntIndexPair> increaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return value1 - value2;

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        static Comparator<IntIndexPair> decreaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return -(value1 - value2);

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        int value, index;

        IntIndexPair(int value, int index) {
            super();
            this.value = value;
            this.index = index;
        }

        int getRealIndex() {
            return index + 1;
        }
    }

    private IntIndexPair[] readIntIndexArray(int size) {
        IntIndexPair[] array = new IntIndexPair[size];

        for (int index = 0; index < size; ++index) {
            array[index] = new IntIndexPair(readInt(), index);
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    private static class OutputWriter extends PrintWriter {

        final int DEFAULT_PRECISION = 12;

        private int precision;
        private String format, formatWithSpace;

        {
            precision = DEFAULT_PRECISION;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        OutputWriter(OutputStream out) {
            super(out);
        }

        OutputWriter(String fileName) throws FileNotFoundException {
            super(fileName);
        }

        int getPrecision() {
            return precision;
        }

        void setPrecision(int precision) {
            precision = max(0, precision);
            this.precision = precision;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        String createFormat(int precision){
            return "%." + precision + "f";
        }

        @Override
        public void print(double d){
            printf(format, d);
        }

        void printWithSpace(double d){
            printf(formatWithSpace, d);
        }

        void printAll(double...d){
            for (int i = 0; i < d.length - 1; ++i){
                printWithSpace(d[i]);
            }

            print(d[d.length - 1]);
        }

        @Override
        public void println(double d){
            printlnAll(d);
        }

        void printlnAll(double... d){
            printAll(d);
            println();
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class RuntimeIOException extends RuntimeException {

        /**
         *
         */
        private static final long serialVersionUID = -6463830523020118289L;

        RuntimeIOException(Throwable cause) {
            super(cause);
        }
    }

    /////////////////////////////////////////////////////////////////////
    //////////////// Some useful constants and functions ////////////////
    /////////////////////////////////////////////////////////////////////

    private static final int[][] steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    private static final int[][] steps8 = {
            {-1, 0}, {1, 0}, {0, -1}, {0, 1},
            {-1, -1}, {1, 1}, {1, -1}, {-1, 1}
    };

    private static boolean checkCell(int row, int rowsCount, int column, int columnsCount) {
        return checkIndex(row, rowsCount) && checkIndex(column, columnsCount);
    }

    private static boolean checkIndex(int index, int lim){
        return (0 <= index && index < lim);
    }

    /////////////////////////////////////////////////////////////////////

    private static boolean checkBit(int mask, int bit){
        return (mask & (1 << bit)) != 0;
    }
    private static boolean checkBit(long mask, int bit){
        return (mask & (1L << bit)) != 0;
    }

    /////////////////////////////////////////////////////////////////////

    private static long getSum(int[] array) {
        long sum = 0;
        for (int value: array) {
            sum += value;
        }

        return sum;
    }

    private static Point getMinMax(int[] array) {
        int min = array[0];
        int max = array[0];

        for (int index = 0, size = array.length; index < size; ++index, ++index) {
            int value = array[index];

            if (index == size - 1) {
                min = min(min, value);
                max = max(max, value);
            } else {
                int otherValue = array[index + 1];

                if (value <= otherValue) {
                    min = min(min, value);
                    max = max(max, otherValue);
                } else {
                    min = min(min, otherValue);
                    max = max(max, value);
                }
            }
        }

        return new Point(min, max);
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] getPrimes(int n) {
        boolean[] used = new boolean[n];
        used[0] = used[1] = true;

        int size = 0;
        for (int i = 2; i < n; ++i) {
            if (!used[i]) {
                ++size;
                for (int j = 2 * i; j < n; j += i) {
                    used[j] = true;
                }
            }
        }

        int[] primes = new int[size];
        for (int i = 0, cur = 0; i < n; ++i) {
            if (!used[i]) {
                primes[cur++] = i;
            }
        }

        return primes;
    }

    /////////////////////////////////////////////////////////////////////

    private static long lcm(long a, long b) {
        return a / gcd(a, b) * b;
    }

    private static long gcd(long a, long b) {
        return (a == 0 ? b : gcd(b % a, a));
    }

    /////////////////////////////////////////////////////////////////////

    private static class MultiSet<ValueType> {

        public static <ValueType> MultiSet<ValueType> createMultiSet() {
            Map<ValueType, Integer> multiset = new HashMap<>();
            return new MultiSet<>(multiset);
        }

        private final Map<ValueType, Integer> multiset;
        private int size;

        public MultiSet(Map<ValueType, Integer> multiset) {
            this.multiset = multiset;
            this.size = 0;
        }

        public int size() {
            return size;
        }

        public void inc(ValueType value) {
            int count = get(value);
            multiset.put(value, count + 1);

            ++size;
        }

        public void dec(ValueType value) {
            int count = get(value);
            if (count == 0) return;

            if (count == 1) multiset.remove(value);
            else multiset.put(value, count - 1);

            --size;
        }

        public int get(ValueType value) {
            Integer count = multiset.get(value);
            return (count == null ? 0 : count);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IdMap<KeyType> extends HashMap<KeyType, Integer> {

        /**
         *
         */
        private static final long serialVersionUID = -3793737771950984481L;

        public IdMap() {
            super();
        }

        int getId(KeyType key) {
            Integer id = super.get(key);
            if (id == null) {
                super.put(key, id = size());
            }

            return id;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] castInt(List<Integer> list) {
        int[] array = new int[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }

    private static long[] castLong(List<Long> list) {
        long[] array = new long[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author aryssoncf
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskE {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            try {
                int n = in.readInt();
                long s = in.readLong();
                long[] f = in.readLongArray(n);
                MiscUtils.increaseByOne(f);
                long res = 0;
                for (int mask = 0; mask < (1 << n); mask++) {
                    long k = 0;
                    int sign = 1;
                    for (int i = 0; i < n; i++) {
                        if (((mask >> i) & 1) == 1) {
                            k += f[i];
                            sign *= -1;
                        }
                    }
                    if (k > s) {
                        continue;
                    }
                    long rem = s - k, coef = IntegerUtils.binomialCoefficient(rem + n - 1, rem, MiscUtils.MOD7);
                    res = IntegerUtils.trueMod(res + sign * coef, MiscUtils.MOD7);
                }
                out.printLine(res);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    static class MiscUtils {
        public static final int MOD7 = (int) (1e9 + 7);

        public static void increaseByOne(long[]... arrays) {
            for (long[] array : arrays) {
                for (int i = 0; i < array.length; i++) {
                    array[i]++;
                }
            }
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public long[] readLongArray(int size) {
            long[] array = new long[size];
            for (int i = 0; i < size; i++) {
                array[i] = readLong();
            }
            return array;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long readLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(long i) {
            writer.println(i);
        }

    }

    static class IntegerUtils {
        private static long _x;
        private static long _y;

        public static long trueMod(long a, long b) {
            a %= b;
            a += b;
            a %= b;
            return a;
        }

        public static long factorial(int n, long mod) {
            long result = 1;
            for (int i = 2; i <= n; i++) {
                result = result * i % mod;
            }
            return result % mod;
        }

        public static long reverse(long number, long modulo) {
            extGcd(number, modulo);
            return trueMod(_x, modulo);
        }

        private static long extGcd(long a, long b) {
            if (a == 0) {
                _x = 0;
                _y = 1;
                return b;
            }
            long d = extGcd(b % a, a);
            long nx = _y - (b / a) * _x;
            //noinspection SuspiciousNameCombination
            _y = _x;
            _x = nx;
            return d;
        }

        public static long binomialCoefficient(long n, long m, long mod) {
            if (m < 0 || m > n) {
                return 0;
            }
            if (2 * m > n) {
                m = n - m;
            }
            long result = 1;
            for (long i = n - m + 1; i <= n; i++) {
                result = result * (i % mod) % mod;
            }
            return result * reverse(factorial((int) m, mod), mod) % mod;
        }

    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Task451E {

	private static final int MOD = 1000000007;

	private FastScanner in;
	private PrintWriter out;

	private long inverseNMinusOneFactorial;

	public Task451E(InputStream in, OutputStream out) {
		this.in = new FastScanner(in);
		this.out = new PrintWriter(out);
	}

	public void solve() throws IOException {
		int n = nextInt();
		long s = nextLong();
		long f[] = new long[n];
		for (int i = 0; i < n; ++i) {
			f[i] = nextLong();
		}
		preCalc(n);
		long result = c(n + s - 1, n - 1);
		mask:
		for (int mask = 1; mask < (1 << n); ++mask) {
			long restS = s;
			boolean subtract = false;
			for (int bit = 0; bit < n; ++bit) {
				if (((1 << bit) & mask) != 0) {
					restS -= f[bit] + 1;
					if (restS < 0) {
						continue mask;
					}
					subtract = !subtract;
				}
			}
			if (subtract) {
				result = (result + (MOD - c(n + restS - 1, n - 1))) % MOD;
			}
			else {
				result = (result + c(n + restS - 1, n - 1)) % MOD;
			}
		}
		out.println(result);
	}

	private void preCalc(int n) {
		int factorial = 1;
		for (int i = 1; i < n; ++i) {
			factorial = (factorial * i) % MOD;
		}
		inverseNMinusOneFactorial = powerMod(factorial, MOD - 2);
	}

	private long powerMod(long n, int power) {
		long result = 1;
		for (int bit = 1; bit <= power; bit <<= 1) {
			if ((power & bit) != 0) {
				result = (result * n) % MOD;
			}
			n = (n * n) % MOD;
		}
		return result;
	}

	long c(long n, long m) {
		long result = 1;
		for (long i = n - m + 1; i <= n; ++i) {
			result = (result * i) % MOD;
		}
		return (result * inverseNMinusOneFactorial) % MOD;
	}

	public void run() {
		try {
			solve();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

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

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

	}

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

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

	public static void main(String[] arg) {
		new Task451E(System.in, System.out).run();
	}
}

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

import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class Main{

	// ArrayList<Integer> lis = new ArrayList<Integer>();
	// ArrayList<String> lis = new ArrayList<String>();
	//  PriorityQueue<P> que = new PriorityQueue<P>();
	// PriorityQueue<Integer> que = new PriorityQueue<Integer>();
	//  Stack<Integer> que = new Stack<Integer>();
    //	static long sum=0;
	// 1000000007 (10^9+7)
	static int mod = 1000000007;
	//static int mod = 1000000009,r=0; ArrayList<Integer> l[]= new ArrayList[n];
   // static int dx[]={1,-1,0,0};
//	static int dy[]={0,0,1,-1};
//	static int dx[]={1,-1,0,0,1,1,-1,-1};
//  static int dy[]={0,0,1,-1,1,-1,1,-1};
	//static Set<Integer> set = new HashSet<Integer>();p

public  static void main(String[] args)   throws Exception, IOException{
   //String line=""; throws Exception, IOException
   //(line=br.readLine())!=null
	//Scanner sc =new Scanner(System.in);
	// !!caution!! int long //
	Reader sc = new Reader(System.in);

 //,a=sc.nextInt(),b=sc.nextInt();
 	 int n=sc.nextInt();
    long f[]=new long[n],s=sc.nextLong()+n-1;

	for (int i = 0; i <n ; i++){
		f[i]=sc.nextLong();
	}

	long a[]=new long [2];
	long d[]=new long[22];
      d[0]++;

	for (int i = 1; i <=20 ; i++){
		d[i]=exGCD(i, mod)[1];d[i]+=mod;
		d[i]*=d[i-1];
        d[i]%=mod;
	}

	//db(d);

	long r=0;

	for(int i=0,c=1;i<1<<n;i++){
	  long 	x=s,k=0;
	    for(int t=0;t<n;t++){
	    	if( bit(i,t) ){ k++;  x-=f[t]+1;      }
	    }
	   if( k%2==0 )c=1 ; else c=-1;
	   if(x<0)continue;
	  x%=mod;
	  r+=c*com( x,n-1,d[n-1] );
	  r%=mod;
	 // db(i,x,r);
	}

	System.out.println(r);

}

static boolean bit(int x,int k){
	// weather k-th bit (from right) be one or zero
	return  ( 0 < ( (x>>k) & 1 )  )  ? true:false;
}

static long com( long n, int m ,long d) {//beware n<m�I

	if( n<m )return 0;

  long r=1;
	 for(int i=0;i<m;i++){
		 r*=n--; r%=mod;
	 }

	 r*=d; r%=mod;

	return r;
}

 static long[] exGCD(long a, long b)
{
	if(a == 0 || b == 0)return null;
	int as = Long.signum(a);
	int bs = Long.signum(b);
	a = Math.abs(a); b = Math.abs(b);
	long p = 1, q = 0, r = 0, s = 1;
	while(b > 0){
		long c = a / b;
		long d;
		d = a; a = b; b = d % b;
		d = p; p = q; q = d - c * q;
		d = r; r = s; s = d - c * s;
	}
	// can be minus!
	return new long[]{a, p * as, r * bs};
}

static void db(Object... os){
    System.err.println(Arrays.deepToString(os));

}

}

  /*
   * class P implements Comparable<P>{
//		implements Comparable<Pair>
		int id; long d;
		P(int id,long d){
			this.id=id;
			this.d=d;
		}
		public int compareTo(P x){
		   	 return  0<=d-x.d?1:-1 ;  //ascend
		   }

 }

class Pair implements Comparable<Pair>{
//	implements Comparable<Pair>
	int a,b;
	Pair(int a,int b){
		this.a=a;
		this.b=b;
	}
	public int compareTo(Pair x){
	   	 return a-x.a; //descend
	   }
}*/

class Reader
{
	private BufferedReader x;
	private StringTokenizer st;

	public Reader(InputStream in)
	{
		x = new BufferedReader(new InputStreamReader(in));
		st = null;
	}
	public String nextString() throws IOException
	{
		while( st==null || !st.hasMoreTokens() )
			st = new StringTokenizer(x.readLine());
		return st.nextToken();
	}
	public int nextInt() throws IOException
	{
		return Integer.parseInt(nextString());
	}
	public long nextLong() throws IOException
	{
		return Long.parseLong(nextString());
	}
	public double nextDouble() throws IOException
	{
		return Double.parseDouble(nextString());
	}
}

import java.io.*;
import java.util.*;
public class Main {

    public static void main(String[] args)
    {
        InputStream inputstream = System.in;
        OutputStream outputstream = System.out;
        InputReader in = new InputReader(inputstream);
        OutputWriter out = new OutputWriter(outputstream);
        mysolver mysol = new mysolver();
        mysol.solve(in, out);
        out.close();
    }

}

class mysolver {
	public long mod = 1000000007;
	public long MOD = 1_000_000_007;
	long inv[] = new long[26];
    public void solve(InputReader in,OutputWriter out)
    {
    	PrintWriter pout = new PrintWriter(new BufferedOutputStream(System.out));
    	int n = in.readInt();
    	long s = Long.parseLong(in.readString());
    	long f[] = new long[n];
    	for(int i=0;i<n;i++)
    		f[i] = Long.parseLong(in.readString());
    	long ans = 0;
    	for(int i=1;i<=25;i++)
    		inv[i] = inverse(i);
    	for(int i=0 ;i< 1<<n ; i++)
    	{
    		int bit = Long.bitCount(i);
    		String str = Long.toBinaryString(i);
    		str = ("00000000000000000000000000000000").concat(str);
    		int sign = 0;

    		if(bit%2==0)
    			sign = 1;
    		else
    			sign = -1;

    		char[] ch = str.toCharArray();
    		long val = s;
    		for(int j=ch.length-1;j>ch.length-n-1;j--)
    		{
    			if(ch[j]=='1')
    			{
    				val = val - f[ch.length-1-j]-1;
    			}
    		}
    		val = val+n-1;
    		if(val < 0)
    			continue;
    		ans = ans + sign * C(val,n-1);
    		ans = ans%mod;
    		//System.out.println(ans);
    	}
    	System.out.println(ans);
    	pout.close();
    }

    public long C(long n, long k) {
        long r = 1;
        for (long i = n; i > n - k; i--)
            r = (r * (i % MOD)) % MOD;
        long d = 1;
        for (long i = 1; i <= k; i++)
            d = (d * i) % MOD;
        return (r * inverse(d)) % MOD;
    }

    public long inverse(long a)
    {
    	long val = mod-2;
    	long ans = 1;
    	long mul = a;
    	while(val!=0)
    	{
    		if(val%2==1)
    		{
    			ans = (ans*mul)%mod;
    		}
    		mul = (mul*mul)%mod;
    		val = val/2;
    	}
    	return ans;
    }
}
class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public String readString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public String next() {
        return readString();
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void close() {
        writer.close();
    }

    public void printLine(int i) {
        writer.println(i);
    }
}

class IOUtils {

    public static void readIntArrays(InputReader in, int[]... arrays) {
        for (int i = 0; i < arrays[0].length; i++) {
            for (int j = 0; j < arrays.length; j++)
                arrays[j][i] = in.readInt();
        }
    }

    }

import java.io.*;
import java.util.*;
public class Main {

    public static void main(String[] args)
    {
        InputStream inputstream = System.in;
        OutputStream outputstream = System.out;
        InputReader in = new InputReader(inputstream);
        OutputWriter out = new OutputWriter(outputstream);
        mysolver mysol = new mysolver();
        mysol.solve(in, out);
        out.close();
    }

}

class mysolver {
	public long mod = 1000000007;
	public long MOD = 1_000_000_007;
	long inv[] = new long[26];
    public void solve(InputReader in,OutputWriter out)
    {
    	PrintWriter pout = new PrintWriter(new BufferedOutputStream(System.out));
    	int n = in.readInt();
    	long s = Long.parseLong(in.readString());
    	long f[] = new long[n];
    	for(int i=0;i<n;i++)
    		f[i] = Long.parseLong(in.readString());
    	long ans = 0;
    	for(int i=1;i<=25;i++)
    		inv[i] = inverse(i);
    	for(int i=0 ;i< 1<<n ; i++)
    	{
    		int bit = Long.bitCount(i);
    		String str = Long.toBinaryString(i);
    		str = ("00000000000000000000000000000000").concat(str);
    		int sign = 0;

    		if(bit%2==0)
    			sign = 1;
    		else
    			sign = -1;

    		char[] ch = str.toCharArray();
    		long val = s;
    		for(int j=ch.length-1;j>ch.length-n-1;j--)
    		{
    			if(ch[j]=='1')
    			{
    				val = val - f[ch.length-1-j]-1;
    			}
    		}
    		val = val+n-1;
    		if(val < 0)
    			continue;
    		ans = ans + sign * C(val,n-1);
    		ans = ans%mod;
    		System.out.println(ans);
    	}
    	System.out.println(ans);
    	pout.close();
    }

    public long C(long n, long k) {
        if (n - k < k)
            return C(n, n - k);
        long r = 1;
        for (long i = n; i > n - k; i--)
            r = (r * (i % MOD)) % MOD;
        long d = 1;
        for (long i = 1; i <= k; i++)
            d = (d * i) % MOD;
        return (r * inverse(d)) % MOD;
    }

    public long inverse(long a)
    {
    	long val = mod-2;
    	long ans = 1;
    	long mul = a;
    	while(val!=0)
    	{
    		if(val%2==1)
    		{
    			ans = (ans*mul)%mod;
    		}
    		mul = (mul*mul)%mod;
    		val = val/2;
    	}
    	return ans;
    }
}
class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public String readString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public String next() {
        return readString();
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void close() {
        writer.close();
    }

    public void printLine(int i) {
        writer.println(i);
    }
}

class IOUtils {

    public static void readIntArrays(InputReader in, int[]... arrays) {
        for (int i = 0; i < arrays[0].length; i++) {
            for (int j = 0; j < arrays.length; j++)
                arrays[j][i] = in.readInt();
        }
    }

    }

import java.io.*;
import java.util.*;
public class Main {

    public static void main(String[] args)
    {
        InputStream inputstream = System.in;
        OutputStream outputstream = System.out;
        InputReader in = new InputReader(inputstream);
        OutputWriter out = new OutputWriter(outputstream);
        mysolver mysol = new mysolver();
        mysol.solve(in, out);
        out.close();
    }

}

class mysolver {
	public long mod = 1000000007;
    public void solve(InputReader in,OutputWriter out)
    {
    	PrintWriter pout = new PrintWriter(new BufferedOutputStream(System.out));
    	int n = in.readInt();
    	long s = Long.parseLong(in.readString());
    	long f[] = new long[n];
    	for(int i=0;i<n;i++)
    		f[i] = Long.parseLong(in.readString());
    	long ans = 0;
    	for(int i=0 ;i< 1<<n ; i++)
    	{
    		int bit = Long.bitCount(i);
    		String str = Long.toBinaryString(i);
    		str = ("00000000000000000000000000000000").concat(str);
    		int sign = 0;

    		if(bit%2==0)
    			sign = 1;
    		else
    			sign = -1;

    		char[] ch = str.toCharArray();
    		long val = s;
    		for(int j=ch.length-1;j>ch.length-n-1;j--)
    		{
    			//System.out.print(ch[j]);
    			if(ch[j]=='1')
    			{
    				val = val - f[ch.length-1-j]-1;
    			}
    		}
    		//System.out.println();
    		val = val+n-1;

    		ans = ans + sign * C(val,n-1);
    		ans = ans%mod;
    		//System.out.println(C(val,n-1) + " "+val+" "+(n-1));
    		//System.out.println(ans+"\n");
    		//System.out.println("\n"+bit+" "+Integer.toBinaryString(i));
    	}
    	System.out.println(ans);
    	pout.close();
    }
    public long C(long n,long r)
    {
    	if(n<r)
    		return 0;
    	else
    	{
    		long ans = 1;
    		for(int i=0;i<r;i++)
    		{
    			ans = (ans*(n-i)/(i+1));
    		}
    		return ans%mod;
    	}
    }
}
class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public String readString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public String next() {
        return readString();
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void close() {
        writer.close();
    }

    public void printLine(int i) {
        writer.println(i);
    }
}

class IOUtils {

    public static void readIntArrays(InputReader in, int[]... arrays) {
        for (int i = 0; i < arrays[0].length; i++) {
            for (int j = 0; j < arrays.length; j++)
                arrays[j][i] = in.readInt();
        }
    }

    }

import java.util.Scanner;

public class E {

    static int n;
    static long MOD = 1_000_000_007;
    static long LIM = MOD * MOD;

    public static long modPower(long base, long exponent) {
        long r = 1;
        while (exponent > 0) {
            if (exponent % 2 == 1)
                r = (r * base) % MOD;
            base = (base * base) % MOD;
            exponent /= 2;
        }
        return r;
    }

    public static long C(long n, long k) {
        if (n - k < k)
            return C(n, n - k);
        long r = 1;
        for (long i = n; i > n - k; i--) {
            r = (r * i) % MOD;
        }
        long d = 1;
        for (long i = 1; i <= k; i++)
            d = (d * i) % MOD;
        return (r * modPower(d, MOD - 2)) % MOD;
    }

    public static long S(long n, long k) {
        return C(n + k - 1, k);
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        long k = in.nextLong();
        long[] f = new long[n];
        for (int i = 0; i < n; i++)
            f[i] = in.nextLong();
        long sum = 0;
        for (int i = 0; i < 1 << n; i++) {
            int sign = Integer.bitCount(i) % 2 == 0 ? 1 : -1;
            long kleft = k;
            for (int j = 0; j < n; j++)
                if ((i & 1 << j) != 0)
                    kleft -= f[j] + 1;
            if (kleft >= 0)
                sum = ((sum + sign * S(n, kleft)) % MOD + MOD) % MOD;
        }
        System.out.println(sum);
    }
}

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

public class Main{
    FastScanner in;
    PrintWriter out;

    public long mod = 1000000000+7;

    public long bin_pow(long d, long step) {
        if (step == 0) return 1;
        if (step == 1) return d % mod;
        long x = bin_pow(d, step/2);
        x = (x * x) % mod;
        if (step % 2 == 1)
            x = (x * d) % mod;
        return x;
    }

    public long fact(int x) {
        long res = 1;
        for (int i = 2; i < x + 1; i++) {
            res *= i;
            res %= mod;
        }
        return res;
    }

    public long bC(int n, int k) {
        long res = fact(n);
        res *= bin_pow(fact(k), mod-2);
        res %= mod;
        res *= bin_pow(fact(n-k), mod-2);
        res %= mod;
        return res;
    }

    public long C(long n, int k) {
        if (n <= k)
            return bC((int)n, k);

        long res = n - (k - 1);
        res %= mod;
        for (int p = 0; p < k-1 ; p++) {
            res *= (n-p) % mod;
            res %= mod;
        }

        res *= bin_pow(fact(k), mod-2);
        res %= mod;

        return res;
    }

    public void solve()
    {
        int n = in.nextInt();
        long s = in.nextLong();
        long[] f = new long[n];
        long sum = 0;
        for (int i = 0; i < n; i++) {
            f[i] = in.nextLong();
            sum += f[i];
        }

        long ans = 0;
        long sg;
        for(int mask = 0; mask < (1<<n); mask++) {
            int cnt = 0;
            sum = s;
            for (int i = 0; i < n; i++)
            if ((mask >> i) % 2 == 1)
            {
                cnt++;
                sum -= f[i]+1;
            }

            if (sum < 0) continue;

            if (cnt % 2 == 1)
                sg = -1;
            else
                sg = 1;

            long tmp_ans = 0;

            tmp_ans = C(sum + n - 1, n - 1);

            ans += sg * tmp_ans;
            ans += mod;
            ans %= mod;
        }

        out.println(ans);
    }

    public void run()
    {
        in = new FastScanner();
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

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

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

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

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

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

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

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

public class Main{
    FastScanner in;
    PrintWriter out;

    public long mod = 1000000000+7;

    public long bin_pow(long d, long step) {
        if (step == 0) return 1;
        if (step == 1) return d % mod;
        long x = bin_pow(d, step/2);
        x = (x * x) % mod;
        if (step % 2 == 1)
            x = (x * d) % mod;
        return x;
    }

    public long fact(int x) {
        long res = 1;
        for (int i = 2; i < x + 1; i++) {
            res *= i;
            res %= mod;
        }
        return res;
    }

    public long bC(int n, int k) {
        long res = fact(n);
        res *= bin_pow(fact(k), mod-2);
        res %= mod;
        res *= bin_pow(fact(n-k), mod-2);
        res %= mod;
        return res;
    }

    public long C(long n, int k) {
        if (n <= k)
            return bC((int)n, k);

        long res = n - (k - 1);
        res %= mod;
        for (int p = 0; p < k-1 ; p++) {
            res *= (n-p) % mod;
            res %= mod;
        }

        res *= bin_pow(fact(k), mod-2);
        res %= mod;

        return res;
    }

    public void solve()
    {
        int n = in.nextInt();
        long s = in.nextLong();
        long[] f = new long[n];
        long sum = 0;
        for (int i = 0; i < n; i++) {
            f[i] = in.nextLong();
            sum += f[i];
        }

        long ans = 0;
        long sg;
        for(int mask = 0; mask < (1<<n); mask++) {
            int cnt = 0;
            sum = s;
            for (int i = 0; i < n; i++)
            if ((mask >> i) % 2 == 1)
            {
                cnt++;
                sum -= f[i]+1;
            }

            if (sum < 0) continue;

            if (cnt % 2 == 1)
                sg = -1;
            else
                sg = 1;

            long tmp_ans = 0;

            tmp_ans = C(sum + n - 1, n - 1);

            ans += sg * tmp_ans;
            ans += 2*mod;
            ans %= mod;
        }

        out.println(ans);
    }

    public void run()
    {
        in = new FastScanner();
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

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

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

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

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

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

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

import java.io.PrintWriter;
import java.util.Scanner;

public class E451 {

	static class Solver {

		int N;
		long S, MOD = 1_000_000_007;;
		long[] boxes;

		long modPow(long k, long exp) {
			if (exp == 0)
				return 1;
			if (exp == 1)
				return k;
			long hs = (k * k) % MOD;
			if ((exp & 1) == 1)
				return (k * modPow(hs, exp / 2)) % MOD;
			return modPow(hs, exp / 2) % MOD;
		}

		long modInv(long k) {
			return modPow(k, MOD - 2);
		}

		long chooseMod(long n, long k) {
			n %= MOD;
			if (n < k)
				return 0;
			if (n == k)
				return 1;
			long top = n;
			for (long i = n - 1; i > n - k; i--) {
				top *= i;
				top %= MOD;
			}
			return (top * modInv(k)) % MOD;

		}

		// @SuppressWarnings("unchecked")
		public void solve(int testNumber, Scanner s, PrintWriter out) {

			N = s.nextInt();
			S = s.nextLong();
			boxes = new long[N];
			for (int i = 0; i < N; i++)
				boxes[i] = s.nextLong();

			long ways = 0;
			for (int i = 0; i < 1 << N; i++) {
				// overcounting on bits
				long over = 0;
				for (int c = 0; c < N; c++) {
					if ((i & (1 << c)) > 0)
						over += boxes[c] + 1;
				}
				if ((Integer.bitCount(i) & 1) == 1)
					ways -= chooseMod(S - over + N - 1, N - 1);
				else
					ways += chooseMod(S - over + N - 1, N - 1);
				ways %= MOD;

			}

			out.println(ways);

		}

	}

	public static void main(String[] args) {

		// Scanner s = new Scanner("2 3\n" + "1 3\n");
		// Scanner s = new Scanner("2 4\n" + "2 2\n");
		// Scanner s = new Scanner("3 5\n" + "1 3 2\n");
		Scanner s = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		Solver solver = new Solver();
		solver.solve(1, s, out);

		out.close();
		s.close();

	}
}

import java.io.PrintWriter;
import java.util.Scanner;

public class E451 {

	static class Solver {

		int N;
		long S, MOD = 1_000_000_007;;
		long[] boxes;

		long modPow(long k, long exp) {
			if (exp == 0)
				return 1;
			if (exp == 1)
				return k;
			long hs = (k * k) % MOD;
			if ((exp & 1) == 1)
				return (k * modPow(hs, exp / 2)) % MOD;
			return modPow(hs, exp / 2) % MOD;
		}

		long modInv(long k) {
			return modPow(k, MOD - 2);
		}

		long chooseMod(long n, long k) {
			n %= MOD;
			if (n < k)
				return 0;
			if (n == k)
				return 1;
			long top = n;
			for (long i = n - 1; i > n - k; i--) {
				top *= i;
				top %= MOD;
			}
			return (top * modInv(k)) % MOD;

		}

		// @SuppressWarnings("unchecked")
		public void solve(int testNumber, Scanner s, PrintWriter out) {

			N = s.nextInt();
			S = s.nextLong();
			boxes = new long[N];
			for (int i = 0; i < N; i++)
				boxes[i] = s.nextLong();

			long ways = 0;
			for (int i = 0; i < 1 << N; i++) {
				// overcounting on bits
				long over = 0;
				for (int c = 0; c < N; c++) {
					if ((i & (1 << c)) > 0)
						over += boxes[c] + 1;
				}
				if ((Integer.bitCount(i) & 1) == 1)
					ways -= chooseMod(S - over + N - 1, N - 1);
				else
					ways += chooseMod(S - over + N - 1, N - 1);

			}

			out.println(ways % MOD);

		}

	}

	public static void main(String[] args) {

		// Scanner s = new Scanner("2 3\n" + "1 3\n");
		// Scanner s = new Scanner("2 4\n" + "2 2\n");
		// Scanner s = new Scanner("3 5\n" + "1 3 2\n");
		Scanner s = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		Solver solver = new Solver();
		solver.solve(1, s, out);

		out.close();
		s.close();

	}
}

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

public class CODEFORCES {
	private InputStream is;
	private PrintWriter out;

	long fact[] = new long[21];
	long mod = (long) 1e9 + 7;
	long fi[] = new long[21];

	long pow(long a, long b) {
		long ans = 1;
		if (a == 0)
			return 0;
		while (b > 0) {
			if ((b & 1) == 1)
				ans = (ans * a) % mod;
			a = (a * a) % mod;
			b >>= 1;
		}
		return ans;
	}

	long ni;

	long nCr(long a) {
		long ans = 1;
		long mi = Math.min(a, ni - 1);
		long ma = mi;
		while (mi-- > 0)
			ans = (ans * (ni + (--a))) % mod;
		return (ans * fi[(int) ma]) % mod;
	}

	void solve() {
		int n = ni();
		ni = n;
		long s = nl();
		long val[] = new long[n];
		for (int i = 0; i < n; i++)
			val[i] = nl();
		fact[0] = 1;
		fi[0] = pow(fact[0], mod - 2);
		for (int i = 1; i <= 20; i++) {
			fact[i] = (fact[i - 1] * i) % mod;
			fi[i] = pow(fact[i], mod - 2);
		}
		HashMap<Long, Long> map = new HashMap<Long, Long>();
		map.put((long) 0, (long) 1);
		for (int i = 0; i < n; i++) {
			HashMap<Long, Long> tmp = new HashMap<Long, Long>();
			for (long p : map.keySet())
				tmp.put(p, map.get(p));
			for (long p : map.keySet()) {
				long add = p + val[i]+1;
				if (add > s)
					continue;
				if (tmp.containsKey(add))
					tmp.put(add, (mod + tmp.get(add) - map.get(p)) % mod);
				else
					tmp.put(add, mod-map.get(p));
			}
			map = tmp;
		}
		long ans = 0;
		for (long a : map.keySet()) {
			//out.println(a + " " + map.get(a));
			ans = (ans + nCr(s - a) * map.get(a) % mod) % mod;
		}
		out.println(ans);
	}

	void soln() throws Exception {
		is = System.in;
		out = new PrintWriter(System.out);
		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new CODEFORCES().soln();
	}

	// To Get Input
	// Some Buffer Methods
	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n && !(isSpaceChar(b))) {
			buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

	private void tr(Object... o) {
		if (!oj)
			System.out.println(Arrays.deepToString(o));
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	public static final long MOD = (long) (1e9 + 7);
	public static long[] fac, inv, a;
	public static final int MAX = 20;
	public static long N, M;

	public static void main(String[] args) throws IOException {
		fac = new long[MAX + 1];
		inv = new long[MAX + 1];
		fac[0] = 1;
		inv[0] = 1;
		for (int i = 1; i <= MAX; i++) {
			fac[i] = (fac[i - 1] * i) % MOD;
			inv[i] = qpow(fac[i], MOD - 2, MOD);
		}
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(f.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Long.parseLong(st.nextToken());
		a = new long[(int) N];
		st = new StringTokenizer(f.readLine());
		for (int i = 0; i < N; i++) {
			a[i] = Long.parseLong(st.nextToken());
		}
		System.out.println(solve());
	}

	public static long solve() {
		long res = C(N + M - 1, N - 1);
		for (int x = 1; x < 1 << N; x++) {
			long t = N + M;
			int p = 0;
			for (int i = 0; i < N; i++) {
				if (((x >> i) & 1) == 1) {
					p++;
					t -= a[i];
				}
			}
			t -= (p + 1);
			if (p % 2 == 1) {
				res = (res + MOD - C(t, N - 1)) % MOD;
			} else {
				res = (res + C(t, N - 1)) % MOD;
			}
		}
		return res;
	}

	public static long C(long y, long x) {
		if (y < 0 || x < 0 || y < x)
			return 0;
		y %= MOD;
		if (y == 0 && x == 0)
			return 1;
		long res = 1;
		for (int i = 0; i < x; i++) {
			res = (res * (y - i)) % MOD;
		}
		for (int i = 1; i <= x; i++) {
			res = (res * inv[i]) % MOD;
		}
		return res;
	}

	public static long qpow(long a, long b, long p) {
		long res = 1 % p;
		for (; b > 0; b >>= 1) {
			if ((b & 1) == 1) {
				res *= a;
				res %= p;
			}
			a *= a;
			a %= p;
		}
		return res;
	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DevuAndFlowers solver = new DevuAndFlowers();
        solver.solve(1, in, out);
        out.close();
    }

    static class DevuAndFlowers {
        long MOD = (long) (1e9) + 7;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            Poly p = new Poly();
            int N = in.nextInt();
            long s = in.nextLong();
            for (int i = 0; i < N; i++) {
                if (N == 1) {
                    long a = in.nextLong();
                    if (a >= s) {
                        out.println(1);
                    } else {
                        out.println(0);
                    }
                    return;
                }
                p.mult(in.nextLong() + 1);
            }
            long inv = 1;
            for (int i = 1; i <= N - 1; i++) {
                inv *= i;
                inv %= MOD;
            }
            inv = MathUtils.inverse(inv, MOD);
            long res = 0;
            for (long l : p.poly.keySet()) {
                long i = s - l;
                if (i < 0) {
                    continue;
                } else {
                    long num = 1;
                    for (long j = N + i - 1; j >= i + 1; j--) {
                        num *= j;
                        num %= MOD;
                    }
                    num *= inv;
                    num %= MOD;
                    num *= p.poly.get(l);
                    num %= MOD;
                    res += num;
                    if (res >= MOD) {
                        res -= MOD;
                    }
                    if (res < 0) {
                        res += MOD;
                    }
                }
            }
            out.println(res);
        }

        class Poly {
            HashMap<Long, Long> poly;

            Poly() {
                poly = new HashMap<>();
                poly.put(0L, 1L);
            }

            void mult(long i) {
                HashMap<Long, Long> toAdd = new HashMap<>();
                for (long l : poly.keySet()) {
                    toAdd.putIfAbsent(l + i, 0L);
                    toAdd.replace(l + i, -poly.get(l));
                }
                for (long l : toAdd.keySet()) {
                    poly.putIfAbsent(l, 0L);
                    long next = poly.get(l) + toAdd.get(l);
                    if (next < 0) {
                        next += MOD;
                    }
                    if (next >= MOD) {
                        next -= MOD;
                    }
                    poly.replace(l, next);
                }
            }

        }

    }

    static class MathUtils {
        public static long inverse(long a, long mod) {
            long[] inv = extended_gcd(a, mod);
            if (inv[0] != 1) {
                return 0;
            } else {
                return (inv[1] + 2 * mod) % mod;
            }
        }

        public static long[] extended_gcd(long a, long b) {
            //three numbers, first is gcd, second is x, third is y
            if (a == 0) {
                return new long[]{b, 0, 1};
            }
            long[] next = extended_gcd(b % a, a);
            long tempX = next[1];
            next[1] = next[2] - (b / a) * next[1];
            next[2] = tempX;
            return next;
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

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

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

    }
}

import java.io.*;
import java.lang.*;
import static java.lang.Math.*;
import java.lang.reflect.*;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.security.CodeSource;
import java.security.KeyStore;
import java.util.*;
import static java.util.Arrays.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;

// https://netbeans.org/kb/73/java/editor-codereference_ru.html#display

public class Main {

    final long mod = (long)1e9 + 7;
    int n;
    long s;
    long[] f;
    long[] invFact = new long[1000];
    {
        invFact[0] = 1;
        long f = 1;
        for (int i = 1; i < invFact.length; i++) {
            f = (f * i) % mod;
            invFact[i] = valueOf(f).modInverse(valueOf(mod)).longValue();
        }
    }

    long C( int l, long b ){
        long ans = 1;
        for( long x = b-l+1; x <= b; ++x ){
            ans = (ans * x) % mod;
        }
        ans = (ans * invFact[l]) % mod;
        return ans;
    }

    void solve(){
        for( int n = 0; n <= 10; ++n ){
            for (int m = 0; m <= n; m++) {
                err.print( " " + C(m,n) );
            }
            err.println();
        }

        n = sc.nextInt();
        s = sc.nextLong();
        f = new long[n];
        for (int i = 0; i < f.length; i++) {
            f[i] = sc.nextLong();
        }

        long ans = 0;
        for (int msk = 0; msk < (1<<n); msk++) {
            long curS = s;
            for (int i = 0; i < n; i++) {
                if( ((msk>>i)&1) == 1 ){
                    curS -= f[i] + 1;
                }
            }
            if( 0 <= curS ){
                long comb = C(n-1, curS+n-1);
                err.println( msk +") "+ comb );
                if( Integer.bitCount(msk) % 2 == 0 )
                    ans = (ans + comb) % mod;
                else
                    ans = (ans - comb + mod) % mod;
            }
        }
        out.println(ans);
    }

    //------------------------------------------------------------------//

    private void run(){
        err = System.err;
        boolean oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }

        if( oj ){
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        }
        else{
            try {
                sc = new FastScanner(new FileReader("input.txt"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch ( IOException e) {
                MLE();
            }
        }
        solve();

        out.flush();
    }

    FastScanner sc;
    PrintWriter out;
    PrintStream err;

    void MLE(){
        int[][] arr = new int[1024*1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024*1024];
        }
    }

    class FastScanner {

        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStreamReader reader) {
            br = new BufferedReader(reader);
            st = new StringTokenizer("");
        }

        String next() {
            while( !st.hasMoreElements() )
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException ex) {
                    MLE();
                }
            return st.nextToken();
        }

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

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

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

}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Main {

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

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	private void run() throws IOException {
		if (new File("input.txt").exists())
			in = new BufferedReader(new FileReader("input.txt"));
		else
			in = new BufferedReader(new InputStreamReader(System.in));
		if (new File("output.txt").exists())
			out = new PrintWriter("output.txt");
		else
			out = new PrintWriter(System.out);

		solve();

		in.close();
		out.close();
	}

	final int maxn = 22;
	final int p = 1000 * 1000 * 1000 + 7;

	int n;
	long s;
	long f[] = new long[maxn];
	long ans;

	long inv[] = new long[maxn];
	long finv[] = new long[maxn];

	TreeMap<Long, Long> polynom = new TreeMap<>();

	void rec(int index, long a, long pow) {
		if (index == n) {
			if (polynom.containsKey(pow))
				polynom.put(pow, (polynom.get(pow) + a) % p);
			else
				polynom.put(pow, a);
		} else {
			rec(index + 1, a, pow);
			rec(index + 1, (p - a) % p, pow + f[index] + 1);
		}
	}

	long getC(long n, int m) {
		long c = 1;
		for (long i = n - m + 1; i <= n; i++)
			c = (c * i) % p;
		c = (c * finv[m]) % p;
		return c;
	}

	void precalc() {
		inv[1] = 1;
		for (int i = 2; i < maxn; i++)
			inv[i] = (p - ((p / i) * inv[p % i]) % p) % p;
		finv[0] = 1;
		for (int i = 1; i < maxn; i++)
			finv[i] = finv[i - 1] * inv[i];
	}

	void solve() throws IOException {
		precalc();
		n = nextInt();
		s = nextLong();
		for (int i = 0; i < n; i++)
			f[i] = nextLong();

		rec(0, 1, 0);
		ans = 0;
		for (long pow : polynom.keySet()) {
			long k = s - pow;
			if (k >= 0) {
				long c = getC(n + k - 1, n - 1);
//				System.err.println(k + " " + c);
				ans = (ans + c * polynom.get(pow)) % p;
			}
		}

		out.println(ans);
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	String nextToken() throws IOException {
		while (!st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String str = in.readLine();
			if (str == null)
				return true;
			st = new StringTokenizer(str);
		}
		return false;
	}

}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Main {

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

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	private void run() throws IOException {
		if (new File("input.txt").exists())
			in = new BufferedReader(new FileReader("input.txt"));
		else
			in = new BufferedReader(new InputStreamReader(System.in));
		if (new File("output.txt").exists())
			out = new PrintWriter("output.txt");
		else
			out = new PrintWriter(System.out);

		solve();

		in.close();
		out.close();
	}

	final int maxn = 22;
	final int p = 1000 * 1000 * 1000 + 7;

	int n;
	long s;
	long f[] = new long[maxn];
	long ans;

	long inv[] = new long[maxn];
	long finv[] = new long[maxn];

	TreeMap<Long, Long> polynom = new TreeMap<>();

	void rec(int index, long a, long pow) {
		if (index == n) {
			if (polynom.containsKey(pow))
				polynom.put(pow, (polynom.get(pow) + a) % p);
			else
				polynom.put(pow, a);
		} else {
			rec(index + 1, a, pow);
			rec(index + 1, (p - a) % p, pow + f[index] + 1);
		}
	}

	long getC(long n, int m) {
		long c = 1;
		for (long i = n - m + 1; i <= n; i++)
			c = (c * i) % p;
		c = (c * finv[m]) % p;
		return c;
	}

	void precalc() {
		inv[1] = 1;
		for (int i = 2; i < maxn; i++)
			inv[i] = p - ((p / i) * inv[p % i]) % p;
		finv[0] = 1;
		for (int i = 1; i < maxn; i++)
			finv[i] = finv[i - 1] * inv[i];
	}

	void solve() throws IOException {
		precalc();
		n = nextInt();
		s = nextLong();
		for (int i = 0; i < n; i++)
			f[i] = nextLong();

		rec(0, 1, 0);
		ans = 0;
		for (long pow : polynom.keySet()) {
			long k = s - pow;
			if (k >= 0) {
				long c = getC(n + k - 1, n - 1);
//				System.err.println(k + " " + c);
				ans = (ans + c * polynom.get(pow)) % p;
			}
		}

		out.println(ans);
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	String nextToken() throws IOException {
		while (!st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String str = in.readLine();
			if (str == null)
				return true;
			st = new StringTokenizer(str);
		}
		return false;
	}

}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Main {

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

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	private void run() throws IOException {
		if (new File("input.txt").exists())
			in = new BufferedReader(new FileReader("input.txt"));
		else
			in = new BufferedReader(new InputStreamReader(System.in));
		if (new File("output.txt").exists())
			out = new PrintWriter("output.txt");
		else
			out = new PrintWriter(System.out);

		solve();

		in.close();
		out.close();
	}

	final int maxn = 22;
	final int p = 1000 * 1000 * 1000 + 7;

	int n;
	long s;
	long f[] = new long[maxn];
	long ans;

	long inv[] = new long[maxn];
	long finv[] = new long[maxn];

	TreeMap<Long, Long> polynom = new TreeMap<>();

	void rec(int index, long a, long pow) {
		if (index == n) {
			if (polynom.containsKey(pow))
				polynom.put(pow, (polynom.get(pow) + a) % p);
			else
				polynom.put(pow, a);
		} else {
			rec(index + 1, a, pow);
			rec(index + 1, (p - a) % p, pow + f[index] + 1);
		}
	}

	long getC(long n, int m) {
		long c = 1;
		for (long i = n - m + 1; i <= n; i++)
			c = (c * i) % p;
		c = (c * finv[m]) % p;
		return c;
	}

	void precalc() {
		inv[1] = 1;
		for (int i = 2; i < maxn; i++)
			inv[i] = (p - ((p / i) * inv[p % i]) % p) % p;
		finv[0] = 1;
		for (int i = 1; i < maxn; i++)
			finv[i] = (finv[i - 1] * inv[i]) % p;
	}

	void solve() throws IOException {
		precalc();
		n = nextInt();
		s = nextLong();
		for (int i = 0; i < n; i++)
			f[i] = nextLong();

		rec(0, 1, 0);
		ans = 0;
		for (long pow : polynom.keySet()) {
			long k = s - pow;
			if (k >= 0) {
				long c = getC(n + k - 1, n - 1);
				// System.err.println(k + " " + c);
				ans = (ans + c * polynom.get(pow)) % p;
			}
		}

		out.println(ans);
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	String nextToken() throws IOException {
		while (!st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String str = in.readLine();
			if (str == null)
				return true;
			st = new StringTokenizer(str);
		}
		return false;
	}

}

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

public class DevuAndFlowers {

	static long mod = 1000000007;
	static long modInv[];
	static int N;
	static long S;
	static long f[];
	public static void main(String[] args) {
		JS in = new JS();
		N = in.nextInt();
		S = in.nextLong();
		f = new long[N];
		for(int i = 0; i < N; i++) f[i] = in.nextLong();
		modInv = new long[N+1];
		for(int i = 0; i <= N; i++) modInv[i] = pow(i, mod-2);

		long total = sumTo(S, N);
		long pie = 0;
		for(int i = 1; i < (1<<N); i++) {
			long over = S;
			boolean found = false;
			for(int j = 0; j < N; j++) {
				if((i & (1<<j)) > 0) {
					if(f[j] < S) {
						found = true;
						over -= (f[j]+1);
					}
				}
			}
			if(over < 0) continue;
			long v = sumTo(over, N);
			if(found) {
				if(Integer.bitCount(i)%2 == 0) {
					pie -= v;
					while(pie < 0) pie += mod;
					while(pie >= mod) pie -= mod;
				}
				else {
					pie += v;
					while(pie < 0) pie += mod;
					while(pie >= mod) pie -= mod;
				}
			}
		}
		//System.out.println(total+" "+pie);
		long res = total - pie;
		while(res < 0) res += mod;
		System.out.println(res);
	}

	static long sumTo(long sum, long n) {
		return choose(sum+n-1, n-1);
	}
	static long choose(long n, long k) {
		long prev = 1;
		for(int c = 1; c <= k; c++)
			prev = (((prev*(n-c+1))%mod)*modInv[c])%mod;
		return prev;
	}

	// Choose under mod
	long lucasTheorem(long m, long n) {
		long ans = 1;
	  while(m != 0 && n != 0) {
		long a = m % mod, b = n % mod;
	    if(a < b) return 0;
	    ans = (ans * choose(a, b)) % mod;
	    m /= mod; n /= mod;
	  }
	  return ans;
	}

	static long pow(long base, long power) {
		if(power == 0) return 1;
		if(power == 1) return base;
		if((power&1)==0) {
			long r = pow(base, power/2);
			return (r*r)%mod;
		}
		else {
			return (base * pow(base,power-1))%mod;
		}
	}

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

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

		public JS(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			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 long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

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

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

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

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int []nia(int n){
			int r[] = new int[n];
			for(int i = 0; i < n; i++) r[i] = nextInt();
			return r;
		}
		public double []nda(int n){
			double r[] = new double[n];
			for(int i = 0; i < n; i++) r[i] = nextDouble();
			return r;
		}
		public long []nla(int n){
			long r[] = new long[n];
			for(int i = 0; i < n; i++) r[i] = nextLong();
			return r;
		}
	}

}

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

public class DevuAndFlowers {

	static long mod = 1000000007;
	static long modInv[];
	static int N;
	static long S;
	static long f[];
	public static void main(String[] args) {
		JS in = new JS();
		N = in.nextInt();
		S = in.nextLong();
		f = new long[N];
		for(int i = 0; i < N; i++) f[i] = in.nextLong();
		modInv = new long[N+1];
		for(int i = 0; i <= N; i++) modInv[i] = pow(i, mod-2);

		long ans = 0;
		for(int i = 0; i < (1<<N); i++) {
			long over = S;
			for(int j = 0; j < N; j++) {
				if((i & (1<<j)) > 0) {
					over -= f[j]+1;
				}
			}
			if(over < 0) continue;
			long v = sumTo(over, N);
			if(Integer.bitCount(i)%2==1) ans -= v;
			else ans += v;
			while(ans < 0) ans+=mod;
			while(ans >= mod)ans-=mod;
		}
		System.out.println(ans);
	}

	static long sumTo(long sum, long n) {
		return choose(sum+n-1, n-1);
	}
	static long choose(long n, long k) {
		long prev = 1;
		for(int c = 1; c <= k; c++)
			prev = (((prev*(n-c+1))%mod)*modInv[c])%mod;
		return prev;
	}

	static long pow(long base, long power) {
		if(power == 0) return 1;
		if(power == 1) return base;
		if((power%2)==0) {
			long r = pow(base, power/2);
			return (r*r)%mod;
		}
		else {
			return (base * pow(base,power-1))%mod;
		}
	}

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

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

		public JS(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			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 long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

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

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

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

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int []nia(int n){
			int r[] = new int[n];
			for(int i = 0; i < n; i++) r[i] = nextInt();
			return r;
		}
		public double []nda(int n){
			double r[] = new double[n];
			for(int i = 0; i < n; i++) r[i] = nextDouble();
			return r;
		}
		public long []nla(int n){
			long r[] = new long[n];
			for(int i = 0; i < n; i++) r[i] = nextLong();
			return r;
		}
	}

}

import java.util.*;
import java.text.*;
import java.io.*;
import java.math.*;
public class code5 {
	InputStream is;
	PrintWriter out;
	static long mod=pow(10,9)+7;
	static int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
 	void solve() throws Exception
	{
 		int n=ni();
 		long sum=nl();
 		long a[]=nl(n);
 		long ans=ncr(sum+n-1,n-1);
 		for(int i=1;i<(1<<n);i++)
 		{
 			long temp=0,count=0;
 			for(int j=0;j<n;j++)
 			{
 				if((i&(1<<j))!=0)
 				{
 					count++;
 					temp+=(a[j]+1);
 				}
 			}
 			if(count%2==0)
 			{
 				ans+=(ncr(sum-temp+n-1,n-1));
 				ans%=mod;
 			}else {
 				ans=(ans-ncr(sum-temp+n-1,n-1)+mod)%mod;
 			}
 		}
 		out.print(ans%mod);
	}
 	long ncr(long n,long r)
 	{
 		long nom=1;
 		if(n<=0)
 			return 0;
 		for(long i=n;i>=(n-r+1);i--)
 		{
 			nom*=i;
 			nom%=mod;
 		}
 		long dom=1;
 		for(long i=r;i>=1;i--)
 		{
 			dom*=i;
 			dom%=mod;
 		}
 		return (nom*pow(dom,mod-2,mod))%mod;
 	}
 	/*void take(int n)
 	{
 		al=new ArrayList[n];
 		for(int i=0;i<n;i++)
 			al[i]=new ArrayList<Integer>();
 		for(int i=0;i<n-1;i++)
 		{
 			int x=ni()-1;
 			int y=ni()-1;
 			al[x].add(y);
 			al[y].add(x);
 		}
 	}*/

 	int check(long n)
 	{
 		int count=0;
 		while(n!=0)
 		{
 			if(n%10!=0)
 				break;
 			n/=10;
 			count++;
 		}
 		return count;
 	}
	public static int count(int x)
	{
		int num=0;
		while(x!=0)
		{
			x=x&(x-1);
			num++;
		}
		return num;
	}
	static long d, x, y;
	void extendedEuclid(long A, long B) {
	    if(B == 0) {
	        d = A;
	        x = 1;
	        y = 0;
	    }
	    else {
	        extendedEuclid(B, A%B);
	        long temp = x;
	        x = y;
	        y = temp - (A/B)*y;
	    }
	}
	long modInverse(long A,long M) //A and M are coprime
	{
	    extendedEuclid(A,M);
	    return (x%M+M)%M;    //x may be negative
	}
	public static void mergeSort(int[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(int arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		int left[] = new int[n1];
		int right[] = new int[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	public static void mergeSort(long[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(long arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		long left[] = new long[n1];
		long right[] = new long[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	 static class Pair implements Comparable<Pair>{

	       int x,y,k;
	       int i,dir;
		Pair (int xx,int yy){
			this.x=xx;
			this.y=yy;
		}
		public int compareTo(Pair o) {
			if(this.x!=o.x)
				return this.x-o.x;
			return this.y-o.y;
		}

		public String toString(){
			return x+" "+y+" "+k+" "+i;}
		public boolean equals(Object o) {
			if (o instanceof Pair) {
				Pair p = (Pair)o;
				return p.x == x && p.y == y;
			}
			return false;
		}
		public int hashCode() {
			return new Long(x).hashCode()*31 + new Long(y).hashCode() ;
		}
	}

	    public static boolean isPal(String s){
	        for(int i=0, j=s.length()-1;i<=j;i++,j--){
	                if(s.charAt(i)!=s.charAt(j)) return false;
	        }
	        return true;
	    }
	    public static String rev(String s){
			StringBuilder sb=new StringBuilder(s);
			sb.reverse();
			return sb.toString();
	    }

	    public static long gcd(long x,long y){
		if(y==0)
			return x;
		else
			return gcd(y,x%y);
	    }

	    public static int gcd(int x,int y){
	    	if(y==0)
	    		return x;
	    	return gcd(y,x%y);
	    }

	    public static long gcdExtended(long a,long b,long[] x){

	        if(a==0){
	            x[0]=0;
	            x[1]=1;
	            return b;
	        }
	        long[] y=new long[2];
	        long gcd=gcdExtended(b%a, a, y);

	        x[0]=y[1]-(b/a)*y[0];
	        x[1]=y[0];

	        return gcd;
	    }

	    public static int abs(int a,int b){
		return (int)Math.abs(a-b);
	    }

	    public static long abs(long a,long b){
		return (long)Math.abs(a-b);
	    }

	    public static int max(int a,int b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static int min(int a,int b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long max(long a,long b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static long min(long a,long b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long pow(long n,long p,long m){
		 long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    if(result>=m)
		    result%=m;
		    p >>=1;
		    n*=n;
		    if(n>=m)
		    n%=m;
		}
		return result;
	    }

	    public static long pow(long n,long p){
		long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    p >>=1;
		    n*=n;
		}
		return result;
	    }
	    public static void debug(Object... o) {
			System.out.println(Arrays.deepToString(o));
		}
	    void run() throws Exception {
			is = System.in;
			out = new PrintWriter(System.out);
			solve();
			out.flush();
		}

	    public static void main(String[] args) throws Exception {
			new Thread(null, new Runnable() {
				public void run() {
					try {
						new code5().run();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}, "1", 1 << 26).start();

	    	//new code5().run();
		}
	    private byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		private int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		private boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		private int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b));
			return b;
		}

		private double nd() {
			return Double.parseDouble(ns());
		}

		private char nc() {
			return (char) skip();
		}

		private String ns() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		private char[] ns(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		private char[][] nm(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = ns(m);
			return map;
		}

		private int[] na(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = ni();
			return a;
		}
		private long[] nl(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nl();
			return a;
		}

		private int ni() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		private long nl() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

}

import java.util.*;
import java.text.*;
import java.io.*;
import java.math.*;
public class code5 {
	InputStream is;
	PrintWriter out;
	static long mod=pow(10,9)+7;
	static int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
 	void solve() throws Exception
	{
 		int n=ni();
 		long sum=nl();
 		long a[]=nl(n);
 		long ans=ncr(sum+n-1,n-1);
 		for(int i=1;i<(1<<n);i++)
 		{
 			long temp=0,count=0;
 			for(int j=0;j<n;j++)
 			{
 				if((i&(1<<j))!=0)
 				{
 					count++;
 					temp+=(a[j]+1);
 				}
 			}
 			if(count%2==0)
 			{
 				ans+=(ncr(sum-temp+n-1,n-1));
 				ans%=mod;
 			}else {
 				ans=(ans-ncr(sum-temp+n-1,n-1)+mod)%mod;
 			}
 			System.out.println(ans);
 		}
 		out.print(ans%mod);
	}
 	long ncr(long n,long r)
 	{
 		long nom=1;
 		if(n<0||n<r)
 			return 0;
 		for(long i=n;i>=(n-r+1);i--)
 		{
 			nom*=i;
 			nom%=mod;
 		}
 		long dom=1;
 		for(long i=r;i>=1;i--)
 		{
 			dom*=i;
 			dom%=mod;
 		}
 		return (nom*pow(dom,mod-2,mod))%mod;
 	}
 	/*void take(int n)
 	{
 		al=new ArrayList[n];
 		for(int i=0;i<n;i++)
 			al[i]=new ArrayList<Integer>();
 		for(int i=0;i<n-1;i++)
 		{
 			int x=ni()-1;
 			int y=ni()-1;
 			al[x].add(y);
 			al[y].add(x);
 		}
 	}*/

 	int check(long n)
 	{
 		int count=0;
 		while(n!=0)
 		{
 			if(n%10!=0)
 				break;
 			n/=10;
 			count++;
 		}
 		return count;
 	}
	public static int count(int x)
	{
		int num=0;
		while(x!=0)
		{
			x=x&(x-1);
			num++;
		}
		return num;
	}
	static long d, x, y;
	void extendedEuclid(long A, long B) {
	    if(B == 0) {
	        d = A;
	        x = 1;
	        y = 0;
	    }
	    else {
	        extendedEuclid(B, A%B);
	        long temp = x;
	        x = y;
	        y = temp - (A/B)*y;
	    }
	}
	long modInverse(long A,long M) //A and M are coprime
	{
	    extendedEuclid(A,M);
	    return (x%M+M)%M;    //x may be negative
	}
	public static void mergeSort(int[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(int arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		int left[] = new int[n1];
		int right[] = new int[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	public static void mergeSort(long[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(long arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		long left[] = new long[n1];
		long right[] = new long[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	 static class Pair implements Comparable<Pair>{

	       int x,y,k;
	       int i,dir;
		Pair (int xx,int yy){
			this.x=xx;
			this.y=yy;
		}
		public int compareTo(Pair o) {
			if(this.x!=o.x)
				return this.x-o.x;
			return this.y-o.y;
		}

		public String toString(){
			return x+" "+y+" "+k+" "+i;}
		public boolean equals(Object o) {
			if (o instanceof Pair) {
				Pair p = (Pair)o;
				return p.x == x && p.y == y;
			}
			return false;
		}
		public int hashCode() {
			return new Long(x).hashCode()*31 + new Long(y).hashCode() ;
		}
	}

	    public static boolean isPal(String s){
	        for(int i=0, j=s.length()-1;i<=j;i++,j--){
	                if(s.charAt(i)!=s.charAt(j)) return false;
	        }
	        return true;
	    }
	    public static String rev(String s){
			StringBuilder sb=new StringBuilder(s);
			sb.reverse();
			return sb.toString();
	    }

	    public static long gcd(long x,long y){
		if(y==0)
			return x;
		else
			return gcd(y,x%y);
	    }

	    public static int gcd(int x,int y){
	    	if(y==0)
	    		return x;
	    	return gcd(y,x%y);
	    }

	    public static long gcdExtended(long a,long b,long[] x){

	        if(a==0){
	            x[0]=0;
	            x[1]=1;
	            return b;
	        }
	        long[] y=new long[2];
	        long gcd=gcdExtended(b%a, a, y);

	        x[0]=y[1]-(b/a)*y[0];
	        x[1]=y[0];

	        return gcd;
	    }

	    public static int abs(int a,int b){
		return (int)Math.abs(a-b);
	    }

	    public static long abs(long a,long b){
		return (long)Math.abs(a-b);
	    }

	    public static int max(int a,int b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static int min(int a,int b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long max(long a,long b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static long min(long a,long b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long pow(long n,long p,long m){
		 long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    if(result>=m)
		    result%=m;
		    p >>=1;
		    n*=n;
		    if(n>=m)
		    n%=m;
		}
		return result;
	    }

	    public static long pow(long n,long p){
		long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    p >>=1;
		    n*=n;
		}
		return result;
	    }
	    public static void debug(Object... o) {
			System.out.println(Arrays.deepToString(o));
		}
	    void run() throws Exception {
			is = System.in;
			out = new PrintWriter(System.out);
			solve();
			out.flush();
		}

	    public static void main(String[] args) throws Exception {
			new Thread(null, new Runnable() {
				public void run() {
					try {
						new code5().run();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}, "1", 1 << 26).start();

	    	//new code5().run();
		}
	    private byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		private int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		private boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		private int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b));
			return b;
		}

		private double nd() {
			return Double.parseDouble(ns());
		}

		private char nc() {
			return (char) skip();
		}

		private String ns() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		private char[] ns(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		private char[][] nm(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = ns(m);
			return map;
		}

		private int[] na(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = ni();
			return a;
		}
		private long[] nl(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nl();
			return a;
		}

		private int ni() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		private long nl() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

}

import java.util.*;
import java.text.*;
import java.io.*;
import java.math.*;
public class code5 {
	InputStream is;
	PrintWriter out;
	static long mod=pow(10,9)+7;
	static int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
 	void solve() throws Exception
	{
 		int n=ni();
 		long sum=nl();
 		long a[]=nl(n);
 		long ans=ncr(sum+n-1,n-1);
 		for(int i=1;i<(1<<n);i++)
 		{
 			long temp=0,count=0;
 			for(int j=0;j<n;j++)
 			{
 				if((i&(1<<j))!=0)
 				{
 					count++;
 					temp+=(a[j]+1);
 				}
 			}
 			if(count%2==0)
 			{
 				ans+=(ncr(sum-temp+n-1,n-1));
 				ans%=mod;
 			}else {
 				ans-=(ncr(sum-temp+n-1,n-1));
 				ans%=mod;
 			}
 		}
 		out.print(ans);
	}
 	long ncr(long n,long r)
 	{
 		long nom=1;
 		if(n<=0)
 			return 0;
 		for(long i=n;i>=(n-r+1);i--)
 		{
 			nom*=i;
 			nom%=mod;
 		}
 		long dom=1;
 		for(long i=r;i>=1;i--)
 		{
 			dom*=i;
 			dom%=mod;
 		}
 		return (nom*pow(dom,mod-2,mod))%mod;
 	}
 	/*void take(int n)
 	{
 		al=new ArrayList[n];
 		for(int i=0;i<n;i++)
 			al[i]=new ArrayList<Integer>();
 		for(int i=0;i<n-1;i++)
 		{
 			int x=ni()-1;
 			int y=ni()-1;
 			al[x].add(y);
 			al[y].add(x);
 		}
 	}*/

 	int check(long n)
 	{
 		int count=0;
 		while(n!=0)
 		{
 			if(n%10!=0)
 				break;
 			n/=10;
 			count++;
 		}
 		return count;
 	}
	public static int count(int x)
	{
		int num=0;
		while(x!=0)
		{
			x=x&(x-1);
			num++;
		}
		return num;
	}
	static long d, x, y;
	void extendedEuclid(long A, long B) {
	    if(B == 0) {
	        d = A;
	        x = 1;
	        y = 0;
	    }
	    else {
	        extendedEuclid(B, A%B);
	        long temp = x;
	        x = y;
	        y = temp - (A/B)*y;
	    }
	}
	long modInverse(long A,long M) //A and M are coprime
	{
	    extendedEuclid(A,M);
	    return (x%M+M)%M;    //x may be negative
	}
	public static void mergeSort(int[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(int arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		int left[] = new int[n1];
		int right[] = new int[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	public static void mergeSort(long[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(long arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		long left[] = new long[n1];
		long right[] = new long[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	 static class Pair implements Comparable<Pair>{

	       int x,y,k;
	       int i,dir;
		Pair (int xx,int yy){
			this.x=xx;
			this.y=yy;
		}
		public int compareTo(Pair o) {
			if(this.x!=o.x)
				return this.x-o.x;
			return this.y-o.y;
		}

		public String toString(){
			return x+" "+y+" "+k+" "+i;}
		public boolean equals(Object o) {
			if (o instanceof Pair) {
				Pair p = (Pair)o;
				return p.x == x && p.y == y;
			}
			return false;
		}
		public int hashCode() {
			return new Long(x).hashCode()*31 + new Long(y).hashCode() ;
		}
	}

	    public static boolean isPal(String s){
	        for(int i=0, j=s.length()-1;i<=j;i++,j--){
	                if(s.charAt(i)!=s.charAt(j)) return false;
	        }
	        return true;
	    }
	    public static String rev(String s){
			StringBuilder sb=new StringBuilder(s);
			sb.reverse();
			return sb.toString();
	    }

	    public static long gcd(long x,long y){
		if(y==0)
			return x;
		else
			return gcd(y,x%y);
	    }

	    public static int gcd(int x,int y){
	    	if(y==0)
	    		return x;
	    	return gcd(y,x%y);
	    }

	    public static long gcdExtended(long a,long b,long[] x){

	        if(a==0){
	            x[0]=0;
	            x[1]=1;
	            return b;
	        }
	        long[] y=new long[2];
	        long gcd=gcdExtended(b%a, a, y);

	        x[0]=y[1]-(b/a)*y[0];
	        x[1]=y[0];

	        return gcd;
	    }

	    public static int abs(int a,int b){
		return (int)Math.abs(a-b);
	    }

	    public static long abs(long a,long b){
		return (long)Math.abs(a-b);
	    }

	    public static int max(int a,int b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static int min(int a,int b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long max(long a,long b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static long min(long a,long b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long pow(long n,long p,long m){
		 long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    if(result>=m)
		    result%=m;
		    p >>=1;
		    n*=n;
		    if(n>=m)
		    n%=m;
		}
		return result;
	    }

	    public static long pow(long n,long p){
		long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    p >>=1;
		    n*=n;
		}
		return result;
	    }
	    public static void debug(Object... o) {
			System.out.println(Arrays.deepToString(o));
		}
	    void run() throws Exception {
			is = System.in;
			out = new PrintWriter(System.out);
			solve();
			out.flush();
		}

	    public static void main(String[] args) throws Exception {
			new Thread(null, new Runnable() {
				public void run() {
					try {
						new code5().run();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}, "1", 1 << 26).start();

	    	//new code5().run();
		}
	    private byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		private int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		private boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		private int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b));
			return b;
		}

		private double nd() {
			return Double.parseDouble(ns());
		}

		private char nc() {
			return (char) skip();
		}

		private String ns() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		private char[] ns(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		private char[][] nm(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = ns(m);
			return map;
		}

		private int[] na(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = ni();
			return a;
		}
		private long[] nl(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nl();
			return a;
		}

		private int ni() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		private long nl() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

}

import java.util.*;
import java.text.*;
import java.io.*;
import java.math.*;
public class code5 {
	InputStream is;
	PrintWriter out;
	static long mod=pow(10,9)+7;
	static int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
 	void solve() throws Exception
	{
 		int n=ni();
 		long sum=nl();
 		long a[]=nl(n);
 		long ans=ncr(sum+n-1,n-1);
 		for(int i=1;i<(1<<n);i++)
 		{
 			long temp=0,count=0;
 			for(int j=0;j<n;j++)
 			{
 				if((i&(1<<j))!=0)
 				{
 					count++;
 					temp+=(a[j]+1);
 				}
 			}
 			if(count%2==0)
 			{
 				ans+=(ncr(sum-temp+n-1,n-1));
 				ans%=mod;
 			}else {
 				ans=(ans-ncr(sum-temp+n-1,n-1)+mod)%mod;
 			}
 		}
 		out.print(ans%mod);
	}
 	long ncr(long n,long r)
 	{
 		long nom=1;
 		if(n<0||n<r)
 			return 0;
 		for(long i=n;i>=(n-r+1);i--)
 		{
 			nom*=i;
 			nom%=mod;
 		}
 		long dom=1;
 		for(long i=r;i>=1;i--)
 		{
 			dom*=i;
 			dom%=mod;
 		}
 		return (nom*pow(dom,mod-2,mod))%mod;
 	}
 	/*void take(int n)
 	{
 		al=new ArrayList[n];
 		for(int i=0;i<n;i++)
 			al[i]=new ArrayList<Integer>();
 		for(int i=0;i<n-1;i++)
 		{
 			int x=ni()-1;
 			int y=ni()-1;
 			al[x].add(y);
 			al[y].add(x);
 		}
 	}*/

 	int check(long n)
 	{
 		int count=0;
 		while(n!=0)
 		{
 			if(n%10!=0)
 				break;
 			n/=10;
 			count++;
 		}
 		return count;
 	}
	public static int count(int x)
	{
		int num=0;
		while(x!=0)
		{
			x=x&(x-1);
			num++;
		}
		return num;
	}
	static long d, x, y;
	void extendedEuclid(long A, long B) {
	    if(B == 0) {
	        d = A;
	        x = 1;
	        y = 0;
	    }
	    else {
	        extendedEuclid(B, A%B);
	        long temp = x;
	        x = y;
	        y = temp - (A/B)*y;
	    }
	}
	long modInverse(long A,long M) //A and M are coprime
	{
	    extendedEuclid(A,M);
	    return (x%M+M)%M;    //x may be negative
	}
	public static void mergeSort(int[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(int arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		int left[] = new int[n1];
		int right[] = new int[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	public static void mergeSort(long[] arr, int l ,int r){
		if((r-l)>=1){
			int mid = (l+r)/2;
			mergeSort(arr,l,mid);
			mergeSort(arr,mid+1,r);
			merge(arr,l,r,mid);
		}
	}
	public static void merge(long arr[], int l, int r, int mid){
		int n1 = (mid-l+1), n2 = (r-mid);
		long left[] = new long[n1];
		long right[] = new long[n2];
		for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
		for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
		int i =0, j =0, k = l;
		while(i<n1 && j<n2){
			if(left[i]>right[j]){
				arr[k++] = right[j++];
			}
			else{
				arr[k++] = left[i++];
			}
		}
		while(i<n1) arr[k++] = left[i++];
		while(j<n2) arr[k++] = right[j++];
	}
	 static class Pair implements Comparable<Pair>{

	       int x,y,k;
	       int i,dir;
		Pair (int xx,int yy){
			this.x=xx;
			this.y=yy;
		}
		public int compareTo(Pair o) {
			if(this.x!=o.x)
				return this.x-o.x;
			return this.y-o.y;
		}

		public String toString(){
			return x+" "+y+" "+k+" "+i;}
		public boolean equals(Object o) {
			if (o instanceof Pair) {
				Pair p = (Pair)o;
				return p.x == x && p.y == y;
			}
			return false;
		}
		public int hashCode() {
			return new Long(x).hashCode()*31 + new Long(y).hashCode() ;
		}
	}

	    public static boolean isPal(String s){
	        for(int i=0, j=s.length()-1;i<=j;i++,j--){
	                if(s.charAt(i)!=s.charAt(j)) return false;
	        }
	        return true;
	    }
	    public static String rev(String s){
			StringBuilder sb=new StringBuilder(s);
			sb.reverse();
			return sb.toString();
	    }

	    public static long gcd(long x,long y){
		if(y==0)
			return x;
		else
			return gcd(y,x%y);
	    }

	    public static int gcd(int x,int y){
	    	if(y==0)
	    		return x;
	    	return gcd(y,x%y);
	    }

	    public static long gcdExtended(long a,long b,long[] x){

	        if(a==0){
	            x[0]=0;
	            x[1]=1;
	            return b;
	        }
	        long[] y=new long[2];
	        long gcd=gcdExtended(b%a, a, y);

	        x[0]=y[1]-(b/a)*y[0];
	        x[1]=y[0];

	        return gcd;
	    }

	    public static int abs(int a,int b){
		return (int)Math.abs(a-b);
	    }

	    public static long abs(long a,long b){
		return (long)Math.abs(a-b);
	    }

	    public static int max(int a,int b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static int min(int a,int b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long max(long a,long b){
		if(a>b)
			return a;
		else
			return b;
	    }

	    public static long min(long a,long b){
		if(a>b)
			return b;
		else
			return a;
	    }

	    public static long pow(long n,long p,long m){
		 long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    if(result>=m)
		    result%=m;
		    p >>=1;
		    n*=n;
		    if(n>=m)
		    n%=m;
		}
		return result;
	    }

	    public static long pow(long n,long p){
		long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    p >>=1;
		    n*=n;
		}
		return result;
	    }
	    public static void debug(Object... o) {
			System.out.println(Arrays.deepToString(o));
		}
	    void run() throws Exception {
			is = System.in;
			out = new PrintWriter(System.out);
			solve();
			out.flush();
		}

	    public static void main(String[] args) throws Exception {
			new Thread(null, new Runnable() {
				public void run() {
					try {
						new code5().run();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}, "1", 1 << 26).start();

	    	//new code5().run();
		}
	    private byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		private int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		private boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		private int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b));
			return b;
		}

		private double nd() {
			return Double.parseDouble(ns());
		}

		private char nc() {
			return (char) skip();
		}

		private String ns() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		private char[] ns(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		private char[][] nm(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = ns(m);
			return map;
		}

		private int[] na(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = ni();
			return a;
		}
		private long[] nl(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nl();
			return a;
		}

		private int ni() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		private long nl() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

}

import java.util.*;

import static java.lang.Math.min;

public class Solution {

    private static final long MOD = 1000000007;
    private static long FACT[] = new long[25];

    private static long modPow(long a, long x, long m) {
        long res = 1;
        while(x > 0) {
            if(x % 2 !=0) {
                res = (res*a) % m;
            }
            a = (a*a)%m;
            x /= 2;
        }
        return res % m;
    }

    private static long modInverse(long a, long p) {
        // p doit être premier
        return modPow(a, p - 2, p);
    }

    private static long nCr(long n, int r) {
        if(n < r) return 0;
        r = (int) min(r, n-r);
        long ret = 1;
        for(long x = n; x >= n - r + 1; x--){
            ret = (ret*(x%MOD))%MOD;
        }
        ret = (ret*modInverse(FACT[r], MOD))%MOD;
        return ret;
    }

    public static void main(String[] args) {
        FACT[0] = 1;
        for(int i = 1; i < 25; i++) {
            FACT[i] = (FACT[i - 1]*i)%MOD;
        }

        Scanner in = new Scanner(System.in);
        int n;
        long s, N;
        n = in.nextInt();
        s = in.nextLong();
        long f[] = new long[n];
        for(int i = 0; i < n; i++) {
            f[i] = in.nextLong();
        }

        N = 1 << n;

        long res = 0;
        for(int i = 0; i < N; i++) {
            int count = 0, p = 0;
            for(int j = 0; j < n; j++) {
                if((i & (1 << j) )> 0) {
                    count += f[j] + 1;
                    p++;
                }
            }
            if(count > s) continue;
            long C = nCr(s + n - 1 - count, n - 1);
            if(p % 2 == 1) C = -C;
            res = (res + C) % MOD;
        }

        System.out.println(res);
    }
}

import java.util.*;

import static java.lang.Math.min;

public class Solution {

    private static final long MOD = 1000000007;
    private static long FACT[] = new long[25];

    private static long modPow(long a, long x, long m) {
        long res = 1;
        while(x > 0) {
            if(x % 2 !=0) {
                res = (res*a) % m;
            }
            a = (a*a)%m;
            x /= 2;
        }
        return res % m;
    }

    private static long modInverse(long a, long p) {
        // p doit être premier
        return modPow(a, p - 2, p);
    }

    private static long nCr(long n, int r) {
        if(n < r) return 0;
        r = (int) min(r, n-r);
        long ret = 1;
        for(long x = n; x >= n - r + 1; x--){
            ret = (ret*(x%MOD))%MOD;
        }
        ret = (ret*modInverse(FACT[r], MOD))%MOD;
        return ret;
    }

    public static void main(String[] args) {
        FACT[0] = 1;
        for(int i = 1; i < 25; i++) {
            FACT[i] = (FACT[i - 1]*i)%MOD;
        }

        Scanner in = new Scanner(System.in);
        int n;
        long s, N;
        n = in.nextInt();
        s = in.nextLong();
        long f[] = new long[n];
        for(int i = 0; i < n; i++) {
            f[i] = in.nextLong();
        }

        N = 1 << n;

        long res = 0;
        for(int i = 0; i < N; i++) {
            int count = 0, p = 0;
            for(int j = 0; j < n; j++) {
                if((i & (1 << j) )> 0) {
                    count += f[j] + 1;
                    p++;
                }
            }
            if(count > s) continue;
            long C = nCr(s + n - 1 - count, n - 1);
            if(p % 2 == 1) C = -C;
            res = (res + C) % MOD;
            if(res < 0) res += MOD;
        }

        System.out.println(res);
    }
}

import java.util.*;

import static java.lang.Math.min;

public class Solution {

    private static final long MOD = 1000000007;
    private static long FACT[] = new long[25];

    private static long modPow(long a, long x, long m) {
        long res = 1;
        while(x > 0) {
            if(x % 2 !=0) {
                res = (res*a) % m;
            }
            a = (a*a)%m;
            x /= 2;
        }
        return res % m;
    }

    private static long modInverse(long a, long p) {
        // p doit être premier
        return modPow(a, p - 2, p);
    }

    private static long nCr(long n, int r) {
        if(n < r) return 0;
        r = (int) min(r, n-r);
        long ret = 1;
        for(long x = n; x >= n - r + 1; x--){
            ret = (ret*(x%MOD))%MOD;
        }
        ret = (ret*modInverse(FACT[r], MOD))%MOD;
        return ret;
    }

    public static void main(String[] args) {
        FACT[0] = 1;
        for(int i = 1; i < 25; i++) {
            FACT[i] = (FACT[i - 1]*i)%MOD;
        }

        Scanner in = new Scanner(System.in);
        int n;
        long s, N;
        n = in.nextInt();
        s = in.nextLong();
        long f[] = new long[n];
        for(int i = 0; i < n; i++) {
            f[i] = in.nextLong();
        }

        N = 1 << n;

        long res = 0;
        for(int i = 0; i < N; i++) {
            int count = 0, p = 0;
            for(int j = 0; j < n; j++) {
                if((i & (1 << j) )> 0) {
                    count += f[j] + 1;
                    p++;
                }
            }
            if(count > s) continue;
            long C = nCr(s + n - 1 - count, n - 1);
            if(p % 2 == 1) C = -C;
            res += C;
        }

        System.out.println(res);
    }
}

import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.IOException;
import java.util.Arrays;
import java.io.InputStream;
import java.io.OutputStreamWriter;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int n=in.readInt(), MOD=1000000007;
        long s=in.readLong(), ret=0;
        long[] F= IOUtils.readLongArray(in, n), revFac=IntegerUtils.generateReverseFactorials(n, MOD);
        for (int mask=0; mask<1<<n; mask++) {
            long used=0;
            for (int i=0; i<n; i++) if ((mask&(1<<i))>0)  used+=F[i]+1;
            if (used>s) continue;
            long s2=s-used, x=revFac[n-1];
            for (int i=1; i<n; i++) x=(s2+n-i)%MOD*x%MOD;
            ret+=(Integer.bitCount(mask)%2==0?1:-1)*x;
        }
        out.printLine(ret);
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public long readLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public void close() {
        writer.close();
    }

    public void printLine(long i) {
        writer.println(i);
    }

}

class IOUtils {

    public static long[] readLongArray(InputReader in, int size) {
        long[] array = new long[size];
        for (int i = 0; i < size; i++)
            array[i] = in.readLong();
        return array;
    }

}

class IntegerUtils {

    public static long[] generateReverse(int upTo, long module) {
        long[] result = new long[upTo];
        if (upTo > 1)
            result[1] = 1;
        for (int i = 2; i < upTo; i++)
            result[i] = (module - module / i * result[((int) (module % i))] % module) % module;
        return result;
    }

    public static long[] generateReverseFactorials(int upTo, long module) {
        long[] result = generateReverse(upTo, module);
        if (upTo > 0)
            result[0] = 1;
        for (int i = 1; i < upTo; i++)
            result[i] = result[i] * result[i - 1] % module;
        return result;
    }

}

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class e {
	static final long MOD = (long)1e9+7;
	public static void main(String[] args) {
		long[] invs = new long[300];
		invs[1] = 1;
		for (int i = 2; i < invs.length; ++i)
			invs[i] = (MOD - (MOD / i) * invs[((int) (MOD % i))] % MOD) % MOD;

		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		long s = in.nextLong();
		long[] fs = new long[n];
		for(int i=0;i<n;i++)
			fs[i] = in.nextLong();
		ArrayList<Term> ans = new ArrayList<>();
		ans.add(new Term(1, 0));
		for(int i=0;i<n;i++) {
			ArrayList<Term> cur = new ArrayList<>();
			cur.add(new Term(1,0));
			cur.add(new Term(-1,fs[i]+1));
			ans = multiply(ans, cur);
		}
		Collections.sort(ans);
		System.out.println(ans);
		long sum = 0;
		for(Term t : ans) {
			long pow = s - t.pow;
			if(pow < 0) continue;
			long choose = 1;
			for(int i=0;i<n-1;i++) {
				choose *= (pow+n-1-i) % MOD;
				choose %= MOD;
				choose *= invs[i+1];
				choose %= MOD;
//				System.out.println(" * " + (pow-i) + " / " + (i+1));
			}
//			System.out.println("(" + (pow+n-1) + " choose " + (n-1) + ") = " + choose);
			sum += t.c * choose;
			sum %= MOD;
		}
		if(sum < 0) sum += MOD;
		System.out.println(sum);
	}
	static ArrayList<Term> multiply(ArrayList<Term> eq1, ArrayList<Term> eq2) {
		ArrayList<Term> ans = new ArrayList<>();
		for(Term t1 : eq1) {
			for(Term t2 : eq2) {
				ans.add(new Term((t1.c * t2.c) % MOD, t1.pow + t2.pow));
			}
		}
		return ans;
	}
	static class Term implements Comparable<Term>{
		long c;
		long pow;
		public Term(long c, long pow) {
			this.c = c;
			this.pow = pow;
		}
		@Override
		public int compareTo(Term o) {
			return Long.compare(pow, o.pow);
		}
		@Override
		public String toString() {
			return c + "x^(" + pow + ")";
		}
	}
}

import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

public final class devu_and_flowers
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long mod=(long)(1e9+7);

	static long C(long n,long diff)
	{
		long ret=1,upper=n+diff-1;

		for(long x=upper;x>diff;x--)
		{
			ret=(ret*x)%mod;
		}

		return (ret*pow(fact(n-1),mod-2))%mod;
	}

	static long fact(long n)
	{
		long ret=1;

		for(long i=1;i<=n;i++)
		{
			ret=(ret*i)%mod;
		}

		return ret;
	}

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

	static Map<Long,Long> merge(Map<Long,Long> m1,long now)
	{
		Map<Long,Long> m2=new HashMap<>(),ret=new HashMap<>();

		m2.put(0L,1L);m2.put(now,-1L);

		for(Map.Entry<Long,Long> en1:m1.entrySet())
		{
			for(Map.Entry<Long,Long> en2:m2.entrySet())
			{
				long add=en1.getKey()+en2.getKey(),mul=(en1.getValue()*en2.getValue())%mod;

				ret.put(add,(ret.getOrDefault(add,0L)+mul)%mod);
			}
		}

		return ret;
	}

    public static void main(String args[]) throws Exception
    {
		int n=sc.nextInt();long s=sc.nextLong();

		long[] a=new long[n];

		for(int i=0;i<n;i++)
		{
			a[i]=sc.nextLong();
		}

		// 1-x^a[i]+1..

		Map<Long,Long> m1=new HashMap<>();m1.put(0L,1L);

		for(int i=0;i<n;i++)
		{
			m1=merge(m1,a[i]+1);
		}

		long res=0;

		for(Map.Entry<Long,Long> en:m1.entrySet())
		{
			long curr=en.getKey();

			if(curr<=s)
			{
				long diff=s-curr;

				long now=C(n,diff);

				long mul=(en.getValue()*now)%mod;

				res=(res+mul+mod)%mod;
			}
		}

		out.println(res);out.close();
    }

	private static class Pair
	{
		long pow,cof;

		public Pair(long pow,long cof)
		{
			this.pow=pow;this.cof=cof;
		}
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

public final class devu_and_flowers
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long mod=(long)(1e9+7);

	static long C(long n,long diff)
	{
		long ret=1,upper=n+diff-1;

		for(long x=upper;x>diff;x--)
		{
			ret=(ret*x)%mod;
		}

		return (ret*pow(fact(n-1),mod-2))%mod;
	}

	static long fact(long n)
	{
		long ret=1;

		for(long i=1;i<=n;i++)
		{
			ret=(ret*i)%mod;
		}

		return ret;
	}

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

	static Map<Long,Long> merge(Map<Long,Long> m1,long now)
	{
		Map<Long,Long> m2=new HashMap<>(),ret=new HashMap<>();

		m2.put(0L,1L);m2.put(now,(-1L+mod)%mod);

		for(Map.Entry<Long,Long> en1:m1.entrySet())
		{
			for(Map.Entry<Long,Long> en2:m2.entrySet())
			{
				long add=en1.getKey()+en2.getKey(),mul=(en1.getValue()*en2.getValue())%mod;

				ret.put(add,(ret.getOrDefault(add,0L)+mul)%mod);
			}
		}

		return ret;
	}

    public static void main(String args[]) throws Exception
    {
		int n=sc.nextInt();long s=sc.nextLong();

		long[] a=new long[n];

		for(int i=0;i<n;i++)
		{
			a[i]=sc.nextLong();
		}

		// 1-x^a[i]+1..

		Map<Long,Long> m1=new HashMap<>();m1.put(0L,1L);

		for(int i=0;i<n;i++)
		{
			m1=merge(m1,a[i]+1);
		}

		long res=0;

		for(Map.Entry<Long,Long> en:m1.entrySet())
		{
			long curr=en.getKey();

			if(curr<=s)
			{
				long diff=s-curr;

				long now=C(n,diff);

				long mul=(en.getValue()*now)%mod;

				res=(res+mul+mod)%mod;
			}
		}

		out.println(res);out.close();
    }

	private static class Pair
	{
		long pow,cof;

		public Pair(long pow,long cof)
		{
			this.pow=pow;this.cof=cof;
		}
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

import java.awt.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.List;

import static java.lang.Math.max;
import static java.lang.Math.min;

public class E implements Runnable{

    // SOLUTION!!!
    // HACK ME PLEASE IF YOU CAN!!!
    // PLEASE!!!
    // PLEASE!!!
    // PLEASE!!!

    private final static Random rnd = new Random();
    private final static String fileName = "";

    final static long MODULO = 1000 * 1000 * 1000 + 7;

    long inverseNMinus1Factorial;

    private void solve() {
        int n = readInt();
        long s = readLong();

        long[] f = readLongArray(n);

        Map<Long, Long> coeffs = new HashMap<>();
        coeffs.put(0L, 1L);

        for (long size : f) {
            List<Map.Entry<Long, Long>> coeffEntries = new ArrayList<>(coeffs.entrySet());
            for (Map.Entry<Long, Long> coeffEntry : coeffEntries) {
                long power = coeffEntry.getKey();
                long coeff = coeffEntry.getValue();

                long nextPower = power + size + 1;
                coeffs.put(nextPower,
                        add(coeffs.getOrDefault(nextPower, 0L), -coeff)
                );
            }
        }

        long nMinus1Factorial = multSequence(1, n - 1);
        this.inverseNMinus1Factorial = inverse(nMinus1Factorial);

        long answer = 0;
        for (Map.Entry<Long, Long> coeffEntry : coeffs.entrySet()) {
            long power = coeffEntry.getKey();
            long coeff = coeffEntry.getValue();

            if (s >= power) {
                long need = s - power;
                answer = add(answer, mult(binom(n + need - 1, need), coeff));
            }
        }

        out.println(answer);
    }

    long multSequence(long start, long end) {
        long res = 1;
        for (long i = start; i <= end; ++i) {
            res = mult(res, i);
        }

        return res;
    }

    long inverse(long x) {
        return binpow(x, MODULO - 2);
    }

    long binpow(long base, long power) {
        if (power == 0) return 1;

        if ((power & 1) == 0) {
            long half = binpow(base, power >> 1);
            return mult(half, half);
        } else {
            long prev = binpow(base, power - 1);
            return mult(prev, base);
        }
    }

    long binom(long n, long k) {
        return mult(
                multSequence(k + 1, n),
                inverseNMinus1Factorial
        );
    }

    long add(long a, long b) {
        return (a + b + MODULO) % MODULO;
    }

    long mult(long a, long b) {
        return (a % MODULO) * (b % MODULO) % MODULO;
    }

    /////////////////////////////////////////////////////////////////////

    private final static boolean FIRST_INPUT_STRING = false;
    private final static boolean MULTIPLE_TESTS = true;
    private final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

    private final static int MAX_STACK_SIZE = 128;

    private final static boolean OPTIMIZE_READ_NUMBERS = true;

    /////////////////////////////////////////////////////////////////////

    public void run(){
        try{
            timeInit();
            Locale.setDefault(Locale.US);

            init();

            if (ONLINE_JUDGE) {
                solve();
            } else {
                do {
                    try {
                        timeInit();
                        solve();
                        time();

                        out.println();
                    } catch (NumberFormatException e) {
                        break;
                    } catch (NullPointerException e) {
                        if (FIRST_INPUT_STRING) break;
                        else throw e;
                    }
                } while (MULTIPLE_TESTS);
            }

            out.close();
            time();
        }catch (Exception e){
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private BufferedReader in;
    private OutputWriter out;
    private StringTokenizer tok = new StringTokenizer("");

    public static void main(String[] args){
        new Thread(null, new E(), "", MAX_STACK_SIZE * (1L << 20)).start();
    }

    /////////////////////////////////////////////////////////////////////

    private void init() throws FileNotFoundException{
        Locale.setDefault(Locale.US);

        if (ONLINE_JUDGE){
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new OutputWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new OutputWriter(fileName + ".out");
            }
        }else{
            in = new BufferedReader(new FileReader("input.txt"));
            out = new OutputWriter("output.txt");
        }
    }

    ////////////////////////////////////////////////////////////////

    private long timeBegin;

    private void timeInit() {
        this.timeBegin = System.currentTimeMillis();
    }

    private void time(){
        long timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    private void debug(Object... objects){
        if (ONLINE_JUDGE){
            for (Object o: objects){
                System.err.println(o.toString());
            }
        }
    }

    /////////////////////////////////////////////////////////////////////

    private String delim = " ";

    private String readLine() {
        try {
            return in.readLine();
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private String readString() {
        try {
            while(!tok.hasMoreTokens()){
                tok = new StringTokenizer(readLine());
            }

            return tok.nextToken(delim);
        } catch (NullPointerException e) {
            return null;
        }
    }

    /////////////////////////////////////////////////////////////////

    private final char NOT_A_SYMBOL = '\0';

    private char readChar() {
        try {
            int intValue = in.read();

            if (intValue == -1){
                return NOT_A_SYMBOL;
            }

            return (char) intValue;
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private char[] readCharArray() {
        return readLine().toCharArray();
    }

    private char[][] readCharField(int rowsCount) {
        char[][] field = new char[rowsCount][];
        for (int row = 0; row < rowsCount; ++row) {
            field[row] = readCharArray();
        }

        return field;
    }

    /////////////////////////////////////////////////////////////////

    private long optimizedReadLong() {
        int sign = 1;
        long result = 0;
        boolean started = false;
        while (true) {
            try {
                int j = in.read();
                if (-1 == j) {
                    if (started) return sign * result;
                    throw new NumberFormatException();
                }

                if (j == '-') {
                    if (started) throw new NumberFormatException();
                    sign = -sign;
                }

                if ('0' <= j && j <= '9') {
                    result = result * 10 + j - '0';
                    started = true;
                } else if (started) {
                    return sign * result;
                }
            } catch (IOException e) {
                throw new RuntimeIOException(e);
            }
        }
    }

    private int readInt() {

        if (!OPTIMIZE_READ_NUMBERS) {
            return Integer.parseInt(readString());
        } else {
            return (int) optimizedReadLong();
        }
    }

    private int[] readIntArray(int size) {
        int[] array = new int[size];

        for (int index = 0; index < size; ++index){
            array[index] = readInt();
        }

        return array;
    }

    private int[] readSortedIntArray(int size) {
        Integer[] array = new Integer[size];

        for (int index = 0; index < size; ++index) {
            array[index] = readInt();
        }
        Arrays.sort(array);

        int[] sortedArray = new int[size];
        for (int index = 0; index < size; ++index) {
            sortedArray[index] = array[index];
        }

        return sortedArray;
    }

    private int[] readIntArrayWithDecrease(int size) {
        int[] array = readIntArray(size);

        for (int i = 0; i < size; ++i) {
            array[i]--;
        }

        return array;
    }

    ///////////////////////////////////////////////////////////////////

    private int[][] readIntMatrix(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArray(columnsCount);
        }

        return matrix;
    }

    private int[][] readIntMatrixWithDecrease(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArrayWithDecrease(columnsCount);
        }

        return matrix;
    }

    ///////////////////////////////////////////////////////////////////

    private long readLong() {
        if (!OPTIMIZE_READ_NUMBERS) {
            return Long.parseLong(readString());
        } else {
            return optimizedReadLong();
        }
    }

    private long[] readLongArray(int size) {
        long[] array = new long[size];

        for (int index = 0; index < size; ++index){
            array[index] = readLong();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private double readDouble() {
        return Double.parseDouble(readString());
    }

    private double[] readDoubleArray(int size) {
        double[] array = new double[size];

        for (int index = 0; index < size; ++index){
            array[index] = readDouble();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private BigInteger readBigInteger() {
        return new BigInteger(readString());
    }

    private BigDecimal readBigDecimal() {
        return new BigDecimal(readString());
    }

    /////////////////////////////////////////////////////////////////////

    private Point readPoint() {
        int x = readInt();
        int y = readInt();
        return new Point(x, y);
    }

    private Point[] readPointArray(int size) {
        Point[] array = new Point[size];

        for (int index = 0; index < size; ++index){
            array[index] = readPoint();
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    @Deprecated
    private List<Integer>[] readGraph(int vertexNumber, int edgeNumber) {
        @SuppressWarnings("unchecked")
        List<Integer>[] graph = new List[vertexNumber];

        for (int index = 0; index < vertexNumber; ++index){
            graph[index] = new ArrayList<>();
        }

        while (edgeNumber-- > 0){
            int from = readInt() - 1;
            int to = readInt() - 1;

            graph[from].add(to);
            graph[to].add(from);
        }

        return graph;
    }

    private static class GraphBuilder {

        final int size;
        final List<Integer>[] edges;

        static GraphBuilder createInstance(int size) {
            List<Integer>[] edges = new List[size];
            for (int v = 0; v < size; ++v) {
                edges[v] = new ArrayList<>();
            }

            return new GraphBuilder(edges);
        }

        private GraphBuilder(List<Integer>[] edges) {
            this.size = edges.length;
            this.edges = edges;
        }

        public void addEdge(int from, int to) {
            addDirectedEdge(from, to);
            addDirectedEdge(to, from);
        }

        public void addDirectedEdge(int from, int to) {
            edges[from].add(to);
        }

        public int[][] build() {
            int[][] graph = new int[size][];
            for (int v = 0; v < size; ++v) {
                List<Integer> vEdges = edges[v];
                graph[v] = castInt(vEdges);
            }

            return graph;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IntIndexPair {

        static Comparator<IntIndexPair> increaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return value1 - value2;

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        static Comparator<IntIndexPair> decreaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return -(value1 - value2);

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        int value, index;

        IntIndexPair(int value, int index) {
            super();
            this.value = value;
            this.index = index;
        }

        int getRealIndex() {
            return index + 1;
        }
    }

    private IntIndexPair[] readIntIndexArray(int size) {
        IntIndexPair[] array = new IntIndexPair[size];

        for (int index = 0; index < size; ++index) {
            array[index] = new IntIndexPair(readInt(), index);
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    private static class OutputWriter extends PrintWriter {

        final int DEFAULT_PRECISION = 12;

        private int precision;
        private String format, formatWithSpace;

        {
            precision = DEFAULT_PRECISION;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        OutputWriter(OutputStream out) {
            super(out);
        }

        OutputWriter(String fileName) throws FileNotFoundException {
            super(fileName);
        }

        int getPrecision() {
            return precision;
        }

        void setPrecision(int precision) {
            precision = max(0, precision);
            this.precision = precision;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        String createFormat(int precision){
            return "%." + precision + "f";
        }

        @Override
        public void print(double d){
            printf(format, d);
        }

        void printWithSpace(double d){
            printf(formatWithSpace, d);
        }

        void printAll(double...d){
            for (int i = 0; i < d.length - 1; ++i){
                printWithSpace(d[i]);
            }

            print(d[d.length - 1]);
        }

        @Override
        public void println(double d){
            printlnAll(d);
        }

        void printlnAll(double... d){
            printAll(d);
            println();
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class RuntimeIOException extends RuntimeException {

        /**
         *
         */
        private static final long serialVersionUID = -6463830523020118289L;

        RuntimeIOException(Throwable cause) {
            super(cause);
        }
    }

    /////////////////////////////////////////////////////////////////////
    //////////////// Some useful constants and functions ////////////////
    /////////////////////////////////////////////////////////////////////

    private static final int[][] steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    private static final int[][] steps8 = {
            {-1, 0}, {1, 0}, {0, -1}, {0, 1},
            {-1, -1}, {1, 1}, {1, -1}, {-1, 1}
    };

    private static boolean checkCell(int row, int rowsCount, int column, int columnsCount) {
        return checkIndex(row, rowsCount) && checkIndex(column, columnsCount);
    }

    private static boolean checkIndex(int index, int lim){
        return (0 <= index && index < lim);
    }

    /////////////////////////////////////////////////////////////////////

    private static boolean checkBit(int mask, int bit){
        return (mask & (1 << bit)) != 0;
    }
    private static boolean checkBit(long mask, int bit){
        return (mask & (1L << bit)) != 0;
    }

    /////////////////////////////////////////////////////////////////////

    private static long getSum(int[] array) {
        long sum = 0;
        for (int value: array) {
            sum += value;
        }

        return sum;
    }

    private static Point getMinMax(int[] array) {
        int min = array[0];
        int max = array[0];

        for (int index = 0, size = array.length; index < size; ++index, ++index) {
            int value = array[index];

            if (index == size - 1) {
                min = min(min, value);
                max = max(max, value);
            } else {
                int otherValue = array[index + 1];

                if (value <= otherValue) {
                    min = min(min, value);
                    max = max(max, otherValue);
                } else {
                    min = min(min, otherValue);
                    max = max(max, value);
                }
            }
        }

        return new Point(min, max);
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] getPrimes(int n) {
        boolean[] used = new boolean[n];
        used[0] = used[1] = true;

        int size = 0;
        for (int i = 2; i < n; ++i) {
            if (!used[i]) {
                ++size;
                for (int j = 2 * i; j < n; j += i) {
                    used[j] = true;
                }
            }
        }

        int[] primes = new int[size];
        for (int i = 0, cur = 0; i < n; ++i) {
            if (!used[i]) {
                primes[cur++] = i;
            }
        }

        return primes;
    }

    /////////////////////////////////////////////////////////////////////

    private static long lcm(long a, long b) {
        return a / gcd(a, b) * b;
    }

    private static long gcd(long a, long b) {
        return (a == 0 ? b : gcd(b % a, a));
    }

    /////////////////////////////////////////////////////////////////////

    private static class MultiSet<ValueType> {

        public static <ValueType> MultiSet<ValueType> createMultiSet() {
            Map<ValueType, Integer> multiset = new HashMap<>();
            return new MultiSet<>(multiset);
        }

        private final Map<ValueType, Integer> multiset;
        private int size;

        public MultiSet(Map<ValueType, Integer> multiset) {
            this.multiset = multiset;
            this.size = 0;
        }

        public int size() {
            return size;
        }

        public void inc(ValueType value) {
            int count = get(value);
            multiset.put(value, count + 1);

            ++size;
        }

        public void dec(ValueType value) {
            int count = get(value);
            if (count == 0) return;

            if (count == 1) multiset.remove(value);
            else multiset.put(value, count - 1);

            --size;
        }

        public int get(ValueType value) {
            Integer count = multiset.get(value);
            return (count == null ? 0 : count);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IdMap<KeyType> extends HashMap<KeyType, Integer> {

        /**
         *
         */
        private static final long serialVersionUID = -3793737771950984481L;

        public IdMap() {
            super();
        }

        int getId(KeyType key) {
            Integer id = super.get(key);
            if (id == null) {
                super.put(key, id = size());
            }

            return id;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] castInt(List<Integer> list) {
        int[] array = new int[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }

    private static long[] castLong(List<Long> list) {
        long[] array = new long[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }
}

import java.awt.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.List;

import static java.lang.Math.max;
import static java.lang.Math.min;

public class E implements Runnable{

    // SOLUTION!!!
    // HACK ME PLEASE IF YOU CAN!!!
    // PLEASE!!!
    // PLEASE!!!
    // PLEASE!!!

    private final static Random rnd = new Random();
    private final static String fileName = "";

    final static long MODULO = 1000 * 1000 * 1000 + 7;

    long inverseNMinus1Factorial;

    private void solve() {
        int n = readInt();
        long s = readLong();

        long[] f = readLongArray(n);

        Map<Long, Long> coeffs = new HashMap<>();
        coeffs.put(0L, 1L);

        for (long size : f) {
            List<Map.Entry<Long, Long>> coeffEntries = new ArrayList<>(coeffs.entrySet());
            for (Map.Entry<Long, Long> coeffEntry : coeffEntries) {
                long power = coeffEntry.getKey();
                long coeff = coeffEntry.getValue();

                long nextPower = power + size + 1;
                coeffs.put(nextPower,
                        add(coeffs.getOrDefault(nextPower, 0L), -coeff)
                );
            }
        }

        long nMinus1Factorial = multSequence(1, n - 1);
        this.inverseNMinus1Factorial = inverse(nMinus1Factorial);

        long answer = 0;
        for (Map.Entry<Long, Long> coeffEntry : coeffs.entrySet()) {
            long power = coeffEntry.getKey();
            long coeff = coeffEntry.getValue();

            if (s >= power) {
                long need = s - power;
                answer = add(answer, mult(binom(n + need - 1, need), coeff));
            }
        }

        out.println(answer);
    }

    long multSequence(long start, long end) {
        long res = 1;
        for (long i = start; i <= end; ++i) {
            res = mult(res, i);
        }

        return res;
    }

    long inverse(long x) {
        return binpow(x, MODULO - 2);
    }

    long binpow(long base, long power) {
        if (power == 0) return 1;

        if ((power & 1) == 0) {
            long half = binpow(base, power >> 1);
            return mult(half, half);
        } else {
            long prev = binpow(base, power - 1);
            return mult(prev, base);
        }
    }

    long binom(long n, long k) {
        return mult(
                multSequence(k + 1, n),
                inverseNMinus1Factorial
        );
    }

    long add(long a, long b) {
        return (a + b + MODULO) % MODULO;
    }

    long mult(long a, long b) {
        return (a * b) % MODULO;
    }

    /////////////////////////////////////////////////////////////////////

    private final static boolean FIRST_INPUT_STRING = false;
    private final static boolean MULTIPLE_TESTS = true;
    private final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

    private final static int MAX_STACK_SIZE = 128;

    private final static boolean OPTIMIZE_READ_NUMBERS = true;

    /////////////////////////////////////////////////////////////////////

    public void run(){
        try{
            timeInit();
            Locale.setDefault(Locale.US);

            init();

            if (ONLINE_JUDGE) {
                solve();
            } else {
                do {
                    try {
                        timeInit();
                        solve();
                        time();

                        out.println();
                    } catch (NumberFormatException e) {
                        break;
                    } catch (NullPointerException e) {
                        if (FIRST_INPUT_STRING) break;
                        else throw e;
                    }
                } while (MULTIPLE_TESTS);
            }

            out.close();
            time();
        }catch (Exception e){
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private BufferedReader in;
    private OutputWriter out;
    private StringTokenizer tok = new StringTokenizer("");

    public static void main(String[] args){
        new Thread(null, new E(), "", MAX_STACK_SIZE * (1L << 20)).start();
    }

    /////////////////////////////////////////////////////////////////////

    private void init() throws FileNotFoundException{
        Locale.setDefault(Locale.US);

        if (ONLINE_JUDGE){
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new OutputWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new OutputWriter(fileName + ".out");
            }
        }else{
            in = new BufferedReader(new FileReader("input.txt"));
            out = new OutputWriter("output.txt");
        }
    }

    ////////////////////////////////////////////////////////////////

    private long timeBegin;

    private void timeInit() {
        this.timeBegin = System.currentTimeMillis();
    }

    private void time(){
        long timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    private void debug(Object... objects){
        if (ONLINE_JUDGE){
            for (Object o: objects){
                System.err.println(o.toString());
            }
        }
    }

    /////////////////////////////////////////////////////////////////////

    private String delim = " ";

    private String readLine() {
        try {
            return in.readLine();
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private String readString() {
        try {
            while(!tok.hasMoreTokens()){
                tok = new StringTokenizer(readLine());
            }

            return tok.nextToken(delim);
        } catch (NullPointerException e) {
            return null;
        }
    }

    /////////////////////////////////////////////////////////////////

    private final char NOT_A_SYMBOL = '\0';

    private char readChar() {
        try {
            int intValue = in.read();

            if (intValue == -1){
                return NOT_A_SYMBOL;
            }

            return (char) intValue;
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private char[] readCharArray() {
        return readLine().toCharArray();
    }

    private char[][] readCharField(int rowsCount) {
        char[][] field = new char[rowsCount][];
        for (int row = 0; row < rowsCount; ++row) {
            field[row] = readCharArray();
        }

        return field;
    }

    /////////////////////////////////////////////////////////////////

    private long optimizedReadLong() {
        int sign = 1;
        long result = 0;
        boolean started = false;
        while (true) {
            try {
                int j = in.read();
                if (-1 == j) {
                    if (started) return sign * result;
                    throw new NumberFormatException();
                }

                if (j == '-') {
                    if (started) throw new NumberFormatException();
                    sign = -sign;
                }

                if ('0' <= j && j <= '9') {
                    result = result * 10 + j - '0';
                    started = true;
                } else if (started) {
                    return sign * result;
                }
            } catch (IOException e) {
                throw new RuntimeIOException(e);
            }
        }
    }

    private int readInt() {

        if (!OPTIMIZE_READ_NUMBERS) {
            return Integer.parseInt(readString());
        } else {
            return (int) optimizedReadLong();
        }
    }

    private int[] readIntArray(int size) {
        int[] array = new int[size];

        for (int index = 0; index < size; ++index){
            array[index] = readInt();
        }

        return array;
    }

    private int[] readSortedIntArray(int size) {
        Integer[] array = new Integer[size];

        for (int index = 0; index < size; ++index) {
            array[index] = readInt();
        }
        Arrays.sort(array);

        int[] sortedArray = new int[size];
        for (int index = 0; index < size; ++index) {
            sortedArray[index] = array[index];
        }

        return sortedArray;
    }

    private int[] readIntArrayWithDecrease(int size) {
        int[] array = readIntArray(size);

        for (int i = 0; i < size; ++i) {
            array[i]--;
        }

        return array;
    }

    ///////////////////////////////////////////////////////////////////

    private int[][] readIntMatrix(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArray(columnsCount);
        }

        return matrix;
    }

    private int[][] readIntMatrixWithDecrease(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArrayWithDecrease(columnsCount);
        }

        return matrix;
    }

    ///////////////////////////////////////////////////////////////////

    private long readLong() {
        if (!OPTIMIZE_READ_NUMBERS) {
            return Long.parseLong(readString());
        } else {
            return optimizedReadLong();
        }
    }

    private long[] readLongArray(int size) {
        long[] array = new long[size];

        for (int index = 0; index < size; ++index){
            array[index] = readLong();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private double readDouble() {
        return Double.parseDouble(readString());
    }

    private double[] readDoubleArray(int size) {
        double[] array = new double[size];

        for (int index = 0; index < size; ++index){
            array[index] = readDouble();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private BigInteger readBigInteger() {
        return new BigInteger(readString());
    }

    private BigDecimal readBigDecimal() {
        return new BigDecimal(readString());
    }

    /////////////////////////////////////////////////////////////////////

    private Point readPoint() {
        int x = readInt();
        int y = readInt();
        return new Point(x, y);
    }

    private Point[] readPointArray(int size) {
        Point[] array = new Point[size];

        for (int index = 0; index < size; ++index){
            array[index] = readPoint();
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    @Deprecated
    private List<Integer>[] readGraph(int vertexNumber, int edgeNumber) {
        @SuppressWarnings("unchecked")
        List<Integer>[] graph = new List[vertexNumber];

        for (int index = 0; index < vertexNumber; ++index){
            graph[index] = new ArrayList<>();
        }

        while (edgeNumber-- > 0){
            int from = readInt() - 1;
            int to = readInt() - 1;

            graph[from].add(to);
            graph[to].add(from);
        }

        return graph;
    }

    private static class GraphBuilder {

        final int size;
        final List<Integer>[] edges;

        static GraphBuilder createInstance(int size) {
            List<Integer>[] edges = new List[size];
            for (int v = 0; v < size; ++v) {
                edges[v] = new ArrayList<>();
            }

            return new GraphBuilder(edges);
        }

        private GraphBuilder(List<Integer>[] edges) {
            this.size = edges.length;
            this.edges = edges;
        }

        public void addEdge(int from, int to) {
            addDirectedEdge(from, to);
            addDirectedEdge(to, from);
        }

        public void addDirectedEdge(int from, int to) {
            edges[from].add(to);
        }

        public int[][] build() {
            int[][] graph = new int[size][];
            for (int v = 0; v < size; ++v) {
                List<Integer> vEdges = edges[v];
                graph[v] = castInt(vEdges);
            }

            return graph;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IntIndexPair {

        static Comparator<IntIndexPair> increaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return value1 - value2;

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        static Comparator<IntIndexPair> decreaseComparator = new Comparator<E.IntIndexPair>() {

            @Override
            public int compare(E.IntIndexPair indexPair1, E.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return -(value1 - value2);

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        int value, index;

        IntIndexPair(int value, int index) {
            super();
            this.value = value;
            this.index = index;
        }

        int getRealIndex() {
            return index + 1;
        }
    }

    private IntIndexPair[] readIntIndexArray(int size) {
        IntIndexPair[] array = new IntIndexPair[size];

        for (int index = 0; index < size; ++index) {
            array[index] = new IntIndexPair(readInt(), index);
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    private static class OutputWriter extends PrintWriter {

        final int DEFAULT_PRECISION = 12;

        private int precision;
        private String format, formatWithSpace;

        {
            precision = DEFAULT_PRECISION;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        OutputWriter(OutputStream out) {
            super(out);
        }

        OutputWriter(String fileName) throws FileNotFoundException {
            super(fileName);
        }

        int getPrecision() {
            return precision;
        }

        void setPrecision(int precision) {
            precision = max(0, precision);
            this.precision = precision;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        String createFormat(int precision){
            return "%." + precision + "f";
        }

        @Override
        public void print(double d){
            printf(format, d);
        }

        void printWithSpace(double d){
            printf(formatWithSpace, d);
        }

        void printAll(double...d){
            for (int i = 0; i < d.length - 1; ++i){
                printWithSpace(d[i]);
            }

            print(d[d.length - 1]);
        }

        @Override
        public void println(double d){
            printlnAll(d);
        }

        void printlnAll(double... d){
            printAll(d);
            println();
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class RuntimeIOException extends RuntimeException {

        /**
         *
         */
        private static final long serialVersionUID = -6463830523020118289L;

        RuntimeIOException(Throwable cause) {
            super(cause);
        }
    }

    /////////////////////////////////////////////////////////////////////
    //////////////// Some useful constants and functions ////////////////
    /////////////////////////////////////////////////////////////////////

    private static final int[][] steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    private static final int[][] steps8 = {
            {-1, 0}, {1, 0}, {0, -1}, {0, 1},
            {-1, -1}, {1, 1}, {1, -1}, {-1, 1}
    };

    private static boolean checkCell(int row, int rowsCount, int column, int columnsCount) {
        return checkIndex(row, rowsCount) && checkIndex(column, columnsCount);
    }

    private static boolean checkIndex(int index, int lim){
        return (0 <= index && index < lim);
    }

    /////////////////////////////////////////////////////////////////////

    private static boolean checkBit(int mask, int bit){
        return (mask & (1 << bit)) != 0;
    }
    private static boolean checkBit(long mask, int bit){
        return (mask & (1L << bit)) != 0;
    }

    /////////////////////////////////////////////////////////////////////

    private static long getSum(int[] array) {
        long sum = 0;
        for (int value: array) {
            sum += value;
        }

        return sum;
    }

    private static Point getMinMax(int[] array) {
        int min = array[0];
        int max = array[0];

        for (int index = 0, size = array.length; index < size; ++index, ++index) {
            int value = array[index];

            if (index == size - 1) {
                min = min(min, value);
                max = max(max, value);
            } else {
                int otherValue = array[index + 1];

                if (value <= otherValue) {
                    min = min(min, value);
                    max = max(max, otherValue);
                } else {
                    min = min(min, otherValue);
                    max = max(max, value);
                }
            }
        }

        return new Point(min, max);
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] getPrimes(int n) {
        boolean[] used = new boolean[n];
        used[0] = used[1] = true;

        int size = 0;
        for (int i = 2; i < n; ++i) {
            if (!used[i]) {
                ++size;
                for (int j = 2 * i; j < n; j += i) {
                    used[j] = true;
                }
            }
        }

        int[] primes = new int[size];
        for (int i = 0, cur = 0; i < n; ++i) {
            if (!used[i]) {
                primes[cur++] = i;
            }
        }

        return primes;
    }

    /////////////////////////////////////////////////////////////////////

    private static long lcm(long a, long b) {
        return a / gcd(a, b) * b;
    }

    private static long gcd(long a, long b) {
        return (a == 0 ? b : gcd(b % a, a));
    }

    /////////////////////////////////////////////////////////////////////

    private static class MultiSet<ValueType> {

        public static <ValueType> MultiSet<ValueType> createMultiSet() {
            Map<ValueType, Integer> multiset = new HashMap<>();
            return new MultiSet<>(multiset);
        }

        private final Map<ValueType, Integer> multiset;
        private int size;

        public MultiSet(Map<ValueType, Integer> multiset) {
            this.multiset = multiset;
            this.size = 0;
        }

        public int size() {
            return size;
        }

        public void inc(ValueType value) {
            int count = get(value);
            multiset.put(value, count + 1);

            ++size;
        }

        public void dec(ValueType value) {
            int count = get(value);
            if (count == 0) return;

            if (count == 1) multiset.remove(value);
            else multiset.put(value, count - 1);

            --size;
        }

        public int get(ValueType value) {
            Integer count = multiset.get(value);
            return (count == null ? 0 : count);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IdMap<KeyType> extends HashMap<KeyType, Integer> {

        /**
         *
         */
        private static final long serialVersionUID = -3793737771950984481L;

        public IdMap() {
            super();
        }

        int getId(KeyType key) {
            Integer id = super.get(key);
            if (id == null) {
                super.put(key, id = size());
            }

            return id;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] castInt(List<Integer> list) {
        int[] array = new int[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }

    private static long[] castLong(List<Long> list) {
        long[] array = new long[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }
}