using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;

class ProblemD {
    static string inputFileName = "../../input.txt";
    static StreamReader fileReader;
    static string[] inputTokens;
    static int curInputTokenIndex;
    static string NextToken() {
        string ret = "";
        while (ret == "") {
            if (inputTokens == null || curInputTokenIndex >= inputTokens.Length) {
                string line;
                if (Type.GetType("HaitaoLocal") != null) {
                    if (fileReader == null) {
                        fileReader = new StreamReader(inputFileName);
                    }
                    line = fileReader.ReadLine();
                    if (line == null) {
                        throw new Exception("Error: out of input tokens!");
                    }
                } else {
                    line = Console.ReadLine();
                }
                inputTokens = line.Split();
                curInputTokenIndex = 0;
            }
            ret = inputTokens[curInputTokenIndex++];
        }
        return ret;
    }
    static int ReadInt() {
        return Int32.Parse(NextToken());
    }
    static string ReadString() {
        return NextToken();
    }
    static long ReadLong() {
        return Int64.Parse(NextToken());
    }
    static int[] ReadIntArray(int length) {
        int[] ret = new int[length];
        for (int i = 0; i < length; i++) {
            ret[i] = ReadInt();
        }
        return ret;
    }
    static string[] ReadStringArray(int length) {
        string[] ret = new string[length];
        for (int i = 0; i < length; i++) {
            ret[i] = ReadString();
        }
        return ret;
    }
    static long[] ReadLongArray(int length) {
        long[] ret = new long[length];
        for (int i = 0; i < length; i++) {
            ret[i] = ReadLong();
        }
        return ret;
    }
    static string DoubleToString(double d) {
        return d.ToString(new CultureInfo("en-US"));
    }

    public static void Main(string[] args) {
        int Q = 1000001;
        bool[] notPrime = new bool[Q];
        notPrime[0] = true;
        notPrime[1] = true;
        for (int i = 2; i <= Math.Sqrt(notPrime.Length); i++) {
            if (!notPrime[i]) {
                for (int j = i * 2; j < notPrime.Length; j += i) {
                    notPrime[j] = true;
                }
            }
        }
        List<int> primes = new List<int>();
        for(int i=0; i<Q; i++) if(!notPrime[i]) primes.Add(i);
        long N = ReadLong();
        List<long> factors = new List<long>();
        for (long i = 1; i <= 1000000; i++) {
            if (N % i != 0) continue;
            if (i * i > N) break;
            factors.Add(i);
            if(i*i!=N) factors.Add(N / i);
        }
        factors.Sort();
        Dictionary<long, long> pmap = new Dictionary<long, long>();
        foreach (long f in factors) {
            long k = f - 1;
            bool flag = true;
            foreach (int p in primes) {
                if (k % p == 0) {
                    flag = false;
                    long x = 1;
                    while (x < k) x *= p;
                    if (x == k) {
                        pmap.Add(f, p);
                    } else {
                        break;
                    }
                }
            }
            if (flag && k>1) pmap.Add(f, k);
        }
        //foreach (long key in pmap.Keys) {
        //    Console.WriteLine(key + " " + pmap[key]);
        //}
        Dictionary<long, long> dp = new Dictionary<long, long>();

        foreach (long i in factors) {
            dp[i] = 0;
        }
        dp[1] = 1;
        Dictionary<long,long> used = new Dictionary<long, long>();
        foreach (long key in pmap.Keys) {
            long p = pmap[key];
            if (used.ContainsKey(p)) continue;
            used.Add(p, 0);

            Dictionary<long, long> toAdd = new Dictionary<long, long>();
            foreach (long k2 in pmap.Keys) {
                if (pmap[k2] != p) continue;
                foreach (long f in factors) {
                    if(f%k2!=0) continue;
                    if (toAdd.ContainsKey(f)) toAdd[f] += dp[f / k2];
                    else toAdd[f] = dp[f / k2];
                }
            }
            foreach (long f in toAdd.Keys) {
                dp[f] += toAdd[f];
            }
        }

        //foreach (long key in factors) {
        //    Console.WriteLine(key + " " + dp[key]);
        //}

        Console.WriteLine(dp[N]);

    }
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int Gcd(int a, int b)
    {
        if (b == 0)
            return a;
        return Gcd(b, a % b);
    }

    private const int SIEVE_SIZE = 1000010;
    private readonly bool[] isComposite = new bool[SIEVE_SIZE + 1];
    private readonly IList<int> primes = new List<int>();
    void Sieve()
    {
        for (int i = 2; i * i <= SIEVE_SIZE; i++)
            if (!isComposite[i])
                for (int j = i * i; j <= SIEVE_SIZE; j += i)
                    isComposite[j] = true;
        for (int i = 2; i <= SIEVE_SIZE; i++)
            if (!isComposite[i])
                primes.Add(i);
    }

    public void Solve()
    {
        Sieve();

        long a = ReadLong();
        if (a == 1)
        {
            Write(1);
            return;
        }
        var d = new SDictionary<long, int> { { a, 1 } };
        int ans = 0;
        var ts = DateTime.Now;
        for (int i = 0; i < primes.Count; i++)
        {
            bool ok = false;
            for (long x = primes[i]; !ok && x < a; x *= primes[i])
                if (a % (x + 1) == 0)
                    ok = true;
            if (!ok)
                continue;

            var toAdd = new List<Tuple<long, int>>();
            var toRemove = new List<long>();
            foreach (var p in d)
            {
                if (p.Key <= primes[i])
                    toRemove.Add(p.Key);
                for (long x = primes[i]; x < p.Key; x *= primes[i])
                    if (p.Key % (x + 1) == 0)
                    {
                        long y = p.Key / (x + 1);
                        if (y == 1)
                            ans += p.Value;
                        else if (y > primes[i] && y % 2 == 0)
                            toAdd.Add(Tuple.Create(y, p.Value));
                    }
            }
            foreach (int x in toRemove)
                d.Remove(x);
            foreach (var p in toAdd)
                d[p.Item1] += p.Item2;
        }
        //Write((DateTime.Now - ts).TotalMilliseconds);

        foreach (var p in d)
            if (p.Key > SIEVE_SIZE)
            {
                long x = p.Key - 1;
                bool ok = true;
                for (int i = 0; ok && 1L * primes[i] * primes[i] <= x; i++)
                    if (x % primes[i] == 0)
                        ok = false;
                if (ok)
                    ans += p.Value;
            }

        Write(ans);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("hull.in");
        //writer = new StreamWriter("hull.out");
#endif
        try
        {
//            var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
//            thread.Start();
//            thread.Join();
            new Solver().Solve();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
#if DEBUG
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() {return reader.ReadLine().Split(new[] { ' ', '\t', '-' }, StringSplitOptions.RemoveEmptyEntries);}
    public static string ReadToken(){while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine());return currentLineTokens.Dequeue();}
    public static int ReadInt(){return int.Parse(ReadToken());}
    public static long ReadLong(){return long.Parse(ReadToken());}
    public static double ReadDouble(){return double.Parse(ReadToken(), CultureInfo.InvariantCulture);}
    public static int[] ReadIntArray(){return ReadAndSplitLine().Select(int.Parse).ToArray();}
    public static long[] ReadLongArray(){return ReadAndSplitLine().Select(long.Parse).ToArray();}
    public static double[] ReadDoubleArray(){return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();}
    public static int[][] ReadIntMatrix(int numberOfRows){int[][] matrix = new int[numberOfRows][];for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray();return matrix;}
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows){int[][] matrix = ReadIntMatrix(numberOfRows);int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++){ret[i] = new int[numberOfRows];for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i];}return ret;}
    public static string[] ReadLines(int quantity){string[] lines = new string[quantity];for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim();return lines;}
    public static void WriteArray<T>(IEnumerable<T> array){writer.WriteLine(string.Join(" ", array));}
    public static void Write(params object[] array){WriteArray(array);}
    public static void WriteLines<T>(IEnumerable<T> array){foreach (var a in array)writer.WriteLine(a);}
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>{public new TValue this[TKey key]{
        get { return ContainsKey(key) ? base[key] : default(TValue); }set { base[key] = value; }}}
    private static T[] Init<T>(int size) where T : new(){var ret = new T[size];for (int i = 0; i < size; i++)ret[i] = new T();return ret;}
    #endregion
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int Gcd(int a, int b)
    {
        if (b == 0)
            return a;
        return Gcd(b, a % b);
    }

    private const int SIEVE_SIZE = 1000010;
    private readonly bool[] isComposite = new bool[SIEVE_SIZE + 1];
    private readonly IList<int> primes = new List<int>();
    void Sieve()
    {
        for (int i = 2; i * i <= SIEVE_SIZE; i++)
            if (!isComposite[i])
                for (int j = i * i; j <= SIEVE_SIZE; j += i)
                    isComposite[j] = true;
        for (int i = 2; i <= SIEVE_SIZE; i++)
            if (!isComposite[i])
                primes.Add(i);
    }

    public void Solve()
    {
        Sieve();

        long a = ReadLong();
        var d = new SDictionary<long, int> { { a, 1 } };
        for (int i = 0; i < primes.Count; i++)
        {
            var nd = new SDictionary<long, int>();
            foreach (var p in d)
            {
                nd[p.Key] += p.Value;
                for (long x = primes[i]; x < p.Key; x *= primes[i])
                    if (p.Key % (x + 1) == 0)
                        nd[p.Key / (x + 1)] += p.Value;
            }
            d = nd;
        }

        long ans = d[1];
        foreach (var p in d)
            if (p.Key > SIEVE_SIZE)
            {
                long x = p.Key - 1;
                bool ok = true;
                for (int i = 0; ok && 1L * primes[i] * primes[i] <= x; i++)
                    if (x % primes[i] == 0)
                        ok = false;
                if (ok)
                    ans += p.Value;
            }

        Write(ans);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("hull.in");
        //writer = new StreamWriter("hull.out");
#endif
        try
        {
//            var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
//            thread.Start();
//            thread.Join();
            new Solver().Solve();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
#if DEBUG
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() {return reader.ReadLine().Split(new[] { ' ', '\t', '-' }, StringSplitOptions.RemoveEmptyEntries);}
    public static string ReadToken(){while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine());return currentLineTokens.Dequeue();}
    public static int ReadInt(){return int.Parse(ReadToken());}
    public static long ReadLong(){return long.Parse(ReadToken());}
    public static double ReadDouble(){return double.Parse(ReadToken(), CultureInfo.InvariantCulture);}
    public static int[] ReadIntArray(){return ReadAndSplitLine().Select(int.Parse).ToArray();}
    public static long[] ReadLongArray(){return ReadAndSplitLine().Select(long.Parse).ToArray();}
    public static double[] ReadDoubleArray(){return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();}
    public static int[][] ReadIntMatrix(int numberOfRows){int[][] matrix = new int[numberOfRows][];for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray();return matrix;}
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows){int[][] matrix = ReadIntMatrix(numberOfRows);int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++){ret[i] = new int[numberOfRows];for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i];}return ret;}
    public static string[] ReadLines(int quantity){string[] lines = new string[quantity];for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim();return lines;}
    public static void WriteArray<T>(IEnumerable<T> array){writer.WriteLine(string.Join(" ", array));}
    public static void Write(params object[] array){WriteArray(array);}
    public static void WriteLines<T>(IEnumerable<T> array){foreach (var a in array)writer.WriteLine(a);}
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>{public new TValue this[TKey key]{
        get { return ContainsKey(key) ? base[key] : default(TValue); }set { base[key] = value; }}}
    private static T[] Init<T>(int size) where T : new(){var ret = new T[size];for (int i = 0; i < size; i++)ret[i] = new T();return ret;}
    #endregion
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CFDIV125_2 {
	class Program {
		static void Main(string[] args) {

#if DEBUG
			TextReader reader = new StreamReader("../../input.txt");

#else
			TextReader reader = Console.In;
#endif

			#region INIT
			int[] c1 = reader.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();
			int[] c2 = reader.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();

			int x1 = c1[0];
			int y1 = c1[1];
			int r1 = c1[2];
			int R1 = c1[3];

			int x2 = c2[0];
			int y2 = c2[1];
			int r2 = c2[2];
			int R2 = c2[3];
			#endregion

			int count = 0;

			if (AreCircleWithBallOk(x1, y1, r1, x2, y2, r2, R2)) count++;
			if (AreCircleWithBallOk(x1, y1, R1, x2, y2, r2, R2)) count++;
			if (AreCircleWithBallOk(x2, y2, r2, x1, y1, r1, R1)) count++;
			if (AreCircleWithBallOk(x2, y2, R2, x1, y1, r1, R1)) count++;

			Console.WriteLine(count);

#if DEBUG
			Console.ReadKey();
#endif

		}

		static bool AreCircleWithBallOk(int x1, int y1, int rd1, int x2, int y2, int rd2, int Rd2) {
			return !(AreBallsIntercect(x1, y1, rd1, x2, y2, rd2) || AreBallsIntercect(x1, y1, rd1, x2, y2, Rd2));
		}

		static bool AreBallsIntercect(int x1, int y1, int rd1, int x2, int y2, int rd2) {

			double centersDist = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

			double l1 = -rd1;
			double r1 = rd1;

			double l2 = centersDist - rd2;
			double r2 = centersDist + rd2;

			if (r1 <= l2)  return false;
			if (l1 <= l2 && r1 >= r2) return false;
			if (l2 <= l1 && r2 >= r1) return false;

			return true;

		}

	}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CFDIV125_2 {
	class Program {
		static void Main(string[] args) {

#if DEBUG
			TextReader reader = new StreamReader("../../input.txt");

#else
			TextReader reader = Console.In;
#endif

			#region INIT
			int[] c1 = reader.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();
			int[] c2 = reader.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();

			int x1 = c1[0];
			int y1 = c1[1];
			int r1 = c1[2];
			int R1 = c1[3];

			int x2 = c2[0];
			int y2 = c2[1];
			int r2 = c2[2];
			int R2 = c2[3];
			#endregion

			int count = 0;

			if (AreCircleWithBallOk(x1, y1, r1, x2, y2, r2, R2)) count++;
			if (AreCircleWithBallOk(x1, y1, R1, x2, y2, r2, R2)) count++;
			if (AreCircleWithBallOk(x2, y2, r2, x1, y1, r1, R1)) count++;
			if (AreCircleWithBallOk(x2, y2, R2, x1, y1, r1, R1)) count++;

			Console.WriteLine(count);

#if DEBUG
			Console.ReadKey();
#endif

		}

		static bool AreCircleWithBallOk(int x1, int y1, int rd1, int x2, int y2, int rd2, int Rd2) {
			return !(AreBallsIntercect(x1, y1, rd1, x2, y2, rd2) || AreBallsIntercect(x1, y1, rd1, x2, y2, Rd2));
		}

		static bool AreBallsIntercect(int x1, int y1, int rd1, int x2, int y2, int rd2) {

			double centersDist = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

			double l1 = -rd1;
			double r1 = rd1;

			double l2 = centersDist - rd2;
			double r2 = centersDist + rd2;

			if (r1 < l2)  return false;
			if (l1 < l2 && r1 > r2) return false;
			if (l2 < l1 && r2 > r1) return false;

			return true;

		}

	}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CFDIV125_2 {
	class Program {
		static void Main(string[] args) {

#if DEBUG
			TextReader reader = new StreamReader("../../input.txt");

#else
			TextReader reader = Console.In;
#endif

			#region INIT
			int[] c1 = reader.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();
			int[] c2 = reader.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();

			int x1 = c1[0];
			int y1 = c1[1];
			int r1 = c1[2];
			int R1 = c1[3];

			int x2 = c2[0];
			int y2 = c2[1];
			int r2 = c2[2];
			int R2 = c2[3];
			#endregion

			int count = 0;

			if (AreCircleWithBallOk(x1, y1, r1, x2, y2, r2, R2)) count++;
			if (AreCircleWithBallOk(x1, y1, R1, x2, y2, r2, R2)) count++;
			if (AreCircleWithBallOk(x2, y2, r2, x1, y1, r1, R1)) count++;
			if (AreCircleWithBallOk(x2, y2, R2, x1, y1, r1, R1)) count++;

			Console.WriteLine(count);

#if DEBUG
			Console.ReadKey();
#endif

		}

		static bool AreCircleWithBallOk(int x1, int y1, int rd1, int x2, int y2, int rd2, int Rd2) {

			bool res1 = !(AreBallsIntercect(x1, y1, rd1, x2, y2, rd2) ||
						  AreBallsIntercect(x1, y1, rd1, x2, y2, Rd2));

			if (!res1) return false;

			double centersDist = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

			double t1 = centersDist + rd2;
			double t2 = rd1;
			double t3 = centersDist + Rd2;
			if (t1 < t2 && t2 < t3) return false;

			return true;

		}

		static bool AreBallsIntercect(int x1, int y1, int rd1, int x2, int y2, int rd2) {

			double centersDist = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

			double l1 = -rd1;
			double r1 = rd1;

			double l2 = centersDist - rd2;
			double r2 = centersDist + rd2;

			if (r1 <= l2)  return false;
			if (l1 <= l2 && r1 >= r2) return false;
			if (l2 <= l1 && r2 >= r1) return false;

			return true;

		}

	}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CFDIV125_2 {
	class Program {
		static void Main(string[] args) {

#if DEBUG
			TextReader reader = new StreamReader("../../input.txt");

#else
			TextReader reader = Console.In;
#endif

			#region INIT
			int[] c1 = reader.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();
			int[] c2 = reader.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();

			int x1 = c1[0];
			int y1 = c1[1];
			int r1 = c1[2];
			int R1 = c1[3];

			int x2 = c2[0];
			int y2 = c2[1];
			int r2 = c2[2];
			int R2 = c2[3];
			#endregion

			int count = 0;

			if (AreCircleWithBallOk(x1, y1, r1, x2, y2, r2, R2)) count++;
			if (AreCircleWithBallOk(x1, y1, R1, x2, y2, r2, R2)) count++;
			if (AreCircleWithBallOk(x2, y2, r2, x1, y1, r1, R1)) count++;
			if (AreCircleWithBallOk(x2, y2, R2, x1, y1, r1, R1)) count++;

			Console.WriteLine(count);

#if DEBUG
			Console.ReadKey();
#endif

		}

		static bool AreCircleWithBallOk(int x1, int y1, int rd1, int x2, int y2, int rd2, int Rd2) {

			bool res1 = !(AreBallsIntercect(x1, y1, rd1, x2, y2, rd2) ||
						  AreBallsIntercect(x1, y1, rd1, x2, y2, Rd2));

			if (!res1) return false;

			double centersDist = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

			double t1 = centersDist + rd2;
			double t2 = rd1;
			double t3 = centersDist + Rd2;
			if (t1 <= t2 && t2 < t3) return false;

			t1 = centersDist - Rd2;
			t2 = -rd1;
			t3 = centersDist - rd2;
			if (t1 <= t2 && t2 < t3) return false;

			return true;

		}

		static bool AreBallsIntercect(int x1, int y1, int rd1, int x2, int y2, int rd2) {

			double centersDist = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

			double l1 = -rd1;
			double r1 = rd1;

			double l2 = centersDist - rd2;
			double r2 = centersDist + rd2;

			if (r1 <= l2)  return false;
			if (l1 <= l2 && r1 >= r2) return false;
			if (l2 <= l1 && r2 >= r1) return false;

			return true;

		}

	}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//namespace Practice
//{
    class TaskF
    {
        public static void Main(string[] args)
        {
            new TaskF().solve();
        }
        const int P = 1000000007;
        public int pow(int a, int b)
        {
            if (b == 0) return 1;
            int res = pow(a, (b >> 1));
            res = (int)((1L * res * res) % P);
            if ((b & 1) == 1)
            {
                return (int)((1L * res * a) % P);
            }
            return res;
        }

        int comb(int n, int k, int[] fac, int[] finv)
        {
            if (k > n) return 0;
            if (k == 0 || k == n) return 1;
            return (int) (((1L * (1L * fac[n] * finv[k]) % P) * finv[n-k]) % P);
        }

        public void solve()
        {
            string[] inputs = Console.ReadLine().Split(' ');
            int f = int.Parse(inputs[0]);
            int w = int.Parse(inputs[1]);
            int h = int.Parse(inputs[2]);

            if (w == 0 || h == 0)
            {
                Console.WriteLine(1);
                return;
            }
            else if (f == 0)
            {
                if (w > h)
                {
                    Console.WriteLine(1);
                    return;
                }
                else
                {
                    Console.WriteLine(0);
                    return;
                }
            }
            if (w <= h && w > 0)
            {
                Console.WriteLine(0);
                return;
            }
            int n = Math.Max(f + 1, w - 1) + 1;
            int[] fac = new int[n];
            int[] finv = new int[n];
            fac[0] = finv[0] = 1;
            fac[1] = finv[1] = 1;
            for (int i = 2; i < n; i++)
            {
                fac[i] = (int)((1L * fac[i - 1] * i) % P);
                finv[i] = pow(fac[i], P - 2);
            }

            int all = 0, good = 0, f1 = f + 1, w1 = w - 1, upper = w / (h + 1);
            for (int u = 1; u <= w; u++)
            {
                if (u > f1) break;
                int f1u = comb(f1, u, fac, finv);
                all += mult(f1u, comb(w1, u - 1, fac, finv));
                all %= P;
                if (u <= upper)
                {
                    good += mult(f1u, comb(w - u * h - 1, u - 1, fac, finv));
                    good %= P;
                }
            }
            //Console.WriteLine(pow(all, P-2));
            int res = (int)(1L * good * pow(all, P - 2) % P);
            //Console.WriteLine(res + " = " + good +" / " + all);
            Console.WriteLine(res);

            //Console.Read();
        }
        public int mult(int a, int b)
        {
            return (int)((1L * a * b) % P);
        }
    }
//}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Practice
{
    class TaskF
    {
        //public static void Main(string[] args)
        //{
        //    new TaskF().solve();
        //}
        const int P = 1000000007;
        public int pow(int a, int b)
        {
            if (b == 0) return 1;
            int res = pow(a, (b >> 1));
            res = (int)(1L * res * res % P);
            if ((b & 1) == 1)
            {
                return (int)(1L * res * a % P);
            }
            return res;
        }

        int comb(int n, int k, int[] fac, int[] finv)
        {
            if (k == 0 || k == n) return 1;
            return (int) (((1L * fac[n] * finv[k] % P) * finv[n-k]) % P);
        }

        public void solve()
        {
            string[] inputs = Console.ReadLine().Split(' ');
            int f = int.Parse(inputs[0]);
            int w = int.Parse(inputs[1]);
            int h = int.Parse(inputs[2]);

            if (w == 0 || h == 0)
            {
                Console.WriteLine(1);
                return;
            }
            else if (f == 0)
            {
                if (w > h)
                {
                    Console.WriteLine(1);
                    return;
                }
                else
                {
                    Console.WriteLine(0);
                    return;
                }
            }
            if (w <= h && w > 0)
            {
                Console.WriteLine(0);
                return;
            }
            int n = Math.Max(f + 1, w - 1) + 1;
            int[] fac = new int[n];
            int[] finv = new int[n];
            fac[0] = finv[0] = 1;
            fac[1] = finv[1] = 1;
            for (int i = 2; i < n; i++)
            {
                fac[i] = (int)(1L * fac[i - 1] * i % P);
                finv[i] = pow(fac[i], P - 2);
            }

            int all = 0, good = 0, f1 = f + 1, w1 = w - 1, upper = w / (h + 1);
            for (int u = 1; u <= w; u++)
            {
                if (u > f1) break;
                int f1u = comb(f1, u, fac, finv);
                all += mult(f1u, comb(w1, u - 1, fac, finv));
                all %= P;
                if (u <= upper)
                {
                    good += mult(f1u, comb(w - u * h - 1, u - 1, fac, finv));
                }
            }
            Console.WriteLine(pow(all, P-2));
            int res = (int)(1L * good * pow(all, P - 2) % P);
            //Console.WriteLine(res + " = " + good +" / " + all);
            Console.WriteLine(res);

            //Console.Read();
        }
        public int mult(int a, int b)
        {
            return (int)(1L * a * b % P);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//namespace Practice
//{
    class TaskF
    {
        public static void Main(string[] args)
        {
            new TaskF().solve();
        }
        const int P = 1000000007;
        public int pow(int a, int b)
        {
            if (b == 0) return 1;
            int res = pow(a, (b >> 1));
            res = (int)(1L * res * res % P);
            if ((b & 1) == 1)
            {
                return (int)(1L * res * b % P);
            }
            return res;
        }

        int comb(int n, int k, int[] fac, int[] finv)
        {
            if (k == 0 || k == n) return 1;
            return (int) (((1L * fac[n] * finv[k] % P) * finv[n-k]) % P);
        }

        public void solve()
        {
            string[] inputs = Console.ReadLine().Split(' ');
            int f = int.Parse(inputs[0]);
            int w = int.Parse(inputs[1]);
            int h = int.Parse(inputs[2]);

            if (w == 0 || h == 0)
            {
                Console.WriteLine(1);
                return;
            }
            else if (f == 0)
            {
                if (w > h)
                {
                    Console.WriteLine(1);
                    return;
                }
                else
                {
                    Console.WriteLine(0);
                    return;
                }
            }
            if (w <= h && w > 0)
            {
                Console.WriteLine(0);
                return;
            }
            int n = Math.Max(f + 1, w - 1) + 1;
            int[] fac = new int[n];
            int[] finv = new int[n];
            fac[0] = finv[0] = 1;
            fac[1] = finv[1] = 1;
            for (int i = 2; i < n; i++)
            {
                fac[i] = (int)(1L * fac[i - 1] * i % P);
                finv[i] = pow(fac[i], P - 2);
            }

            int all = 0, good = 0, f1 = f + 1, w1 = w - 1, upper = w / (h + 1);
            for (int u = 1; u <= w; u++)
            {
                if (u > f1) break;
                int f1u = comb(f1, u, fac, finv);
                all += mult(f1u, comb(w1, u - 1, fac, finv));
                all %= P;
                if (u <= upper)
                {
                    good += mult(f1u, comb(w - u * h - 1, u - 1, fac, finv));
                }
            }
            int res = (int)(1L * good * pow(all, P - 2) % P);
            Console.WriteLine(res + " = " + good +" / " + all);
            Console.Read();
        }
        public int mult(int a, int b)
        {
            return (int)(1L * a * b % P);
        }
    }
//}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//namespace Practice
//{
    class TaskF
    {
        public static void Main(string[] args)
        {
            new TaskF().solve();
        }
        const int P = 1000000007;
        public int pow(int a, int b)
        {
            if (b == 0) return 1;
            int res = pow(a, (b >> 1));
            res = (int)((1L * res * res) % P);
            if ((b & 1) == 1)
            {
                return (int)((1L * res * a) % P);
            }
            return res;
        }

        int comb(int n, int k, int[] fac, int[] finv)
        {
            if (k > n) return 0;
            if (k == 0 || k == n) return 1;
            return (int) ((((1L * fac[n] * finv[k]) % P) * finv[n-k]) % P);
        }

        public void solve()
        {
            string[] inputs = Console.ReadLine().Split(' ');
            int f = int.Parse(inputs[0]);
            int w = int.Parse(inputs[1]);
            int h = int.Parse(inputs[2]);

            if (w == 0 || h == 0)
            {
                Console.WriteLine(1);
                return;
            }
            else if (f == 0)
            {
                if (w > h)
                {
                    Console.WriteLine(1);
                    return;
                }
                else
                {
                    Console.WriteLine(0);
                    return;
                }
            }
            if (w <= h && w > 0)
            {
                Console.WriteLine(0);
                return;
            }
            int n = Math.Max(f + 1, w - 1) + 1;
            int[] fac = new int[n];
            int[] finv = new int[n];
            fac[0] = finv[0] = 1;
            fac[1] = finv[1] = 1;
            for (int i = 2; i < n; i++)
            {
                fac[i] = (int)((1L * fac[i - 1] * i) % P);
                finv[i] = pow(fac[i], P - 2);
            }

            int all = 0, good = 0, f1 = f + 1, w1 = w - 1, upper = w / (h + 1);
            for (int u = 1; u <= w; u++)
            {
                if (u > f1) break;
                int f1u = comb(f1, u, fac, finv);
                all += mult(f1u, comb(w1, u - 1, fac, finv));
                all %= P;
                if (u <= upper)
                {
                    good += mult(f1u, comb(w - u * h - 1, u - 1, fac, finv));
                }
            }
            //Console.WriteLine(pow(all, P-2));
            int res = (int)(1L * good * pow(all, P - 2) % P);
            //Console.WriteLine(res + " = " + good +" / " + all);
            Console.WriteLine(res);

            //Console.Read();
        }
        public int mult(int a, int b)
        {
            return (int)((1L * a * b) % P);
        }
    }
//}


using System;
using CompLib.Mathematics;
using CompLib.Util;

public class Program
{
    private int N;
    private string S;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        S = sc.Next();

        int counter = 0;
        int min = 0;
        foreach (char c in S)
        {
            if (c == '(') counter++;
            else counter--;
            min = Math.Min(min, counter);
        }

        int t = 2 * N - S.Length;

        var dp = new ModInt[t + 1, t + 1];
        dp[0, 0] = 1;
        for (int i = 0; i < t; i++)
        {
            for (int j = 0; j <= t; j++)
            {
                if (j + 1 <= t) dp[i + 1, j + 1] += dp[i, j];
                if (0 <= j - 1) dp[i + 1, j - 1] += dp[i, j];
            }
        }

        ModInt ans = 0;
        for (int i = 0; i <= t; i++)
        {
            int j = t - i;
            for (int k = -min; k <= t; k++)
            {
                int l = counter + k;
                if (0 <= l && l <= t)
                {
                    // Console.WriteLine($"{i} {j} {k} {l} {dp[i, k]} {dp[j, l]}");
                    ans += dp[i, k] * dp[j, l];
                }
            }
        }

        Console.WriteLine(ans);
    }

    public static void Main(string[] args) => new Program().Solve();
}

// https://bitbucket.org/camypaper/complib
namespace CompLib.Mathematics
{
    #region ModInt

    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int) 1e9 + 7;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;

        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n)
        {
            num = n;
        }

        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString()
        {
            return num.ToString();
        }

        public static ModInt operator +(ModInt l, ModInt r)
        {
            l.num += r.num;
            if (l.num >= Mod) l.num -= Mod;
            return l;
        }

        public static ModInt operator -(ModInt l, ModInt r)
        {
            l.num -= r.num;
            if (l.num < 0) l.num += Mod;
            return l;
        }

        public static ModInt operator *(ModInt l, ModInt r)
        {
            return new ModInt(l.num * r.num % Mod);
        }

        public static implicit operator ModInt(long n)
        {
            n %= Mod;
            if (n < 0) n += Mod;
            return new ModInt(n);
        }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k)
        {
            return Pow(v.num, k);
        }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1)
                    ret = ret * v % Mod;
            return new ModInt(ret);
        }

        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v)
        {
            return Pow(v, Mod - 2);
        }
    }

    #endregion

    #region Binomial Coefficient

    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;

        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }

        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }

        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }

    #endregion
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


using System;
using System.Linq;
using CompLib.Util;
using System.Threading;
using CompLib.Mathematics;

public class Program
{
    int N;
    string S;
    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        S = sc.Next();

        int cnt = 0;
        int min = 0;
        foreach (var c in S)
        {
            if (c == '(') cnt++;
            else cnt--;
            min = Math.Min(min, cnt);
        }
        /*
         * Sを部分文字列に含むカッコ列の個数
         */

        // i文字目まで作る、カウンタ、Sより前、Sより後
        var dp = new ModInt[2 * N + 1, N + 1, 2];
        dp[0, 0, 0] = 1;
        for (int i = 0; i < 2 * N; i++)
        {
            for (int j = 0; j <= N; j++)
            {
                // (
                if (j + 1 <= N)
                {
                    dp[i + 1, j + 1, 0] += dp[i, j, 0];
                    dp[i + 1, j + 1, 1] += dp[i, j, 1];
                }

                // )
                if (j - 1 >= 0)
                {
                    dp[i + 1, j - 1, 0] += dp[i, j, 0];
                    dp[i + 1, j - 1, 1] += dp[i, j, 1];
                }

                if (i + S.Length <= 2 * N && j + min >= 0 && j + cnt <= N)
                {
                    dp[i + S.Length, j + cnt, 1] += dp[i, j, 0];
                }
            }
        }

        Console.WriteLine(dp[2 * N, 0, 1]);
    }

    public static void Main(string[] args) => new Program().Solve();
    // public static void Main(string[] args) => new Thread(new Program().Solve, 1 << 27).Start();
}

// https://bitbucket.org/camypaper/complib
namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int)1e9 + 7;
        // public const long Mod = 998244353;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s;
                do
                {
                    s = Console.ReadLine();
                } while (s.Length == 0);

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public string ReadLine()
        {
            _index = _line.Length;
            return Console.ReadLine();
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


using System;
using System.Linq;
using CompLib.Mathematics;
using CompLib.Util;

public class Program
{
    int N;
    string S;
    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        S = sc.Next();
        int l = S.Length;

        int cnt = 0;
        int min = 0;
        for (int i = 0; i < l; i++)
        {
            if (S[i] == '(') cnt++;
            else cnt--;
            min = Math.Min(min, cnt);
        }

        // i番目まで入れた
        // カウンタ
        // Sを入れた数
        var dp = new ModInt[2 * N + 1, 201, 201];
        dp[0, 0, 0] = 1;
        for (int i = 0; i < 2 * N; i++)
        {
            for (int j = 0; j <= 200; j++)
            {
                for (int k = 0; k <= 200; k++)
                {
                    // (を追加
                    if (j + 1 <= 200) dp[i + 1, j + 1, k] += dp[i, j, k];
                    // )
                    if (j - 1 >= 0) dp[i + 1, j - 1, k] += dp[i, j, k];
                    // s
                    if (i + l <= 2 * N && j + min >= 0 && j + cnt <= 200 && k + 1 <= 200) dp[i + l, j + cnt, k + 1] += dp[i, j, k];
                }
            }
        }
        ModInt ans = 0;
        for(int i = 1;i <= 200; i++)
        {
            if (i % 2 == 0) ans -= dp[2 * N, 0, i];
            else ans += dp[2 * N, 0, i];
        }
        Console.WriteLine(ans);
    }

    public static void Main(string[] args) => new Program().Solve();
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}

// https://bitbucket.org/camypaper/complib
namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int)1e9 + 7;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}


using System;
using System.Linq;
using CompLib.Mathematics;
using CompLib.Util;

public class Program
{
    int N;
    string S;
    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        S = sc.Next();

        int[] table;
        {
            table = new int[S.Length];
            table[0] = 0;
            int j = 0;
            for (int i = 1; i < S.Length; i++)
            {
                if (S[i] == S[j])
                {
                    table[i] = j++;
                }
                else
                {
                    table[i] = j;
                    j = 0;
                }
            }
        }

        // i文字目まで構成、カウンタ、Sの何文字目までできた
        var dp = new ModInt[2 * N + 1, N + 1, S.Length + 1];
        dp[0, 0, 0] = 1;
        for (int i = 0; i < 2 * N; i++)
        {
            for (int j = 0; j <= N; j++)
            {
                for (int k = 0; k < S.Length; k++)
                {
                    // (
                    if (j + 1 <= N)
                    {
                        int p = k;
                        while (p != 0 && S[p] != '(') p = table[p];
                        if (S[p] != '(') dp[i + 1, j + 1, 0] += dp[i, j, k];
                        else dp[i + 1, j + 1, p + 1] += dp[i, j, k];
                    }
                    if (j - 1 >= 0)
                    {
                        int p = k;
                        while (p != 0 && S[p] != ')') p = table[p];
                        if (S[p] != ')') dp[i + 1, j - 1, 0] += dp[i, j, k];
                        else dp[i + 1, j - 1, p + 1] += dp[i, j, k];
                    }
                }
                if (j + 1 <= N) dp[i + 1, j + 1, S.Length] += dp[i, j, S.Length];
                if (j - 1 >= 0) dp[i + 1, j - 1, S.Length] += dp[i, j, S.Length];
            }
        }
        Console.WriteLine(dp[2 * N, 0, S.Length]);
    }

    public static void Main(string[] args) => new Program().Solve();
}

// https://bitbucket.org/camypaper/complib
namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int)1e9 + 7;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


using System;
using System.Linq;
using CompLib.Mathematics;
using CompLib.Util;

public class Program
{
    int N;
    string S;
    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        S = sc.Next();

        int[] table;
        {
            table = new int[S.Length + 1];
            table[0] = 0;
            int j = 0;
            for (int i = 1; i < S.Length; i++)
            {
                if (S[i] == S[j])
                {
                    table[i] = j++;
                }
                else
                {
                    table[i] = j;
                    j = 0;
                }
            }
            table[S.Length] = j;
        }

        // i文字目まで構成、カウンタ、Sの何文字目までできた、一度でもSを構成できたか?
        var dp = new ModInt[2 * N + 1, N + 1, S.Length, 2];
        dp[0, 0, 0, 0] = 1;
        for (int i = 0; i < 2 * N; i++)
        {
            for (int j = 0; j <= N; j++)
            {
                for (int k = 0; k < S.Length; k++)
                {
                    // (
                    if (j + 1 <= N)
                    {
                        int p = k;
                        while (p != 0 && (p >= S.Length || S[p] != '(')) p = table[p];
                        if (S[p] != '(')
                        {
                            dp[i + 1, j + 1, 0, 1] += dp[i, j, k, 1];
                            dp[i + 1, j + 1, 0, 0] += dp[i, j, k, 0];
                        }
                        else
                        {
                            dp[i + 1, j + 1, (p + 1) % S.Length, 1] += dp[i, j, k, 1];
                            dp[i + 1, j + 1, (p + 1) % S.Length, (p + 1 == S.Length ? 1 : 0)] += dp[i, j, k, 0];
                        }
                    }
                    if (j - 1 >= 0)
                    {
                        int p = k;
                        while (p != 0 && (p >= S.Length || S[p] != ')')) p = table[p];
                        if (S[p] != ')')
                        {
                            dp[i + 1, j - 1, 0, 1] += dp[i, j, k, 1];
                            dp[i + 1, j - 1, 0, 0] += dp[i, j, k, 0];
                        }
                        else
                        {
                            dp[i + 1, j - 1, (p + 1) % S.Length, 1] += dp[i, j, k, 1];
                            dp[i + 1, j - 1, (p + 1) % S.Length, (p + 1 == S.Length ? 1 : 0)] += dp[i, j, k, 0];
                        }
                    }
                }
            }
        }

        ModInt ans = 0;
        for (int i = 0; i < S.Length; i++)
        {
            ans += dp[2 * N, 0, i, 1];
        }
        Console.WriteLine(ans);
    }

    public static void Main(string[] args) => new Program().Solve();
}

// https://bitbucket.org/camypaper/complib
namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int)1e9 + 7;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace CF954G
{
    class Program
    {
		public class Global
		{
			public static int[,] len;
			public static int[,,,] Dp;
		}

		static void Main(string[] args)
        {
			const int mod = 1000000007;

			int len = Convert.ToInt32(Console.ReadLine());
			string s = Console.ReadLine(), t = "";

			Global.len = new int[s.Length + 1, 2];
			Global.Dp = new int[(len << 1) + 5, (len << 1) + 5, s.Length + 5, 2];
			Global.Dp[0, 0, 0, 0] = 1;

			if(s[0] == '(') Global.len[0, 0] = 1;
			else Global.len[0, 1] = 1;
			for(int i = 0; i < s.Length; i++) {
				t += s[i];t += '(';
				Global.len[i + 1, 0] = Match(s, t);
				t = t.Remove(t.Length - 1, 1); t += ')';
				Global.len[i + 1, 1] = Match(s, t);
				t = t.Remove(t.Length - 1, 1);
			}

			for(int i = 0; i < (len << 1); i++)
				for(int j = 0; j <= len; j++)
					for(int k = 0; k <= s.Length; k++)
						for(int fin = 0; fin <= 1; fin++) {
							if(Global.Dp[i, j, k, fin] == 0) continue;
							if(j < len) {
								Global.Dp[i + 1, j + 1, Global.len[k, 0], fin | (Global.len[k, 0] == s.Length ? 1 : 0)] += Global.Dp[i, j, k, fin];
								Global.Dp[i + 1, j + 1, Global.len[k, 0], fin | (Global.len[k, 0] == s.Length ? 1 : 0)] %= mod;
							}
							if(j > 0) {
								Global.Dp[i + 1, j - 1, Global.len[k, 1], fin | (Global.len[k, 1] == s.Length ? 1 : 0)] += Global.Dp[i, j, k, fin];
								Global.Dp[i + 1, j - 1, Global.len[k, 1], fin | (Global.len[k, 1] == s.Length ? 1 : 0)] %= mod;
							}
						}

			int _count = 0, final_Len = len << 1;
			for(int i = 0; i <= s.Length; i++) {
				_count += Global.Dp[final_Len, 0, i, 1];
				_count %= mod;
			}

			Console.WriteLine(_count.ToString());
		}

		static int Match(string a,string t) {
			for(int i = Math.Min(t.Length, a.Length); i > 0; i--)
				if(a.Substring(0, i) == t.Substring(t.Length - i, i))
					return i;
			return 0;
		}
	}
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
//using System.Numerics;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    long Fun(int a, int b, int c, int v)
    {
        if (b + c > a)
            return 0;
        v = Math.Min(a - b - c, v);
        return 1L * (v + 2) * (v + 1) / 2;
    }

    void Solve()
    {
        int a = ReadInt();
        int b = ReadInt();
        int c = ReadInt();
        int n = ReadInt();

        long ans = 0;
        for (int i = 0; i <= n; i++)
        {
            ans += 1L * (i + 1) * (i + 2) / 2;
            ans -= Fun(a + i, b, c, n - i);
            ans -= Fun(b + i, a, c, n - i);
            ans -= Fun(c + i, a, b, n - i);
        }

        Write(ans);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("transform.in");
        //writer = new StreamWriter("transform.out");
#endif
        try
        {
            //            var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
            //            thread.Start();
            //            thread.Join();
            new Solver().Solve();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
#if DEBUG
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
    #endregion
}


using System;
using System.Linq;
using System.Diagnostics;
using System.Collections.Generic;
using Debug = System.Diagnostics.Debug;
using StringBuilder = System.Text.StringBuilder;
using System.Numerics;

namespace Program
{

    public class Solver
    {
        public void Solve()
        {
            var table = new CombinationTable(300050);
            var a = sc.Integer();
            var b = sc.Integer();
            var c = sc.Integer();
            var l = sc.Integer();
            long all = 0;
            for (int i = 0; i <= l; i++)
            {
                all += table[i + 2, 2];
                Debug.WriteLine(all);
            }
            var abc = new int[] { a, b, c };
            var sum = a + b + c;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j <= l; j++)
                {
                    var max = abc[i] + j;
                    var rem = Math.Min(l - j, max - sum + abc[i]);
                    if (rem < 0) continue;
                    all -= table[rem + 2, 2];
                }
            }
            IO.Printer.Out.WriteLine(all);
        }
        public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());
        static T[] Enumerate<T>(int n, Func<int, T> f) { var a = new T[n]; for (int i = 0; i < n; ++i) a[i] = f(i); return a; }
        static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
    }
}

#region main
static class Ex
{
    static public string AsString(this IEnumerable<char> ie) { return new string(System.Linq.Enumerable.ToArray(ie)); }
    static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") { return string.Join(st, ie); }
    static public void Main()
    {
        var solver = new Program.Solver();
        solver.Solve();
        Program.IO.Printer.Out.Flush();
    }
}
#endregion
#region Ex
namespace Program.IO
{
    using System.IO;
    using System.Text;
    using System.Globalization;
    public class Printer : StreamWriter
    {
        static Printer() { Out = new Printer(Console.OpenStandardOutput()) { AutoFlush = false }; }
        public static Printer Out { get; set; }
        public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
        public Printer(System.IO.Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
        public Printer(System.IO.Stream stream, Encoding encoding) : base(stream, encoding) { }
        public void Write<T>(string format, T[] source) { base.Write(format, source.OfType<object>().ToArray()); }
        public void WriteLine<T>(string format, T[] source) { base.WriteLine(format, source.OfType<object>().ToArray()); }
    }
    public class StreamScanner
    {
        public StreamScanner(Stream stream) { str = stream; }
        public readonly Stream str;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        public bool isEof = false;
        public bool IsEndOfStream { get { return isEof; } }
        private byte read()
        {
            if (isEof) return 0;
            if (ptr >= len) { ptr = 0; if ((len = str.Read(buf, 0, 1024)) <= 0) { isEof = true; return 0; } }
            return buf[ptr++];
        }
        public char Char() { byte b = 0; do b = read(); while ((b < 33 || 126 < b) && !isEof); return (char)b; }

        public string Scan()
        {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read())
                sb.Append(b);
            return sb.ToString();
        }
        public string ScanLine()
        {
            var sb = new StringBuilder();
            for (var b = Char(); b != '\n'; b = (char)read())
                if (b == 0) break;
                else if (b != '\r') sb.Append(b);
            return sb.ToString();
        }
        public long Long()
        {
            if (isEof) return long.MinValue;
            long ret = 0; byte b = 0; var ng = false;
            do b = read();
            while (b != '-' && (b < '0' || '9' < b));
            if (b == '-') { ng = true; b = read(); }
            for (; true; b = read())
            {
                if (b < '0' || '9' < b)
                    return ng ? -ret : ret;
                else ret = ret * 10 + b - '0';
            }
        }
        public int Integer() { return (isEof) ? int.MinValue : (int)Long(); }
        public double Double() { return double.Parse(Scan(), CultureInfo.InvariantCulture); }
        private T[] enumerate<T>(int n, Func<T> f)
        {
            var a = new T[n];
            for (int i = 0; i < n; ++i) a[i] = f();
            return a;
        }

        public char[] Char(int n) { return enumerate(n, Char); }
        public string[] Scan(int n) { return enumerate(n, Scan); }
        public double[] Double(int n) { return enumerate(n, Double); }
        public int[] Integer(int n) { return enumerate(n, Integer); }
        public long[] Long(int n) { return enumerate(n, Long); }
    }
}
#endregion

#region CombinationTable
public class CombinationTable
{
    long[][] nCr;
    public CombinationTable(int n)
    {
        nCr = new long[n + 1][];
        for (int i = 0; i <= n; i++)
            nCr[i] = new long[4];
        nCr[0][0] = 1;
        for (int i = 0; i <= n; i++)
        {
            nCr[i][0] = 1;
            for (int j = 1; j < Math.Min(i + 1, 4); j++)
                nCr[i][j] = (nCr[i - 1][j - 1] + nCr[i - 1][j]);// % mod;
        }
    }
    public long this[int n, int r]
    {
        get
        {
            if (n < 0 || n > nCr.Length)
                return 0;
            if (r < 0 || r > n)
                return 0;
            return nCr[n][r];
        }
    }
    public long RepeatedCombination(int n, int k)
    {
        if (k == 0) return 1;
        return this[n + k - 1, k];
    }
}
#endregion


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;

namespace C.Lengthening_Sticks
{
	class TextReaderHelper
	{
		protected TextReader baseReader;
		protected LinkedList<string> buffer;

		public TextReaderHelper(TextReader baseReader)
		{
			this.baseReader = baseReader;
			buffer = new LinkedList<string>();
		}

		protected void readIfEmpty()
		{
			if (buffer.Count > 0) return;
			string line;
			do
			{
				line = baseReader.ReadLine();
				if (line == null) return;
			}
			while (line.Trim() == string.Empty);
			foreach (var item in line.Split(' ', '\n', '\t'))
				if (item != string.Empty)
					buffer.AddLast(item);
		}

		private object readChar()
		{
			var node = buffer.First;
			var ret = node.Value[0];
			if (node.Value.Length > 1) node.Value = node.Value.Substring(1);
			else buffer.RemoveFirst();
			return ret;
		}

		public T NextElement<T>()
		{
			readIfEmpty();
			if (typeof(T) == typeof(char)) return (T)readChar();
			var ret = (T)Convert.ChangeType(buffer.First.Value, typeof(T));
			buffer.RemoveFirst();
			return ret;
		}

		public int NextInt() { return NextElement<int>(); }

		public string NextString() { return NextElement<string>(); }
	}

	class Program
	{
		[Conditional("DEBUG")]
		static void Pause()
		{
			Console.ReadKey();
		}

		static long Calc(int a, int b, int c, int l)
		{
			if (a < b + c) return 0;
			l = Math.Min(a - b - c, l);
			return (long)(l + 1) * (l + 2) / 2;
		}

		static void Main(string[] args)
		{
			var reader = new TextReaderHelper(new StreamReader(Console.OpenStandardInput(), Encoding.ASCII, false, 1048576));
			var writer = new StreamWriter(Console.OpenStandardOutput(), Encoding.ASCII, 1048576);
			int a = reader.NextInt(), b = reader.NextInt(), c = reader.NextInt(), l = reader.NextInt();
			long ans = (long)(l + 1) * (l + 2) * (l + 3) / 6;
			for (int i = 0; i <= l; i++)
			{
				ans -= Calc(a + i, b, c, l - i);
				ans -= Calc(b + i, a, c, l - i);
				ans -= Calc(c + i, a, b, l - i);
			}
			writer.WriteLine(ans);
			writer.Flush();
			Pause();
        }
	}
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
//using System.Numerics;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    long Sum(int from, int to)
    {
        int len = to - from + 1;
        return 1L * from * len + 1L * len * (len - 1) / 2;
    }

    long Fun(int height, int width, int start, int cut)
    {
        long ret = 0;
        if (start - height + 1 <= cut)
            ret += Sum(1, Math.Min(height - 1, cut - start + height));
        if (start <= cut)
            ret += 1L * height * (Math.Min(width, cut - start) + 1);
        if (start + width + 1 <= cut)
            ret += Sum(Math.Max(1, start + width + height - cut), height - 1);
        return ret;
    }

    void Solve()
    {
        int a = ReadInt();
        int b = ReadInt();
        int c = ReadInt();
        int v = ReadInt();
        int s = a + b + c;
        long ans = 0;
        for (int i = 0; i <= v; i++, s++)
        {
            int s2 = (s - 1) / 2;
            int ca = s2 - a;
            int cb = s2 - b;
            int cc = s2 - c;
            if (ca < 0 || cb < 0 || cc < 0)
                continue;
            int min = Math.Min(cb, cc);
            int max = Math.Max(cb, cc);
            ans += Fun(min + 1, max - min, i - cb - cc + min, ca) - Fun(min + 1, max - min, i - cb - cc + min, -1);
        }

        Write(ans);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("transform.in");
        //writer = new StreamWriter("transform.out");
#endif
        try
        {
            //            var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
            //            thread.Start();
            //            thread.Join();
            new Solver().Solve();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
#if DEBUG
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
    #endregion
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;

namespace Console
{
    class Program
    {
        static void Main(string[] args)
        {
            var arr = new List<long>(System.Console.ReadLine().Split(' ').Select(long.Parse));
            var a = arr[0];
            var b = arr[1];
            var c = arr[2];
            var l = arr[3];

            long ans = (l + 1)*(l + 2)*(l + 3)/6;
            for (int i = 0; i <= l; ++i)
            {
                ans -= Fun(a + i, b, c, l - i);
                ans -= Fun(b + i, a, c, l - i);
                ans -= Fun(c + i, b, a, l - i);
            }
            System.Console.Write(ans);
            //System.Console.ReadLine();
        }

        static long Fun(long a, long b, long c, long x)
        {
            if (a < b + c)
                return 0;
            var min = Math.Min(a - b - c, x);
            return (min + 1)*(min + 2)/2;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;

namespace Console
{
    class Program
    {
        static void Main(string[] args)
        {
            var arr = new List<int>(System.Console.ReadLine().Split(' ').Select(int.Parse));
            var a = arr[0];
            var b = arr[1];
            var c = arr[2];
            var l = arr[3];

            var ans = (l + 1)*(l + 2)*(l + 3)/6;
            for (int i = 0; i <= l; ++i)
            {
                ans -= Fun(a + i, b, c, l - i);
                ans -= Fun(b + i, a, c, l - i);
                ans -= Fun(c + i, b, a, l - i);
            }
            System.Console.Write(ans);
            //System.Console.ReadLine();
        }

        static int Fun(int a, int b, int c, int x)
        {
            if (a < b + c)
                return 0;
            var min = Math.Min(a - b - c, x);
            return (min + 1)*(min + 2)/2;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ForAll
{
    class Program
    {

        static void Main(string[] args)
        {
            Int64[] parametrs = Array.ConvertAll(Console.ReadLine().Split(' '),Int64.Parse);

            Int64 n = parametrs[0], l = parametrs[1],r = parametrs[2];

            Int64 lengthString = (Int64)Math.Pow(2, ((Int64)Math.Log(n, 2)) + 1) - 1;

            int counter = 0;
            for (Int64 i = l; i < r + 1; i++)
            {
                if (BinarySearch(lengthString, n, i) == 1)
                    counter++;
            }

            Console.WriteLine(counter);
        }

        static int BinarySearch(Int64 lengthValue,Int64 root,Int64 index)
        {
            Int64 current = lengthValue / 2 + 1;
            Int64 path = current;
            while (current != index)
            {
                path = path >> 1;
                if (index < current)
                    current = current - path;
                else
                    current = current + path;
                root = root >> 1;
            }

            if (index % 2 == 0)
                return (int)(root % 2);
            else return (int)(root);
        }

    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace Codeforces
{
	internal class Template
	{
		private Dictionary<Tuple<long, long, long>, long> dp;

		private void Solve()
		{
			dp = new Dictionary<Tuple<long, long, long>, long>();

			var n = cin.NextLong();
			var l = cin.NextLong();
			var r = cin.NextLong();

			if (n == 0)
			{
				Console.WriteLine(0);
				return;
			}

			var count = Count(n, l, r);
			Console.WriteLine(count);
		}

		private long Count(long n, long l, long r)
		{
			if (n == 1)
			{
				return 1;
			}

			if (dp.ContainsKey(Tuple.Create(n, l, r)))
			{
				return dp[Tuple.Create(n, l, r)];
			}

			var idx = 0;
			var nn = n;
			while (nn > 1)
			{
				idx++;
				nn/=2;
			}
			var len = 1;
			for (var i = 0; i < idx; i++)
			{
				len *= 2;
				len++;
			}
			var middle = len/2;
			var sum = 0L;
			if (l <= middle && r >= middle)
			{
				sum += n%2;
				if (l < middle)
				{
					sum += Count(n/2, l, middle - 1);
				}
				if (r > middle)
				{
					sum += Count(n/2, 0, r - middle - 1);
				}
			}
			else if (l < middle)
			{
				sum += Count(n/2, l, r);
			}
			else
			{
				sum += Count(n/2, l - middle - 1, r - middle - 1);
			}
			dp[Tuple.Create(n, l, r)] = sum;
			return sum;
		}

		private static readonly Scanner cin = new Scanner();

		private static void Main()
		{
#if DEBUG
			var inputText = File.ReadAllText(@"..\..\input.txt");
			var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
			var consoleOut = Console.Out;
			for (var i = 0; i < testCases.Length; i++)
			{
				var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
				Console.SetIn(new StringReader(parts[0].Trim()));
				var stringWriter = new StringWriter();
				Console.SetOut(stringWriter);
				var sw = Stopwatch.StartNew();
				new Template().Solve();
				sw.Stop();
				var output = stringWriter.ToString();

				Console.SetOut(consoleOut);
				var color = ConsoleColor.Green;
				var status = "Passed";
				if (parts[1].Trim() != output.Trim())
				{
					color = ConsoleColor.Red;
					status = "Failed";
				}
				Console.ForegroundColor = color;
				Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
			}
			Console.ReadLine();
			Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
		}
	}

	internal class Scanner
	{
		private string[] s = new string[0];
		private int i;
		private readonly char[] cs = { ' ' };

		public string NextString()
		{
			if (i < s.Length) return s[i++];
			var line = Console.ReadLine() ?? string.Empty;
			s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			i = 1;
			return s.First();
		}

		public double NextDouble()
		{
			return double.Parse(NextString());
		}

		public int NextInt()
		{
			return int.Parse(NextString());
		}

		public long NextLong()
		{
			return long.Parse(NextString());
		}
	}
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace Codeforces
{
	internal class Template
	{
		private Dictionary<Tuple<long, long, long>, long> dp;

		private void Solve()
		{
			dp = new Dictionary<Tuple<long, long, long>, long>();

			var n = cin.NextLong();
			var l = cin.NextLong();
			var r = cin.NextLong();

			if (n == 0)
			{
				Console.WriteLine(0);
				return;
			}

			var count = Count(n, l-1, r-1);
			Console.WriteLine(count);
		}

		private long Count(long n, long l, long r)
		{
			if (n == 1)
			{
				return 1;
			}

			if (dp.ContainsKey(Tuple.Create(n, l, r)))
			{
				return dp[Tuple.Create(n, l, r)];
			}

			var idx = 0;
			var nn = n;
			while (nn > 1)
			{
				idx++;
				nn/=2;
			}
			var len = 1;
			for (var i = 0; i < idx; i++)
			{
				len *= 2;
				len++;
			}
			var middle = len/2;
			var sum = 0L;
			if (l <= middle && r >= middle)
			{
				sum += n%2;
				if (l < middle)
				{
					sum += Count(n/2, l, middle - 1);
				}
				if (r > middle)
				{
					sum += Count(n/2, 0, r - middle - 1);
				}
			}
			else if (l < middle)
			{
				sum += Count(n/2, l, r);
			}
			else
			{
				sum += Count(n/2, l - middle - 1, r - middle - 1);
			}
			dp[Tuple.Create(n, l, r)] = sum;
			return sum;
		}

		private static readonly Scanner cin = new Scanner();

		private static void Main()
		{
#if DEBUG
			var inputText = File.ReadAllText(@"..\..\input.txt");
			var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
			var consoleOut = Console.Out;
			for (var i = 0; i < testCases.Length; i++)
			{
				var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
				Console.SetIn(new StringReader(parts[0].Trim()));
				var stringWriter = new StringWriter();
				Console.SetOut(stringWriter);
				var sw = Stopwatch.StartNew();
				new Template().Solve();
				sw.Stop();
				var output = stringWriter.ToString();

				Console.SetOut(consoleOut);
				var color = ConsoleColor.Green;
				var status = "Passed";
				if (parts[1].Trim() != output.Trim())
				{
					color = ConsoleColor.Red;
					status = "Failed";
				}
				Console.ForegroundColor = color;
				Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
			}
			Console.ReadLine();
			Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
		}
	}

	internal class Scanner
	{
		private string[] s = new string[0];
		private int i;
		private readonly char[] cs = { ' ' };

		public string NextString()
		{
			if (i < s.Length) return s[i++];
			var line = Console.ReadLine() ?? string.Empty;
			s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			i = 1;
			return s.First();
		}

		public double NextDouble()
		{
			return double.Parse(NextString());
		}

		public int NextInt()
		{
			return int.Parse(NextString());
		}

		public long NextLong()
		{
			return long.Parse(NextString());
		}
	}
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;

namespace CF317
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var sr = new InputReader(Console.In);
            //var sr = new InputReader(new StreamReader("input.txt"));
            var task = new Task();
            using (var sw = Console.Out)
            //using (var sw = new StreamWriter("output.txt"))
            {
                task.Solve(sr, sw);
                //Console.ReadKey();
            }
        }
    }

    internal class Task
    {
        private long l;
        private long r;
        private int answ;

        public void Solve(InputReader sr, TextWriter sw)
        {
            var input = sr.ReadArray(Int64.Parse);
            var n = input[0];
            l = input[1];
            r = input[2];
            Divide(n, 1L);
            sw.WriteLine(answ);
        }

        private void Divide(long n, long indx)
        {
            if (indx > r) {
                return;
            }
            if (n == 0 || n == 1) {
                if (indx >= l && indx <= r && n == 1L) {
                    answ++;
                }
                return;
            }
            var log = (long)Math.Floor(Math.Log(n, 2)) + 1L;
            var power = (long) Math.Pow(2, log) / 2 - 1L;
            if (indx + power*2 < l) {
                return;
            }
            Divide(n / 2, indx);
            if (indx + power >= l && indx + power <= r && n % 2 == 1L)
            {
                answ++;
            }
            Divide(n / 2, indx + power + 1L);
        }
    }
}

internal class InputReader : IDisposable
{
    private bool isDispose;
    private readonly TextReader sr;

    public InputReader(TextReader stream)
    {
        sr = stream;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public string NextString()
    {
        var result = sr.ReadLine();
        return result;
    }

    public int NextInt32()
    {
        return Int32.Parse(NextString());
    }

    public long NextInt64()
    {
        return Int64.Parse(NextString());
    }

    public string[] NextSplitStrings()
    {
        return NextString()
            .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public T[] ReadArray<T>(Func<string, CultureInfo, T> func)
    {
        return NextSplitStrings()
            .Select(s => func(s, CultureInfo.InvariantCulture))
            .ToArray();
    }

    public T[] ReadArrayFromString<T>(Func<string, CultureInfo, T> func, string str)
    {
        return
            str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(s => func(s, CultureInfo.InvariantCulture))
                .ToArray();
    }

    protected void Dispose(bool dispose)
    {
        if (!isDispose)
        {
            if (dispose)
                sr.Close();
            isDispose = true;
        }
    }

    ~InputReader()
    {
        Dispose(false);
    }
}