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

namespace Codeforces
{
    class E
    {
        private static ThreadStart  s_threadStart = new E().Go;

        class Point
        {
            public int X, Y;
            public bool Keep;
        }

        long[] F;

        private void Go()
        {
            long mod = 1000000007;

            int n = GetInt();
            Point[] points = new Point[n];
            for (int i = 0; i < n; i++)
            {
                points[i] = new Point() { X = GetInt(), Y = GetInt() };
            }

            F = new long[2*n + 1];
            F[0] = 1;
            for (int i = 1; i <= 2 * n; i++)
                F[i] = (F[i - 1] * i) % mod;

            Dictionary<int, List<int>> xDict = new Dictionary<int, List<int>>();
            Dictionary<int, List<int>> yDict = new Dictionary<int, List<int>>();
            for(int i = 0; i < n; i++)
            {
                List<int> list;
                if (!xDict.TryGetValue(points[i].X, out list))
                    list = xDict[points[i].X] = new List<int>();

                list.Add(i);

                if (!yDict.TryGetValue(points[i].Y, out list))
                    list = yDict[points[i].Y] = new List<int>();

                list.Add(i);
            }

            long ans = 1;

            Queue<int> queue = new Queue<int>();
            while (xDict.Count > 0)
            {
                int k = 0;
                int m = 0;
                var pair = xDict.First();
                queue.Enqueue(pair.Value[0]);

                HashSet<int> xDir = new HashSet<int>();
                HashSet<int> yDir = new HashSet<int>();
                HashSet<int> pSet = new HashSet<int>();

                while (queue.Count > 0)
                {
                    int pp = queue.Dequeue();
                    Point point = points[pp];
                    pSet.Add(pp);
                    xDir.Add(point.X);
                    yDir.Add(point.Y);
                    if (xDict.ContainsKey(point.X))
                    {
                        foreach (int z in xDict[point.X])
                            if (z != pp)
                                queue.Enqueue(z);
                    }
                    if (yDict.ContainsKey(point.Y))
                    {
                        foreach (int z in yDict[point.Y])
                            if (z != pp)
                                queue.Enqueue(z);
                    }
                    xDict.Remove(point.X);
                    yDict.Remove(point.Y);
                }

                ans *= Bin(xDir.Count() + yDir.Count(), pSet.Count(), mod);
                ans %= mod;
            }

            Wl(ans);
        }

        long Bin(long n, long k, long mod)
        {
            if (n < k)
                k = n;

            long ans = 0;
            for (int i = 0; i <= k; i++)
            {
                long add = F[n];
                add *= Inv(F[i], mod);
                add %= mod;
                add *= Inv(F[n - i], mod);
                add %= mod;
                ans += add;
                ans %= mod;
            }
            return ans;
        }

        public static long Pow(long a, long n, long mod)
        {
            long res = 1L;
            while (n > 0)
            {
                if ((n & 1) != 0)
                    res = (res * a) % mod;
                a = (a * a) % mod;
                n >>= 1;
            }
            return res;
        }

        public static long Inv(long a, long mod)
        {
            return Pow(a, mod - 2, mod);
        }

        #region Template

        private static StringBuilder output = new StringBuilder();

        public static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            output.Length = 0;
            Thread main = new Thread(new ThreadStart(s_threadStart), 512 * 1024 * 1024);
            timer.Start();
            main.Start();
            main.Join();
            Console.Write(output);
            timer.Stop();
            Console.Error.WriteLine(timer.ElapsedMilliseconds);
        }

        private static IEnumerator<string> ioEnum;
        private static string GetString()
        {
            do
            {
                while (ioEnum == null || !ioEnum.MoveNext())
                {
                    ioEnum = Console.ReadLine().Split().AsEnumerable().GetEnumerator();
                }
            } while (string.IsNullOrEmpty(ioEnum.Current));

            return ioEnum.Current;
        }

        private static int GetInt()
        {
            return int.Parse(GetString());
        }

        private static long GetLong()
        {
            return long.Parse(GetString());
        }

        private static double GetDouble()
        {
            return double.Parse(GetString());
        }

        private static List<int> GetIntArr(int n)
        {
            List<int> ret = new List<int>(n);
            for (int i = 0; i < n; i++)
            {
                ret.Add(GetInt());
            }
            return ret;
        }

        private static void Wl<T>(T o)
        {
            W(o);
            output.Append(Console.Out.NewLine);
        }

        private static void Wl<T>(IEnumerable<T> enumerable)
        {
            W(enumerable);
            output.Append(Console.Out.NewLine);
        }

        private static void W<T>(T o)
        {
            if (o is double)
            {
                Wd((o as double?).Value, "");
            }
            else if (o is float)
            {
                Wd((o as float?).Value, "");
            }
            else
                output.Append(o.ToString());
        }

        private static void W<T>(IEnumerable<T> enumerable)
        {
            W(string.Join(" ", enumerable.Select(e => e.ToString()).ToArray()));
        }

        private static void Wd(double d, string format)
        {
            W(d.ToString(format, CultureInfo.InvariantCulture));
        }

        #endregion
    }
}


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

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int[] KMP(string s)
    {
        int n = s.Length;
        var pi = new int[n];
	    for (int i = 1; i < n; ++i)
        {
		    int j = pi[i - 1];
		    while (j > 0 && s[i] != s[j])
			    j = pi[j - 1];
		    if (s[i] == s[j])
                j++;
		    pi[i] = j;
	    }
	    return pi;
    }

    public object Solve()
    {
        string s1 = ReadToken();
        string s2 = ReadToken();
        string s3 = ReadToken();

        int n1 = s1.Length;
        int n2 = s2.Length;
        int n3 = s3.Length;

        var dp = new int[n1 + 1, n2 + 1, n3];
        var path = new Tuple<int, int, int, char>[n1 + 1, n2 + 1, n3];
        for (int i1 = 1; i1 <= n1; i1++)
            for (int i2 = 1; i2 <= n2; i2++)
                for (int i3 = 0; i3 < n3; i3++)
                {
                    if (s1[i1 - 1] == s2[i2 - 1])
                    {
                        if (s3[i3] == s1[i1 - 1])
                        {
                            if (i3 + 1 < n3)
                            {
                                dp[i1, i2, i3 + 1] = dp[i1 - 1, i2 - 1, i3] + 1;
                                path[i1, i2, i3 + 1] = Tuple.Create(i1 - 1, i2 - 1, i3, s1[i1 - 1]);
                            }
                        }
                        else
                        {
                            int jump = KMP(s3.Substring(0, i3) + s1[i1 - 1])[i3];
                            if (dp[i1 - 1, i2 - 1, i3] + 1 > dp[i1, i2, jump])
                            {
                                dp[i1, i2, jump] = dp[i1 - 1, i2 - 1, i3] + 1;
                                path[i1, i2, jump] = Tuple.Create(i1 - 1, i2 - 1, i3, s1[i1 - 1]);
                            }
                        }
                    }
                    if (dp[i1 - 1, i2, i3] >= dp[i1, i2, i3])
                    {
                        dp[i1, i2, i3] = dp[i1 - 1, i2, i3];
                        path[i1, i2, i3] = Tuple.Create(i1 - 1, i2, i3, (char)0);
                    }
                    if (dp[i1, i2 - 1, i3] >= dp[i1, i2, i3])
                    {
                        dp[i1, i2, i3] = dp[i1, i2 - 1, i3];
                        path[i1, i2, i3] = Tuple.Create(i1, i2 - 1, i3, (char)0);
                    }
                }

        int max = -1;
        int nmax = -1;
        for (int i = 0; i < n3; i++)
        {
            if (dp[n1, n2, i] > max)
            {
                max = dp[n1, n2, i];
                nmax = i;
            }
        }
        if (max == 0)
            return 0;

        var list = new List<char>();
        var c = Tuple.Create(n1, n2, nmax, (char)0);
        while (c.Item1 > 0 && c.Item2 > 0)
        {
            c = path[c.Item1, c.Item2, c.Item3];
            if (c.Item4 > 0)
                list.Add(c.Item4);
        }
        list.Reverse();

//        for (int i = 0; i < n3; i++)
//        {
//            for (int j = 0; j <= n1; j++)
//            {
//                for (int k = 0; k <= n2; k++)
//                {
//                    Console.Write(dp[j, k, i]);
//                }
//                Console.WriteLine();
//            }
//            Console.WriteLine("-----------");
//        }

        return new string(list.ToArray());
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
#endif
        try
        {
            var ts = DateTime.Now;
            object result = new Solver().Solve();
            if (result != null)
                writer.WriteLine(result);
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#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));
    }

    #endregion
}


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

class Program
{
    public class Point
    {
        public int X, Y;
    }

    public interface IRequestor
    {
        int Req(int x, int y);
    }

    public class OnlineRequestor : IRequestor
    {
        public int Req(int x, int y)
        {
            Console.WriteLine("0 " + x + " " + y);
            return int.Parse(Console.ReadLine());
        }
    }

    public class OfflineRequestor : IRequestor
    {
        private int[] xx, yy;
        public OfflineRequestor(int[] x, int[] y)
        {
            xx = x;
            yy = y;
        }

        public int Req(int x, int y)
        {
            int ans = int.MaxValue;

            for (int i = 0; i < xx.Length; i++)
                ans = Math.Min(ans, Math.Abs(xx[i] - x));

            for (int i = 0; i < yy.Length; i++)
                ans = Math.Min(ans, Math.Abs(yy[i] - y));

            return ans;
        }
    }

    private static IRequestor requestor;
    private static bool reverse = false;
    private static int Req(int x, int y)
    {
        if (!reverse)
            return requestor.Req(x, y);

        return requestor.Req(y, x);
    }

    private static List<int> answer;
    private static void Search(int l, int r)
    {
        if (r < l) return;

        int mid = (l + r) / 2;
        var d = Req(mid, randomY);

        if (d == 0)
        {
            answer.Add(mid);
            Search(l, mid - 1);
            Search(mid + 1, r);
        }
        else
        {
            Search(l, mid - d);
            Search(mid + d, r);
        }
    }

    private static Random rnd = new Random();
    private static int randomY;
    private static List<int> Solve(bool rev)
    {
        reverse = rev;
        answer = new List<int>();

        randomY = rev ? rY : rX;
        Search(-100000000, 100000000);

        return answer;
    }

    private static int rX, rY;
    private static void SearchRandom()
    {
        while (Req(rX, rY) < 100)
        {
            rX = rnd.Next(-100000000, 100000001);
            rY = rnd.Next(-100000000, 100000001);
        }
    }

    private static void Main(string[] args)
    {
        //requestor = new OfflineRequestor(new int[] { 1, 100 }, new int[] { 20, 50 });
        requestor = new OnlineRequestor();

        SearchRandom();
        var x = Solve(false);
        var y = Solve(true);

        Console.WriteLine("1 " + x.Count + " " + y.Count);
        Console.WriteLine(string.Join(" ", x));
        Console.WriteLine(string.Join(" ", y));
    }

    private const int Mod = 1000000000 + 7;

    #region Data Read
    private static char ReadSign()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (ans == '+' || ans == '-' || ans == '?')
                return (char)ans;
        }
    }

    private static long GCD(long a, long b)
    {
        if (a % b == 0) return b;
        return GCD(b, a % b);
    }

    private static List<int>[] ReadGraph(int n, int m)
    {
        List<int>[] g = new List<int>[n];
        for (int i = 0; i < g.Length; i++) g[i] = new List<int>();
        for (int i = 0; i < m; i++)
        {
            int a = RI() - 1;
            int b = RI() - 1;

            g[a].Add(b);
            g[b].Add(a);
        }

        return g;
    }

    private static int[,] ReadGraphAsMatrix(int n, int m)
    {
        int[,] matrix = new int[n + 1, n + 1];
        for (int i = 0; i < m; i++)
        {
            int a = RI();
            int b = RI();
            matrix[a, b] = matrix[b, a] = 1;
        }

        return matrix;
    }

    private static void Sort(ref int a, ref int b)
    {
        if (a > b) Swap(ref a, ref b);
    }

    private static void Swap(ref int a, ref int b)
    {
        int tmp = a;
        a = b;
        b = tmp;
    }

    private const int BufferSize = 1 << 16;
    private static StreamReader consoleReader;
    private static MemoryStream testData;

    private static int RI()
    {
        int ans = 0;
        int mul = 1;
        do
        {
            ans = consoleReader.Read();
            if (ans == -1)
                return 0;
            if (ans == '-') mul = -1;
        } while (ans < '0' || ans > '9');

        ans -= '0';
        while (true)
        {
            int chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans * mul;
            ans = ans * 10 + chr - '0';
        }
    }

    private static ulong RUL()
    {
        ulong ans = 0;
        int chr;
        do
        {
            chr = consoleReader.Read();
            if (chr == -1)
                return 0;
        } while (chr < '0' || chr > '9');

        ans = (uint)(chr - '0');
        while (true)
        {
            chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans;
            ans = ans * 10 + (uint)(chr - '0');
        }
    }

    private static long RL()
    {
        long ans = 0;
        int mul = 1;
        do
        {
            ans = consoleReader.Read();
            if (ans == -1)
                return 0;
            if (ans == '-') mul = -1;
        } while (ans < '0' || ans > '9');

        ans -= '0';
        while (true)
        {
            int chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans * mul;
            ans = ans * 10 + chr - '0';
        }
    }

    private static int[] RIA(int n)
    {
        int[] ans = new int[n];
        for (int i = 0; i < n; i++)
            ans[i] = RI();
        return ans;
    }

    private static long[] RLA(int n)
    {
        long[] ans = new long[n];
        for (int i = 0; i < n; i++)
            ans[i] = RL();
        return ans;
    }

    private static char[] ReadWord()
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')));

        List<char> s = new List<char>();
        do
        {
            s.Add((char)ans);
            ans = consoleReader.Read();
        } while ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'));

        return s.ToArray();
    }

    private static char[] ReadString(int n)
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')));

        char[] s = new char[n];
        int pos = 0;
        do
        {
            s[pos++] = (char)ans;
            if (pos == n) break;
            ans = consoleReader.Read();
        } while ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'));

        return s;
    }

    private static char[] ReadStringLine()
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (ans == 10 || ans == 13);

        List<char> s = new List<char>();

        do
        {
            s.Add((char)ans);
            ans = consoleReader.Read();
        } while (ans != 10 && ans != 13 && ans != -1);

        return s.ToArray();
    }

    private static char ReadLetter()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'))
                return (char)ans;
        }
    }
    private static char ReadNonLetter()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')))
                return (char)ans;
        }
    }

    private static char ReadAnyOf(IEnumerable<char> allowed)
    {
        while (true)
        {
            char ans = (char)consoleReader.Read();
            if (allowed.Contains(ans))
                return ans;
        }
    }

    private static char ReadDigit()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (ans >= '0' && ans <= '9')
                return (char)ans;
        }
    }

    private static int ReadDigitInt()
    {
        return ReadDigit() - (int)'0';
    }

    private static char ReadAnyChar()
    {
        return (char)consoleReader.Read();
    }

    private static string DoubleToString(double x)
    {
        return x.ToString(CultureInfo.InvariantCulture);
    }

    private static double DoubleFromString(string x)
    {
        return double.Parse(x, CultureInfo.InvariantCulture);
    }

    static Program()
    {
        //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        consoleReader = new StreamReader(Console.OpenStandardInput(BufferSize), Encoding.ASCII, false, BufferSize);
    }

    private static void PushTestData(StringBuilder sb)
    {
        PushTestData(sb.ToString());
    }
    private static void PushTestData(string data)
    {
#if TOLYAN_TEST
        if (testData == null)
        {
            testData = new MemoryStream();
            consoleReader = new StreamReader(testData);
        }

        var pos = testData.Position;
        var bytes = Encoding.UTF8.GetBytes(data);
        testData.Write(bytes, 0, bytes.Length);
        testData.Flush();
        testData.Position = pos;
#endif
    }
    #endregion
}


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

namespace CodeForcesTest.Round278
{
    class CandyBoxes
    {
        public static void Main(string[] args)
        {
            Run();
            //Console.ReadLine();
        }

        static void Run()
        {
            string input = Console.ReadLine();
            int n = Convert.ToInt32(input);
            List<int> list = new List<int>();
            for (int i = 0; i < n; ++i)
            {
                input = Console.ReadLine();
                list.Add(Convert.ToInt32(input));
            }
            list = list.OrderBy(x => x).ToList();

            if (n == 4)
            {
                if (list[0]*3 == list[3] && list[0]*4 == list[1] + list[2])
                    Console.WriteLine("YES");
                else
                    Console.WriteLine("NO");
            }
            else if (n == 3)
            {
                if (list[0]*3 < list[2])
                {
                    Console.WriteLine("NO");
                }
                else
                {
                    if (list[0]*4 == list[1]+list[2])
                    {
                        Console.WriteLine("YES");
                        Console.WriteLine(list[0] * 3);
                    }
                    else if (list[2]%3 == 0
                        && list[2]/3*4 == list[0]+list[1])
                    {
                        Console.WriteLine("YES");
                        Console.WriteLine(list[2]/3);
                    }
                    else if (list[0] * 3 == list[2])
                    {
                        Console.WriteLine("YES");
                        Console.WriteLine(list[0]+list[2]-list[1]);
                    }
                    else
                    {
                        Console.WriteLine("NO");
                    }
                }
            }
            else if (n == 2)
            {
                if (list[0] * 3 < list[1])
                {
                    Console.WriteLine("NO");
                }
                else
                {
                    Console.WriteLine("YES");
                    Console.WriteLine(list[0] * 4 - list[1]);
                    Console.WriteLine(list[0] * 3);
                }
            }
            else if (n == 1)
            {
                Console.WriteLine("YES");
                Console.WriteLine(list[0]);
                Console.WriteLine(list[0] * 2);
                Console.WriteLine(list[0] * 2);
                Console.WriteLine(list[0] * 3);
            }
            else
            {
                Console.WriteLine("YES");
                Console.WriteLine(1);
                Console.WriteLine(2);
                Console.WriteLine(2);
                Console.WriteLine(3);
            }
        }

    }
}


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

namespace CodeForces
{
	class E
	{
		private static int[] ans =
			{
				1,
				2,
				4,
				6,
				12,
				16,
				18,
				30,
				60,
				88,
				106,
				126,
				520,
				606,
				1278,
				2202,
				2280,
				3216,
				4252,
				4422,
				9688,
				9940,
				11212,
				19936,
				21700,
				23208,
				44496,
				86242,
				110502,
				132048,
				216090,
				756838,
				859432,
				1257786,
				1398268,
				2976220,
				3021376,
				6972592,
				13466916,
				20996010
			};

		private const int MOD = 1000000007;
		private void Solve()
		{
			int n = NextInt();
			Out.WriteLine( ( pow( 2, ans[n - 1] ) - 1 + MOD ) % MOD );
			/*
			int MAX = 100000000;
			bool[] ok = new bool[MAX + 1];
			for ( int k = 1; ; ++k )
			{
				int f = 2 * k + 1 + k;
				if ( f > MAX ) break;
				while ( f <= MAX )
				{
					ok[f] = true;
					f += 2 * k + 1;
				}
			}

			for ( int k = 0; ; ++k )
			{
				int f = 2 * k + 2 + k;
				if ( f > MAX ) break;
				while ( f <= MAX )
				{
					ok[f] = true;
					f += 2 * k + 2;
				}
			}

			for ( int i = 1; i <= MAX; ++i )
				if ( !ok[i] ) Out.WriteLine( i );
			 */
		}

		private int pow( int a, int b )
		{
			if ( b == 0 ) return 1;
			int tmp = pow( a, b / 2 );
			tmp = (int)( ( (long)tmp * tmp ) % MOD );
			if ( b % 2 == 1 )
			{
				tmp = (int)( ( (long)tmp * a ) % MOD );
			}
			return tmp;
		}

		#region Local wireup

		public int NextInt()
		{
			return _in.NextInt();
		}

		public long NextLong()
		{
			return _in.NextLong();
		}

		public string NextLine()
		{
			return _in.NextLine();
		}

		public double NextDouble()
		{
			return _in.NextDouble();
		}

		readonly Scanner _in = new Scanner();
		static readonly TextWriter Out = Console.Out;

		void Start()
		{
#if !ONLINE_JUDGE
			var timer = new Stopwatch();
			timer.Start();
#endif
			var t = new Thread( Solve, 128 * 1024 * 1024 );
			t.Start();
			t.Join();
#if !ONLINE_JUDGE
			timer.Stop();
			Console.WriteLine( string.Format( CultureInfo.InvariantCulture, "Done in {0} seconds.\nPress <Enter> to exit.", timer.ElapsedMilliseconds / 1000.0 ) );
			Console.ReadLine();
#endif
		}

		static void Main()
		{
			new E().Start();
		}

		class Scanner : IDisposable
		{
			#region Fields

			readonly TextReader _reader;
			readonly int _bufferSize;
			readonly bool _closeReader;
			readonly char[] _buffer;
			int _length, _pos;

			#endregion

			#region .ctors

			public Scanner( TextReader reader, int bufferSize, bool closeReader )
			{
				_reader = reader;
				_bufferSize = bufferSize;
				_closeReader = closeReader;
				_buffer = new char[_bufferSize];
				FillBuffer( false );
			}

			public Scanner( TextReader reader, bool closeReader ) : this( reader, 1 << 16, closeReader ) { }

			public Scanner( string fileName ) : this( new StreamReader( fileName, Encoding.Default ), true ) { }

#if ONLINE_JUDGE
			public Scanner() : this( Console.In, false ) { }
#else
			public Scanner() : this( "input.txt" ) { }
#endif

			#endregion

			#region IDisposable Members

			public void Dispose()
			{
				if ( _closeReader )
				{
					_reader.Close();
				}
			}

			#endregion

			#region Properties

			public bool Eof
			{
				get
				{
					if ( _pos < _length ) return false;
					FillBuffer( false );
					return _pos >= _length;
				}
			}

			#endregion

			#region Methods

			private char NextChar()
			{
				if ( _pos < _length ) return _buffer[_pos++];
				FillBuffer( true );
				return _buffer[_pos++];
			}

			private char PeekNextChar()
			{
				if ( _pos < _length ) return _buffer[_pos];
				FillBuffer( true );
				return _buffer[_pos];
			}

			private void FillBuffer( bool throwOnEof )
			{
				_length = _reader.Read( _buffer, 0, _bufferSize );
				if ( throwOnEof && Eof )
				{
					throw new IOException( "Can't read beyond the end of file" );
				}
				_pos = 0;
			}

			public int NextInt()
			{
				var neg = false;
				int res = 0;
				SkipWhitespaces();
				if ( !Eof && PeekNextChar() == '-' )
				{
					neg = true;
					_pos++;
				}
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					var c = NextChar();
					if ( c < '0' || c > '9' ) throw new ArgumentException( "Illegal character" );
					res = 10 * res + c - '0';
				}
				return neg ? -res : res;
			}

			public long NextLong()
			{
				var neg = false;
				long res = 0;
				SkipWhitespaces();
				if ( !Eof && PeekNextChar() == '-' )
				{
					neg = true;
					_pos++;
				}
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					var c = NextChar();
					if ( c < '0' || c > '9' ) throw new ArgumentException( "Illegal character" );
					res = 10 * res + c - '0';
				}
				return neg ? -res : res;
			}

			public string NextLine()
			{
				SkipUntilNextLine();
				if ( Eof ) return "";
				var builder = new StringBuilder();
				while ( !Eof && !IsEndOfLine( PeekNextChar() ) )
				{
					builder.Append( NextChar() );
				}
				return builder.ToString();
			}

			public double NextDouble()
			{
				SkipWhitespaces();
				var builder = new StringBuilder();
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					builder.Append( NextChar() );
				}
				return double.Parse( builder.ToString(), CultureInfo.InvariantCulture );
			}

			private void SkipWhitespaces()
			{
				while ( !Eof && IsWhitespace( PeekNextChar() ) )
				{
					++_pos;
				}
			}

			private void SkipUntilNextLine()
			{
				while ( !Eof && IsEndOfLine( PeekNextChar() ) )
				{
					++_pos;
				}
			}

			private static bool IsWhitespace( char c )
			{
				return c == ' ' || c == '\t' || c == '\n' || c == '\r';
			}

			private static bool IsEndOfLine( char c )
			{
				return c == '\n' || c == '\r';
			}

			#endregion
		}

		#endregion
	}
}


using System;
using System.Collections.Generic;
using System.Linq;

namespace olymp_codeforces
{
    class Program
    {
        void dashla(long x, out HashSet<long> digits, out int cnt)
        {
            digits = new HashSet<long>();
            cnt = 0;
            while(x > 0)
            {
                digits.Add(x % 10);
                cnt++;
                x = x/10;
            }
        }
        int res = int.MaxValue;
        Dictionary<long, int> svlebi = new Dictionary<long, int>();
        void rec(long x, int n, int svla)
        {
            if (svlebi.ContainsKey(x) && svlebi[x] <= svla)
                return;
            svlebi[x] = svla;
            HashSet<long> digits;
            int cnt;
            dashla(x, out digits, out cnt);
            if(cnt == n)
            {
                res = Math.Min(res, svla);
                return;
            }
            if (svla >= res || svla > n+ 2)
                return;

            var dSorted = digits.ToList().OrderByDescending(i => i).ToList(); //   digits.OrderBy(_ => rand.Next()).ToList();
            //dSorted.Sort();
            for (int i = 0; i < dSorted.Count; i++)
            {
                long digit = dSorted[i];
                if (digit < 2)
                    break;
                rec(x * digit, n, svla + 1);
            }
        }

        public  void Solve()
        {
            // var t = int.Parse(Console.ReadLine());
            var input = Console.ReadLine().Split(' ').Select(long.Parse).ToList();
            long n = input[0], x = input[1];
            rec(x, (int)n, 0);
            if (res < int.MaxValue)
                Console.WriteLine(res);
            else
                Console.WriteLine(-1);
        }

        static void Main(string[] args)
        {
            var A = new Program();
            A.Solve();
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace Compete2
{
    partial class MainClass
    {
        public static void Main(string[] args)
        {
            int count = 1; //int.Parse(Console.ReadLine());
            List<string> output = new List<string>();

            for (int z = 0; z < count; z++)
            {
                //Console.ReadLine();
                //var s = Console.ReadLine();
                //var n = int.Parse(Console.ReadLine());
                var a = Console.ReadLine().Split(' ').Select(qw => ulong.Parse(qw)).ToList();
                //var b = Console.ReadLine().Split(' ').Select(qw => long.Parse(qw)).ToList();
                //var c = Console.ReadLine().Split(' ').Select(qw => long.Parse(qw)).ToList();
                //var b = long.Parse(Console.ReadLin    e());

                ulong o = ulong.MaxValue;
                //bool can = true;

                Queue<ulong[]> q = new Queue<ulong[]>();

                if ((ulong)a[1].ToString().Length >= a[0])
                    o = 0;
                else
                    q.Enqueue(new ulong[] { a[1], 0 });

                while (q.Count>0)
                {
                    var x = q.Dequeue();

                    if (x[1] + 1 >= o)
                        continue;

                    var ds = x[0].ToString().Distinct().Select(i=>int.Parse(i.ToString())).ToList();

                    if (ds.Contains(1))
                        ds.Remove(1);

                    if (ds.Contains(0))
                        ds.Remove(0);

                    BigInteger bi = x[0];

                    for (int i = 0; i < ds.Count; i++)
                    {
                        BigInteger bi2 = bi * ds[i];

                        if ((ulong)bi2.ToString().Length >= a[0])
                        {
                            if (x[1] + 1 < o)
                                o = x[1] + 1;
                        }
                        else
                        {
                            q.Enqueue(new ulong[] {(ulong)bi2,x[1]+1 });
                        }
                    }
                }

                if (o == ulong.MaxValue)
                    output.Add("-1");
                else
                output.Add(o.ToString());
                //output.Add(string.Join(" ", o));
                /*if (can)
                    output.Add("Yes");
                else
                    output.Add("No");*/
            }

            output.ForEach(d => Console.WriteLine(d));
        }
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using CompLib.Util;

public class Program
{
    private int N;
    private List<(int to, int num)>[] E;
    private int[] U, V;
    private int Max;

    private int R;
    private bool[] IsX;
    private bool Found;
    private int XSize;

    private int[] Len;
    private int[] Dist;
    private int TmpX;
    private int TmpY;

    void Scan()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        E = new List<(int to, int num)>[N];
        U = new int[N - 1];
        V = new int[N - 1];
        for (int i = 0; i < N; i++)
        {
            E[i] = new List<(int to, int num)>();
        }

        for (int i = 0; i < N - 1; i++)
        {
            int u = sc.NextInt() - 1;
            int v = sc.NextInt() - 1;
            U[i] = u + 1;
            V[i] = v + 1;
            E[u].Add((v, i));
            E[v].Add((u, i));
        }

        Max = 2 * N * N / 9;
    }

    void SetFlag(int cur, int par)
    {
        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            SetFlag(e.to, cur);
        }

        IsX[cur] = true;
    }

    int Go(int cur, int par)
    {
        var ls = new List<(int to, int size)>();
        int size = 1;
        foreach (var e in E[cur])
        {
            if (e.to == par) continue;
            int tmp = Go(e.to, cur);
            ls.Add((e.to, tmp));
            size += tmp;
        }

        // if (par != -1)
        // {
        //     ls.Add((par, N - size));
        // }

        // 親側は処理が難しいので飛ばす
        // x,y逆になってもいいので問題ない
        bool[,] dp = new bool[ls.Count + 1, N];
        dp[0, 0] = true;
        for (int i = 0; i < ls.Count; i++)
        {
            for (int j = 0; j < N; j++)
            {
                if (dp[i, j]) dp[i + 1, j + ls[i].size] = true;
            }
        }

        if (!Found)
        {
            int x = -1;
            for (int i = 0; i < N; i++)
            {
                if (!dp[ls.Count, i]) continue;
                int y = N - 1 - i;
                if (Max < (i + 1) * (y + 1))
                {
                    x = i;
                    break;
                }
            }

            if (x != -1)
            {
                XSize = x;
                R = cur;
                for (int i = ls.Count - 1; i >= 0; i--)
                {
                    if (x - ls[i].size >= 0 && dp[i, x - ls[i].size])
                    {
                        SetFlag(ls[i].to, cur);
                        x -= ls[i].size;
                    }
                }

                Found = true;
            }
        }

        return size;
    }

    // r、x,yの頂点を決める
    void SearchR()
    {
        IsX = new bool[N];
        Found = false;
        Go(0, -1);
    }

    // 現在地、親、par-curが辺num
    void SetX(int cur, int par, int num)
    {
        Dist[cur] = TmpX++;
        if (par != -1)
        {
            Len[num] = Dist[cur] - Dist[par];
        }

        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            if (!IsX[e.to]) continue;
            SetX(e.to, cur, e.num);
        }
    }

    void SetY(int cur, int par, int num)
    {
        Dist[cur] = TmpY;
        TmpY += (XSize + 1);
        if (par != -1)
        {
            Len[num] = Dist[cur] - Dist[par];
        }

        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            if (IsX[e.to]) continue;
            SetY(e.to, cur, e.num);
        }
    }

    void SetLen()
    {
        // 辺の長さ
        Len = new int[N - 1];
        // R->頂点までの距離
        Dist = new int[N];
        // X側の頂点はRに近い順に距離1~Xを割り当てる
        // それぞれの頂点までの距離になるように頂点の長さを割り当てる
        TmpX = 0;
        SetX(R, -1, -1);

        // Y (X+1)刻みで割り当てる
        TmpY = 0;
        SetY(R, -1, -1);
    }

    void Write()
    {
        var sb = new StringBuilder();
        for (int i = 0; i < N - 1; i++)
        {
            sb.AppendLine($"{U[i]} {V[i]} {Len[i]}");
        }

        Console.Write(sb);
    }

    public void Solve()
    {
        // ある頂点rを境目に2つに分ける
        // 片方x個 もう片方 y個 x + y + 1 = N
        // 片方でrからの距離 0~xをつくる
        // 残り x+1刻みで y個
        // 0 <= p < (x+1)(y+1)できる

        Scan();
        SearchR();
        SetLen();
        Write();
    }

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

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 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.Collections.Generic;
using System.IO;
using System.Text;

namespace A_Determined_Cleanup
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            Solve(args);
            writer.Flush();
        }

        private static void Solve(string[] args)
        {
            long p = Next();
            long k = Next();

            var list = new List<long>();

            while (true)
            {
                long x;
                if (k > p)
                {
                    x = (k - p)/k;
                    if ((k - p)%k == 0)
                        x--;

                    list.Add(x*k + p);
                    p = x;
                }
                else
                {
                    x = (k - p)/k;
                    x--;
                    list.Add(x*k + p);
                    p = x;
                }
                if (p == 0)
                    break;
            }

            writer.WriteLine(list.Count);
            foreach (long l in list)
            {
                writer.Write(l);
                writer.Write(' ');
            }
        }

        private static long Next()
        {
            int c;
            long res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


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

using E = System.Linq.Enumerable;

internal partial class Solver {
    public void Run() {
        var n = ni();
        var k = ni();
        var mod = 998244353;
        var b = new Binomial(1000010, mod);
        long ans = 0;
        if (k == 1) {
            ans = n;
        } else {
            for (int i = 1; i <= n; i++) {
                var d = n / i;
                if (d < k) break;
                ans += b[d - 1, k - 1];
                ans %= mod;
            }

        }
        cout.WriteLine(ans);

    }
}
public class Binomial {
    private readonly long[] factorial;
    private readonly long[] inverseFactorial;
    private readonly long[] inverse;
    private readonly int mod;

    public Binomial(int size, int primeMod) {
        size++;
        factorial = new long[size];
        inverseFactorial = new long[size];
        inverse = new long[size];
        mod = primeMod;
        Setup(size);
    }

    private void Setup(int size) {
        factorial[0] = factorial[1] = 1;
        inverseFactorial[0] = inverseFactorial[1] = 1;
        inverse[1] = 1;
        for (int i = 2; i < size; i++) {
            factorial[i] = factorial[i - 1] * i % mod;
            inverse[i] = (mod - (mod / i) * inverse[mod % i] % mod);
            inverseFactorial[i] = inverseFactorial[i - 1] * inverse[i] % mod;
        }
    }

    private long C(int s, int t) {
        if (s < 0 || t < 0 || s < t) {
            return 0;
        }

        if (t == 0 || s == t) {
            return 1;
        }

        if (s >= mod) {
            return C(s % mod, t % mod) * C(s / mod, t / mod) % mod; // Lucas' theorem
        }

        return factorial[s] * inverseFactorial[t] % mod * inverseFactorial[s - t] % mod;
    }

    public long this[int s, int t] {
        get {
            return C(s, t);
        }
    }

    public long P(int s, int t) {
        if (s < 0 || t < 0 || s < t) return 0;
        return factorial[s] * inverseFactorial[s - t] % mod;
    }

    /// <summary>
    /// s ��ނ̂��̂���d���������� t �I�ԏꍇ�̐�
    /// </summary>
    public long H(int s, int t) {
        if (s < 0 || t < 0) return 0;
        if (s == 0 && t == 0) return 1;
        return C(s + t - 1, t);
    }

    public long H1(int s, int t) {
        return H(s, t - s);
    }
}

// PREWRITEN CODE BEGINS FROM HERE

static public class StringExtensions {
    static public string JoinToString<T>(this IEnumerable<T> source, string separator = " ") {
        return string.Join(separator, source);
    }
}

internal partial class Solver : Scanner {
    public static void Main() {
#if LOCAL
        byte[] inputBuffer = new byte[1000000];
        var inputStream = Console.OpenStandardInput(inputBuffer.Length);
        using (var reader = new StreamReader(inputStream, Console.InputEncoding, false, inputBuffer.Length)) {
            Console.SetIn(reader);
            new Solver(Console.In, Console.Out).Run();
        }
#else
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver(Console.In, Console.Out).Run();
        Console.Out.Flush();
#endif
    }

#pragma warning disable IDE0052
    private readonly TextReader cin;
    private readonly TextWriter cout;
    private readonly TextWriter cerr;
#pragma warning restore IDE0052

    public Solver(TextReader reader, TextWriter writer)
        : base(reader) {
        cin = reader;
        cout = writer;
        cerr = Console.Error;
    }

    public Solver(string input, TextWriter writer)
        : this(new StringReader(input), writer) {
    }

#pragma warning disable IDE1006
#pragma warning disable IDE0051
    private int ni() { return NextInt(); }
    private int[] ni(int n) { return NextIntArray(n); }
    private long nl() { return NextLong(); }
    private long[] nl(int n) { return NextLongArray(n); }
    private double nd() { return NextDouble(); }
    private double[] nd(int n) { return NextDoubleArray(n); }
    private string ns() { return Next(); }
    private string[] ns(int n) { return NextArray(n); }
#pragma warning restore IDE1006
#pragma warning restore IDE0051
}

internal static class LinqPadExtension {
    [Conditional("DEBUG")]
    public static void Dump<T>(this T obj) {
#if DEBUG
        LINQPad.Extensions.Dump(obj);
#endif
    }
}

public class Scanner {
    private readonly TextReader Reader;
    private readonly CultureInfo ci = CultureInfo.InvariantCulture;

    private readonly char[] buffer = new char[2 * 1024];
    private int cursor = 0, length = 0;
    private string Token;
    private readonly StringBuilder sb = new StringBuilder(1024);

    public Scanner()
        : this(Console.In) {
    }

    public Scanner(TextReader reader) {
        Reader = reader;
    }

    public int NextInt() { return checked((int)NextLong()); }
    public long NextLong() {
        var s = Next();
        long r = 0;
        int i = 0;
        bool negative = false;
        if (s[i] == '-') {
            negative = true;
            i++;
        }
        for (; i < s.Length; i++) {
            r = r * 10 + (s[i] - '0');
#if DEBUG
            if (!char.IsDigit(s[i])) throw new FormatException();
#endif
        }
        return negative ? -r : r;
    }
    public double NextDouble() { return double.Parse(Next(), ci); }
    public string[] NextArray(int size) {
        string[] array = new string[size];
        for (int i = 0; i < size; i++) {
            array[i] = Next();
        }

        return array;
    }
    public int[] NextIntArray(int size) {
        int[] array = new int[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextInt();
        }

        return array;
    }

    public long[] NextLongArray(int size) {
        long[] array = new long[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextLong();
        }

        return array;
    }

    public double[] NextDoubleArray(int size) {
        double[] array = new double[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextDouble();
        }

        return array;
    }

    public string Next() {
        if (Token == null) {
            if (!StockToken()) {
                throw new Exception();
            }
        }
        var token = Token;
        Token = null;
        return token;
    }

    public bool HasNext() {
        if (Token != null) {
            return true;
        }

        return StockToken();
    }

    private bool StockToken() {
        while (true) {
            sb.Clear();
            while (true) {
                if (cursor >= length) {
                    cursor = 0;
                    if ((length = Reader.Read(buffer, 0, buffer.Length)) <= 0) {
                        break;
                    }
                }
                var c = buffer[cursor++];
                if (33 <= c && c <= 126) {
                    sb.Append(c);
                } else {
                    if (sb.Length > 0) break;
                }
            }

            if (sb.Length > 0) {
                Token = sb.ToString();
                return true;
            }

            return false;
        }
    }
}


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

namespace Codeforces
{
    internal class Program
    {
        private const string Test = "E2";

        private static void Solve()
        {
            var MOD = 1000000007;
            var input = ReadIntArray();
            var n = input[0];
            var m = input[1];
            var k = input[2];
            var dp = new List<List<long>>();
            for (int i = 0; i <= 1001; i++)
            {
                dp.Add(new List<long>());
                for (int j = 0; j <= i; j++)
                {
                    if(j == 0 || j == i)
                        dp[i].Add(1);
                    else
                    {
                        dp[i].Add((dp[i-1][j-1] + dp[i - 1][j]) % MOD);
                    }
                }
            }
            var res = Math.Min(n - 1, m - 1) < 2*k ? 0: dp[n - 1][2*k]*dp[m - 1][2*k];
            res %= MOD;
            Console.WriteLine(res);
        }

        private static void Main()
        {
            if (Debugger.IsAttached)
            {
                Console.SetIn(new StreamReader(String.Format(@"..\..\..\..\Tests\{0}.in", Test)));
            }

            Solve();

            if (Debugger.IsAttached)
            {
                Console.In.Close();
                Console.SetIn(new StreamReader(Console.OpenStandardInput()));
                Console.ReadLine();
            }
        }

        #region Reader

        private static string Read()
        {
            return Console.ReadLine();
        }

        private static string[] ReadArray()
        {
            return Console.ReadLine().Split(' ');
        }

        private static int[] ReadIntArray()
        {
            var input = Console.ReadLine().Split(' ').Select(Int32.Parse).ToArray();
            return input;
        }

        private static int ReadInt()
        {
            return Int32.Parse(Console.ReadLine());
        }

        private static long ReadLong()
        {
            return long.Parse(Console.ReadLine());
        }

        private static int ReadNextInt(string[] input, int index)
        {
            return Int32.Parse(input[index]);
        }

        #endregion
    }
}


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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var data = Console.ReadLine().Split().Select(long.Parse).ToArray();
            var n = data[0];
            var m = data[1];
            var coffe = Console.ReadLine().Split().Select(long.Parse).OrderByDescending(x => x).ToArray();
            var totalCofee = 0L;
            for (int i = 0; i < n; i++)
                totalCofee += coffe[i];
            if (totalCofee < m)
            {
                Console.WriteLine("-1");
                return;
            }

            var res = GetMinDays(coffe, m);
            Console.WriteLine(res);
        }

        static long GetMinDays(long[] coffe, long countPages)
        {
            var l = 1;
            var r = coffe.Length;
            while (l < r)
            {
                var m = l + (r - l)/2;
                if (!IsCanDo(countPages, m, coffe))
                    l = m + 1;
                else
                    r = m;
            }

            return l;
        }

        static bool IsCanDo(long countPages, long days, long[] coffe)
        {
            var fine = 0L;
            var res = 0L;
            for (var i = 0; i < coffe.Length; i++)
            {
                res += Math.Max(coffe[i] - fine, 0);
                if ((i + 1) % days == 0)
                    fine++;
            }

            return res >= countPages;
        }
    }
}


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

public class Program
{
    private int N, K;

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

        /*
         * N*Nグリッド
         *
         * 各ますには 1~K書かれてる
         *
         * 各行、列の最小値は1
         *
         * 何通りか?
         */

        var c = new BinomialCoefficient(500);

        // i行目まで見る
        // j列に1がある
        ModInt[,] dp = new ModInt[N + 1, N + 1];
        dp[0, 0] = 1;
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j <= N; j++)
            {
                var cur = dp[i, j];
                for (int k = j; k <= N; k++)
                {
                    if (j == 0 && k == 0) continue;

                    ModInt mul;
                    if (j == k)
                    {
                        mul = (ModInt.Pow(K, j) - ModInt.Pow(K - 1, j)) * ModInt.Pow(K-1, N - j);
                    }
                    else
                    {
                        mul = ModInt.Pow(K, j) * c[N - j, k - j] * ModInt.Pow(K - 1, N - k);
                    }

                    dp[i + 1, k] += cur * mul;
                }
            }
        }

        Console.WriteLine(dp[N, N]);
    }

    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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class IOHelper : IDisposable
    {
        StreamReader reader;
        StreamWriter writer;

        public IOHelper(string inputFile, string outputFile, Encoding encoding)
        {
            StreamReader iReader;
            StreamWriter oWriter;
            if (inputFile == null)
                iReader = new StreamReader(Console.OpenStandardInput(), encoding);
            else
                iReader = new StreamReader(inputFile, encoding);

            if (outputFile == null)
                oWriter = new StreamWriter(Console.OpenStandardOutput(), encoding);
            else
                oWriter = new StreamWriter(outputFile, false, encoding);

            reader = iReader;
            writer = oWriter;

            curLine = new string[] { };
            curTokenIdx = 0;
        }

        string[] curLine;
        int curTokenIdx;

        char[] whiteSpaces = new char[] { ' ', '\t', '\r', '\n' };

        public string ReadNextToken()
        {
            if (curTokenIdx >= curLine.Length)
            {
                //Read next line
                string line = reader.ReadLine();
                if (line != null)
                    curLine = line.Split(whiteSpaces, StringSplitOptions.RemoveEmptyEntries);
                else
                    curLine = new string[] { };
                curTokenIdx = 0;
            }

            if (curTokenIdx >= curLine.Length)
                return null;

            return curLine[curTokenIdx++];
        }

        public int ReadNextInt()
        {
            return int.Parse(ReadNextToken());
        }

        public double ReadNextDouble()
        {
            var nextToken = ReadNextToken();
            var result = 0.0;
            nextToken = nextToken.Replace(".", System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator);
            result = double.Parse(nextToken);
            return result;
        }

        public void Write(string stringToWrite)
        {
            writer.Write(stringToWrite);
        }

        public void WriteLine(string stringToWrite)
        {
            writer.WriteLine(stringToWrite);
        }

        public void WriteLine(double valueToWrite)
        {
            long intPart = (long)valueToWrite;
            double fracPart = valueToWrite - intPart;
            var fracPartStr = fracPart.ToString("F8");
            if (fracPartStr.Length > 1)
                fracPartStr = fracPartStr.Substring(2);
            var strToWrite = string.Format("{0}.{1}", intPart, fracPartStr);
            writer.WriteLine(strToWrite);
        }

        public void Dispose()
        {
            try
            {
                if (reader != null)
                {
                    reader.Dispose();
                }
                if (writer != null)
                {
                    writer.Dispose();
                }
            }
            catch { };
        }

        public void Flush()
        {
            if (writer != null)
            {
                writer.Flush();
            }
        }
    }

    class Program
    {
        protected IOHelper ioHelper;

        int n, m;

        List<Tuple<int, int>> first = new List<Tuple<int, int>>();
        List<Tuple<int, int>> second = new List<Tuple<int, int>>();

        HashSet<int>[] countFirst = new HashSet<int>[20];
        HashSet<int>[] countSecond = new HashSet<int>[20];

        int sol = -1;

        int ExSol(Tuple<int, int> first, Tuple<int, int> second)
        {
            int sol = first.Item1;
            if (sol != second.Item1 && sol != second.Item2)
                sol = first.Item2;

            return sol;
        }

        public void Solve()
        {
            n = ioHelper.ReadNextInt();
            m = ioHelper.ReadNextInt();

            int i,a,b,j;
            for(i=0;i<n;i++)
            {
                a = ioHelper.ReadNextInt();
                b = ioHelper.ReadNextInt();

                if (b < a)
                {
                    int t = b;
                    b = a;
                    a = t;
                }
                countFirst[i] = new HashSet<int>();
                first.Add(new Tuple<int, int>(a, b));
            }

            for (i = 0; i < m; i++)
            {
                a = ioHelper.ReadNextInt();
                b = ioHelper.ReadNextInt();

                if (b < a)
                {
                    int t = b;
                    b = a;
                    a = t;
                }
                countSecond[i] = new HashSet<int>();
                second.Add(new Tuple<int, int>(a, b));
            }

            for(i=0;i<n;i++)
                for(j=0;j<m;j++)
                    if(first[i].Item1 == second[j].Item1 || first[i].Item1 == second[j].Item2 ||
                        first[i].Item2 == second[j].Item1 || first[i].Item2 == second[j].Item2)
                        if(first[i].Item1 != second[j].Item1 || first[i].Item2 != second[j].Item2)
                        {
                            sol = first[i].Item1;
                            if (sol != second[j].Item1 && sol != second[j].Item2)
                                sol = first[i].Item2;

                            countFirst[i].Add(sol);
                            countSecond[j].Add(sol);
                        }

            int bOneAltrs = 0;
            bool bTwoAltrs = false;

            for (i = 0; i < n; i++)
                if (countFirst[i].Count > 1)
                    sol = -1;
                else if (countFirst[i].Count == 1) {
                    if(bOneAltrs != 0 && bOneAltrs != countFirst[i].First())
                    {
                        bTwoAltrs = true;
                    }
                    bOneAltrs = countFirst[i].First();
                }

            int bOneAltrs2 = 0;
            bool bTwoAltrs2 = false;

            for (i = 0; i < m; i++)
                if (countSecond[i].Count > 1)
                    sol = -1;
                else if (countSecond[i].Count == 1)
                {
                    if (bOneAltrs2 != 0 && bOneAltrs2 != countSecond[i].First())
                    {
                        bTwoAltrs2 = true;
                    }
                    bOneAltrs2 = countSecond[i].First();
                }

            if (sol != -1)
                if (bTwoAltrs || bTwoAltrs2)
                    sol = 0;
                else
                    sol = bOneAltrs;

            ioHelper.WriteLine(sol.ToString());
            ioHelper.Flush();

            //Console.ReadKey();
        }

        public Program(string inputFile, string outputFile)
        {
            ioHelper = new IOHelper(inputFile, outputFile, Encoding.Default);
            Solve();
            ioHelper.Dispose();
        }

        static void Main(string[] args)
        {
            Program myProgram = new Program(null, null);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Text;
using System.Diagnostics;
using System.Numerics;
using static System.Console;
using static System.Convert;
using static System.Math;
using static Template;
using SC = Scanner;

public partial class Solver
{
    int N, X;
    string S;
    public void Solve()
    {
        sc.Make(out N, out X);
        S = sc.Str;
        if (X <= 1) Fail(ToInt32(S.Length==1&&S[0] - '0' == X));
        //dp[k][i][j]:=F(k)の部分列に含まれるS[j,i)の数の和
        var cur = Create(N + 1, () => new ModInt[N + 1]);
        var nxt = Create(N + 1, () => new ModInt[N + 1]);
        for (int i = 0; i < N; i++)
        {
            cur[i][i] = nxt[i][i] = 1;
            if (S[i] - '0' == 0) nxt[i + 1][i] = 1;
            else cur[i + 1][i] = 1;
        }
        //端はとっても取らなくてもいいので2
        cur[0][0] = cur[N][N] = nxt[0][0] = nxt[N][N] = 2;
        for (int i = 0; i < X - 1; i++)
        {
            nxt = matmul(nxt, cur);
            swap(ref cur, ref nxt);
        }
        Console.WriteLine(cur[N][0]);
    }

    ModInt[][] matpow(ModInt[][] A, long k)
    {
        var res = Create(A.Length, () => new ModInt[A.Length]);
        for (int i = 0; i < A.Length; i++) res[i][i] = 1;
        while (k != 0)
        {
            if (k % 2 == 1) res = matmul(res, A);
            k >>= 1;
            A = matmul(A, A);
        }
        return res;
    }
    ModInt[][] matmul(ModInt[][] A, ModInt[][] B)
    {
        var rt = Create(A.Length, () => new ModInt[B[0].Length]);
        for (int i = 0; i < A.Length; i++)
            for (int j = 0; j < B[0].Length; j++)
            {
                for (int k = 0; k < B.Length; k++)
                    rt[i][j] += A[i][k] * B[k][j];
            }
        return rt;
    }
    ModInt[] matdot(ModInt[][] A, ModInt[] B)
    {
        var rt = new ModInt[A.Length];
        for (int i = 0; i < A.Length; i++)
        {
            ModInt now = 0;
            for (int j = 0; j < B.Length; j++)
            {
                now += A[i][j] * B[j];
            }
            rt[i] = now;
        }
        return rt;
    }
}

public struct ModInt
{
    public const long MOD = (int)1e9 + 7;
    //public const long MOD = 998244353;
    public long Value { get; set; }
    public ModInt(long n = 0) { Value = n; }
    private static ModInt[] fac, inv, facinv;
    public override string ToString() => Value.ToString();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator +(ModInt l, ModInt r)
    {
        l.Value += r.Value;
        if (l.Value >= MOD) l.Value -= MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator -(ModInt l, ModInt r)
    {
        l.Value -= r.Value;
        if (l.Value < 0) l.Value += MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator *(ModInt l, ModInt r) => new ModInt(l.Value * r.Value % MOD);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator /(ModInt l, ModInt r) => l * Pow(r, MOD - 2);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator long(ModInt l) => l.Value;
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator ModInt(long n)
    {
        n %= MOD; if (n < 0) n += MOD;
        return new ModInt(n);
    }

    public static ModInt Pow(ModInt m, long n)
    {
        if (n == 0) return 1;
        if (n % 2 == 0) return Pow(m * m, n >> 1);
        else return Pow(m * m, n >> 1) * m;
    }

    public static void Build(int n)
    {
        fac = new ModInt[n + 1];
        facinv = new ModInt[n + 1];
        inv = new ModInt[n + 1];
        inv[1] = fac[0] = fac[1] = facinv[0] = facinv[1] = 1;
        for (var i = 2; i <= n; i++)
        {
            fac[i] = fac[i - 1] * i;
            inv[i] = MOD - inv[MOD % i] * (MOD / i);
            facinv[i] = facinv[i - 1] * inv[i];
        }
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Fac(int n) => fac[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Inv(int n) => inv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt FacInv(int n) => facinv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Comb(int n, int r)
    {
        if (n < r) return 0;
        if (n == r) return 1;
        return fac[n] * facinv[r] * facinv[n - r];
    }
    public static ModInt Perm(int n, int r)
    {
        if (n < r) return 0;
        return fac[n] * facinv[n - r];
    }

}
#region Template
public partial class Solver
{
    public SC sc = new SC();
    static void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        var sol = new Solver();
        int testcase = 1;
        //testcase = sol.sc.Int;
        //var th = new Thread(sol.Solve, 1 << 26);th.Start();th.Join();
        while (testcase-- > 0)
            sol.Solve();
        Console.Out.Flush();
    }
}
public static class Template
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) > 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(ref T a, ref T b) { var t = b; b = a; a = t; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(this IList<T> A, int i, int j) { var t = A[i]; A[i] = A[j]; A[j] = t; }
    public static T[] Create<T>(int n, Func<T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(); return rt; }
    public static T[] Create<T>(int n, Func<int, T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(i); return rt; }
    public static void Out<T>(this IList<T> A, out T a) => a = A[0];
    public static void Out<T>(this IList<T> A, out T a, out T b) { a = A[0]; b = A[1]; }
    public static void Out<T>(this IList<T> A, out T a, out T b, out T c) { A.Out(out a, out b); c = A[2]; }
    public static void Out<T>(this IList<T> A, out T a, out T b, out T c, out T d) { A.Out(out a, out b, out c); d = A[3]; }
    public static string Concat<T>(this IEnumerable<T> A, string sp) => string.Join(sp, A);
    public static char ToChar(this int s, char begin = '0') => (char)(s + begin);
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> A) => A.OrderBy(v => Guid.NewGuid());
    public static int CompareTo<T>(this T[] A, T[] B, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; for (var i = 0; i < Min(A.Length, B.Length); i++) { int c = cmp(A[i], B[i]); if (c > 0) return 1; else if (c < 0) return -1; } if (A.Length == B.Length) return 0; if (A.Length > B.Length) return 1; else return -1; }
    public static string ToStr<T>(this T[][] A) => A.Select(a => a.Concat(" ")).Concat("\n");
    public static int ArgMax<T>(this IList<T> A, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; T max = A[0]; int rt = 0; for (int i = 1; i < A.Count; i++) if (cmp(max, A[i]) < 0) { max = A[i]; rt = i; } return rt; }
    public static T PopBack<T>(this List<T> A) { var v = A[A.Count - 1]; A.RemoveAt(A.Count - 1); return v; }
    public static void Fail<T>(T s) { Console.WriteLine(s); Console.Out.Close(); Environment.Exit(0); }
}
public class Scanner
{
    public string Str => Console.ReadLine().Trim();
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public int[] ArrInt => Str.Split(' ').Select(int.Parse).ToArray();
    public long[] ArrLong => Str.Split(' ').Select(long.Parse).ToArray();
    public char[][] Grid(int n) => Create(n, () => Str.ToCharArray());
    public int[] ArrInt1D(int n) => Create(n, () => Int);
    public long[] ArrLong1D(int n) => Create(n, () => Long);
    public int[][] ArrInt2D(int n) => Create(n, () => ArrInt);
    public long[][] ArrLong2D(int n) => Create(n, () => ArrLong);
    private Queue<string> q = new Queue<string>();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public T Next<T>() { if (q.Count == 0) foreach (var item in Str.Split(' ')) q.Enqueue(item); return (T)Convert.ChangeType(q.Dequeue(), typeof(T)); }
    public void Make<T1>(out T1 v1) => v1 = Next<T1>();
    public void Make<T1, T2>(out T1 v1, out T2 v2) { v1 = Next<T1>(); v2 = Next<T2>(); }
    public void Make<T1, T2, T3>(out T1 v1, out T2 v2, out T3 v3) { Make(out v1, out v2); v3 = Next<T3>(); }
    public void Make<T1, T2, T3, T4>(out T1 v1, out T2 v2, out T3 v3, out T4 v4) { Make(out v1, out v2, out v3); v4 = Next<T4>(); }
    public void Make<T1, T2, T3, T4, T5>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5) { Make(out v1, out v2, out v3, out v4); v5 = Next<T5>(); }
    public void Make<T1, T2, T3, T4, T5, T6>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6) { Make(out v1, out v2, out v3, out v4, out v5); v6 = Next<T6>(); }
    public void Make<T1, T2, T3, T4, T5, T6, T7>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6, out T7 v7) { Make(out v1, out v2, out v3, out v4, out v5, out v6); v7 = Next<T7>(); }
    public (T1, T2) Make<T1, T2>() { Make(out T1 v1, out T2 v2); return (v1, v2); }
    public (T1, T2, T3) Make<T1, T2, T3>() { Make(out T1 v1, out T2 v2, out T3 v3); return (v1, v2, v3); }
    public (T1, T2, T3, T4) Make<T1, T2, T3, T4>() { Make(out T1 v1, out T2 v2, out T3 v3, out T4 v4); return (v1, v2, v3, v4); }
}

#endregion


using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
//using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

//using System.Threading;

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            /*Random random = new Random();
            for (int kk = 0; kk < 50; kk++)
            {
                for (int i = 0; i < 250; i++)
                {
                    Writer.Write("{0} ", random.Next(201));
                }
                Writer.WriteLine();
            }*/

            int[] a = ReadIntArray();
            int n = a.Length;
            int s = 10; // ???
            // double min = a.Min();
            // double max = a.Max();
            // double d = max - min;
            // min -= d / 2 / n;
            // max += d / 2 / n;

            double p = a.Average();
            //double sum = GetValue(a, s, n, a.Max());
            double mean = a.Average();
            double sum = a.Sum(x => (x - mean) * (x - mean));
            sum /= (a.Max() - a.Min()) * (a.Max() - a.Min());

            int k = s - 3;
            // double X = 2.17;
            double X = 40;

            maxx = Math.Min(maxx, sum);
            // Writer.WriteLine(maxx);
            bool isUniform = sum > 15;
            //Writer.WriteLine(isUniform ? "uniform" : "poisson");
            if (isUniform)
            {
                double dd = a.Average();
                int minOption = (int)(dd * 0.9);
                int maxOption = (int)(dd * 1.1);
                int[] c2 = new int[maxOption + 1];
                double[] c3 = new double[maxOption + 1];

                int minGc = 20;
                int maxGc = 30;
                for (int gc = minGc; gc <= maxGc; gc++)
                {
                    int avg = -1;
                    double best = double.MaxValue;
                    for (int i = minOption; i <= maxOption; i++)
                    {
                        var val = GetValue(a, gc, n, 2 * i);
                        if (val < best)
                        {
                            best = val;
                            avg = i;
                        }
                        c3[i] += val;
                    }
                    c2[avg]++;
                }
                /*int ans = minOption;
                for (int i = minOption; i <= maxOption; i++)
                {
                    if (c2[i] <= c2[ans])
                    {
                        ans = i;
                    }
                }*/
                double ans = 0;
                for (int i = minOption; i <= maxOption; i++)
                {
                    ans += c2[i] * i;
                }
                ans /= (maxGc - minGc + 1);
                Writer.WriteLine((int)ans);
                // Writer.WriteLine(((int) Math.Round(a.Average())));
                //int[] sorted = a.OrderBy(x => x).ToArray();
                //int avg = (sorted[n / 2] + sorted[(n - 1) / 2]) / 2;
                //Writer.WriteLine("{0} {1}", avg, a.Average());
                // Writer.WriteLine(avg);
            }
            else
            {
                //int R = 50;
                //a = a.OrderBy(x => x).Take(a.Length - R).Skip(R).ToArray();
                Writer.WriteLine(((int)Math.Round(a.Average())));
            }
        }

        private static double GetValue(int[] a, int s, int n, double max)
        {
            double min = 0;
            double e = (max - min) / s;

            int[] count = new int[s];
            for (int i = 0; i < n; i++)
            {
                int index = (int)((a[i] - min - 1e-10) / e);
                if (index < 0)
                {
                    index = 0;
                }
                if (index >= s)
                {
                    index = s - 1;
                }
                count[index]++;
            }

            double np = (double)n / s;
            double sum = count.Sum(x => (x - np) * (x - np) / np);
            return sum;
        }

        public static double maxx = double.MaxValue;

        public static void Solve()
        {
            int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                //Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }
        }

        public class Point
        {
            public Point(int x, int y)
            {
                X = x;
                Y = y;
            }

            public int X;

            public int Y;

            protected bool Equals(Point other)
            {
                return X == other.X && Y == other.Y;
            }

            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj))
                {
                    return false;
                }
                if (ReferenceEquals(this, obj))
                {
                    return true;
                }
                if (obj.GetType() != this.GetType())
                {
                    return false;
                }
                return Equals((Point)obj);
            }

            public override int GetHashCode()
            {
                unchecked
                {
                    return (X * 397) ^ Y;
                }
            }
        }

        public static class Standard
        {
            public static long Power(long x, long p, long mod)
            {
                long result = 1;
                while (p > 0)
                {
                    if ((p & 1) == 0)
                    {
                        x = (x * x) % mod;
                        p >>= 1;
                    }
                    else
                    {
                        result = (result * x) % mod;
                        p--;
                    }
                }
                return result;
            }

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

            public static List<int> GetPrimes(int n)
            {
                bool[] isPrime = Enumerable.Repeat(true, n).ToArray();
                isPrime[0] = false;
                isPrime[1] = false;
                for (int i = 2; i < n; i++)
                {
                    if (isPrime[i])
                    {
                        for (int j = i + i; j < n; j += i)
                        {
                            isPrime[j] = false;
                        }
                    }
                }
                List<int> primes = new List<int>();
                for (int i = 0; i < n; i++)
                {
                    if (isPrime[i])
                    {
                        primes.Add(i);
                    }
                }
                return primes;
            }
        }

        public static void Main()
        {
            //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            //Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            Solve();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Random rnd = new Random();
            for (int i = result.Length - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = result[k];
                result[k] = result[i];
                result[i] = tmp;
            }
            return result;
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        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 string ReadLine()
        {
            return Reader.ReadLine();
        }

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

        #endregion
    }
}


using System;
using System.Globalization;
using System.IO;
using System.Text;

namespace Guess_the_Tree
{
    internal class Program
    {
        private static readonly StreamReader reader =
            new StreamReader(Console.OpenStandardInput(1024 * 10), Encoding.ASCII, false, 1024 * 10);

        private static readonly StreamWriter writer =
            new StreamWriter(Console.OpenStandardOutput(1024 * 10), Encoding.ASCII, 1024 * 10);

        private static void Main(string[] args)
        {
            int n = int.Parse(reader.ReadLine());

            string[] ss = reader.ReadLine().Split(' ');
           int[] nn = new int[n];
            for (int i = 0; i < n; i++)
            {
                nn[i] = int.Parse(ss[i]);
            }

            Array.Sort(nn);

            bool[] used = new bool[n];
bool ok = n==nn[n-1];
            if (ok)
                for (int i = 0; i < n; i++)
            {
                if (nn[i]>1)
                {
                    int count = nn[i] - 1;
                    int p = 0;
                    for (int j = i; j >=0; j--)
                    {
                        if (!used[j] && nn[j]<=count)
                        {
                            if (p == 0 && nn[j] == count)
                                continue;
                            used[j] = true;
                            count -= nn[j];
                            p++;
                        }
                        if (count==0)
                            break;
                    }
                    if (count!=0)
                    {
                        ok = false;
                        break;
                    }
                }
            }

            writer.WriteLine("{0}", ok ? "YES" : "NO");
            writer.Flush();
        }
    }
}


using System;
using System.IO;
using System.Linq;
using System.Text;

namespace INTERCALC
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            int n = Next();

            var nn = new int[n];
            for (int i = 0; i < n; i++)
            {
                nn[i] = Next();
            }

            writer.WriteLine(nn.Max() ^ nn[n - 1]);
            writer.Flush();
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '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 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
}