Devu wants to decorate his garden with flowers. He has purchased n boxes, where the i-th box contains fi flowers. All flowers in a single box are of the same color (hence they are indistinguishable). Also, no two boxes have flowers of the same color.Now Devu wants to select exactly s flowers from the boxes to decorate his garden. Devu would like to know, in how many different ways can he select the flowers from each box? Since this number may be very large, he asks you to find the number modulo (109 + 7). Devu considers two ways different if there is at least one box from which different number of flowers are selected in these two ways.

The first line of input contains two space-separated integers n and s (1 ≤ n ≤ 20, 0 ≤ s ≤ 1014). The second line contains n space-separated integers f1, f2, ... fn (0 ≤ fi ≤ 1012).

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

NoteSample 1. There are two ways of selecting 3 flowers: {1, 2} and {0, 3}.Sample 2. There is only one way of selecting 4 flowers: {2, 2}.Sample 3. There are three ways of selecting 5 flowers: {1, 2, 2}, {0, 3, 2}, and {1, 3, 1}.

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.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();
	}
}

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.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.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();
    }
}

//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)); }
}

//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.*;
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.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.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.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;
	}

}

// 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.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.*;
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 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);
    }
}

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.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.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.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.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;
    }
}