using System;
using System.Linq;
using System.Numerics;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var n = int.Parse(Console.ReadLine());

            var m = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            var r = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();

            int[] result = new int[10000];
            for (int i = 0; i < 10000; i++)
            {
                int you = 0;
                for (int j = 0; j < n; j++)
                {
                    if (i % m[j] == r[j])
                    {
                        you = 1;
                        break;
                    }
                }

                result[i] = you;
            }

            Console.WriteLine(result.Average());
        }
    }
}


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

namespace ConsoleApplication1
{
    class Program : ProgramBase
    {
        private const long commonMod = 1000000007;
        static void Main(string[] args)
        {
            var p = new Program();
            var x = p.Get();
            p.Out(x);
        }
        object Get()
        {
            checked
            {
                var n = ReadLong();
                var m = ReadInts();
                var r = ReadInts();
                long all = 1;
                for (int i = 0; i < m.Length; i++)
                {
                    all = all * m[i] / NOD(all, m[i]);
                }
                double result = 0;
                var grid = new bool[all];
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < all; j+=m[i])
			{
			    grid[j + r[i]] = true;
			}
                }
                return (((double)grid.Where(x=>x).Count()) / grid.Count()).ToString().Replace(',', '.');

                //var n = ReadLong();
                //for (int i = 2; i < Math.Sqrt(n) + 1; i++)
                //{
                //    if (n != i && n % i == 0)
                //        return "NO";
                //}
                //return "YES";
            }
        }

        public long NOD(long a, long b)
        {
            if (b > a)
                return NOD(b, a);
            if (b == 0)
                return a;
            return NOD(b, a % b);
        }

        public int BS(int[] arr, int l, int r, int v)
        {
            if (r - l == 1)
                return arr[l] >= v ? l : r;
            var half = (l + r) / 2;
            if (v == arr[half])
                return half;
            if (v < arr[half])
                return BS(arr, l, half, v);
            return BS(arr, half, r, v);
        }

        public double ProcessPair(long[] a, long[] b, int p)
        {
            return ((double)NumberOfDivs(a, p) * 2000) / Count(a) +
                ((double)NumberOfDivs(b, p) * 2000) / Count(b) -
                ((double)(NumberOfDivs(a, p) * NumberOfDivs(b, p))) * 2000 / (Count(a) * Count(b));
        }

        public long NumberOfDivs(long[] a, int p)
        {
            return a[1] / p - (a[0] - 1) / p;
        }

        public long Count(long[] a)
        {
            return a[1] - a[0] + 1;
        }

        bool DoubleEquals(double a, double b)
        {
            return Math.Abs(a - b) < 0.0000000001;
        }

        bool SameLine(double[] a, double[] b, double[] c)
        {
            var x = a[0];
            var y = a[1];
            var x1 = b[0];
            var y1 = b[1];
            var x2 = c[0];
            var y2 = c[1];
            return DoubleEquals((x - x1) * (y2 - y1), (y - y1) * (x2 - x1));
        }

        object Get7()
        {
            checked
            {
                var m = ReadInt();
                var p = ReadLongs();
                var arr = p.GroupBy(x => x).Select(g => new { g.Key, Count = g.Count() }).ToArray();
                var even = arr.Where(x => (x.Count & 1) == 0).FirstOrDefault();
                if (even != null)
                {
                    var index = Array.IndexOf(arr, even);
                    //arr[index].Count = arr[index].Count / 2;
                }
                long divs = 1;
                long result = 1;
                foreach (var a in arr)
                {
                    var pi = a.Key;
                    var curr = pi;
                    var olddivs = divs;
                    var oldres = result;
                    for (int i = 0; i < a.Count; i++)
                    {
                        result = (result * oldres % commonMod) * FastPow(curr, olddivs, commonMod) % commonMod;
                        curr = curr * pi % commonMod;
                        divs = (divs + olddivs) % (commonMod - 1);
                    }
                }
                return result;
            }
        }

        public long FastPow(long x, BigInteger pow, long mod)
        {
            if (pow == 0)
                return 1;
            if ((pow & 1) == 0)
                return FastPow(x * x % mod, pow / 2, mod);
            return x * FastPow(x, pow - 1, mod) % mod;
        }

        class Cut
        {
            public int a;
            public int b;
            public int line;
        }

        //object Get3()
        //{
        //    FileName = "";
        //    checked
        //    {
        //        var n = ReadInt();
        //        var hor = new List<Cut>();
        //        var ver = new List<Cut>();
        //        for (int i = 0; i < n; i++)
        //        {
        //            var a = ReadInts();
        //            if (a[0] == a[2])
        //                ver.Add(new Cut() { a = Math.Min(a[1], a[3]), b = Math.Max(a[1], a[3]), line = a[0] });
        //            else
        //                hor.Add(new Cut() { a = Math.Min(a[0], a[2]), b = Math.Max(a[0], a[2]), line = a[1] });
        //        }
        //        ver = Merge(ver);
        //        hor = Merge(hor);

        //    }
        //}

        List<Cut> Merge(List<Cut> l)
        {
            var a = l.OrderBy(x => x.line).ThenBy(x => x.a).ToArray();
            Cut previous = null;
            var result = new List<Cut>();
            for (int i = 0; i < a.Length; i++)
                if (previous == null)
                    previous = a[i];
                else
                    if (previous.line == a[i].line && previous.b >= a[i].a)
                        previous.b = Math.Max(previous.b, a[i].b);
                    else
                    {
                        result.Add(previous);
                        previous = a[i];
                    }
            if (previous != null)
                result.Add(previous);
            return result;
        }

    }
    abstract class ProgramBase
    {
        bool? prod = null;
        StreamReader f;
        protected string FileName { private get; set; }

        protected string Read()
        {
            if (string.IsNullOrEmpty(FileName))
                return Console.ReadLine();
            if (f == null)
                f = new StreamReader((GetProd() ? "" : "c:\\dev\\") + FileName + ".in");
            return f.ReadLine();
        }

        protected int ReadInt()
        {
            return Convert.ToInt32(Read());
        }
        protected int[] ReadInts()
        {
            return Read().Split(' ').Select(x => Convert.ToInt32(x)).ToArray();
        }

        protected long ReadLong()
        {
            return Convert.ToInt64(Read());
        }

        protected long[] ReadLongs()
        {
            return Read().Split(' ').Select(x => Convert.ToInt64(x)).ToArray();
        }

        public void Out(object r)
        {
            if (string.IsNullOrEmpty(FileName))
                Console.WriteLine(r);
            else if (GetProd())
                File.WriteAllText(FileName + ".out", r.ToString());
            else
                Console.WriteLine(r);
        }

        private bool GetProd()
        {
            if (!prod.HasValue)
                try
                {
                    prod = Environment.MachineName != "RENADEEN-NB-W7";
                }
                catch (Exception)
                {
                    prod = true;
                }
            return prod.Value;
        }
    }

    public static class Huj
    {
        public static T MinBy<T>(this IEnumerable<T> source, Func<T, double> func) where T : class
        {
            T result = null;
            var min = double.MaxValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (min > current)
                {
                    min = current;
                    result = item;
                }
            }
            return result;
        }

        public static T MaxBy<T>(this IEnumerable<T> source, Func<T, double> func)
        {
            T result = default(T);
            var max = double.MinValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (max < current)
                {
                    max = current;
                    result = item;
                }
            }
            return result;
        }

        public static string JoinStrings(this IEnumerable<string> source, string delimeter)
        {
            return string.Join(delimeter, source.ToArray());
        }
    }
}


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

namespace AlgoTraining.Codeforces.AprilFool2016
{

    class FastScanner : StreamReader
    {
        private string[] _line;
        private int _iterator;

        public FastScanner(Stream stream) : base(stream)
        {
            _line = null;
            _iterator = 0;
        }
        public int NextInt()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt32(_line[_iterator++]);
        }
        public long NextLong()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt64(_line[_iterator++]);
        }
    }
    class ScrambledB
    {
        public static void Main(string[] args)
        {
            using (FastScanner fs = new FastScanner(new BufferedStream(Console.OpenStandardInput())))
            using (StreamWriter writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput())))
            {
                int n = fs.NextInt();
                int[] m = new int[n], r = new int[n];
                for (int i = 0; i < n; i++) m[i] = fs.NextInt();
                for (int i = 0; i < n; i++) r[i] = fs.NextInt();
                int size = (int)1e6;
                bool[] onDuty = new bool[size];
                for (int i = 0; i < size; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        if (i % m[j] == r[j])
                        {
                            onDuty[i] = true;
                            break;
                        }
                    }
                }
                int count = 0;
                for (int i = 0; i < size; i++)
                {
                    if (onDuty[i]) count++;
                }
                writer.WriteLine(((count * 1.0) / size).ToString().Replace(",", "."));
            }
        }
    }
}


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

namespace Task1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.ReadLine();
            var M = Console.ReadLine().Split(' ').Select(Int32.Parse).ToArray();
            var R = Console.ReadLine().Split(' ').Select(Int32.Parse).ToArray();

            int res=0;
            for (int i = 0; i < 1000000; i++)
            {
                for (int z = 0; z < M.Length; z++)
                    if (i % M[z] == R[z]) { res++; break; }
            }
            Console.WriteLine(String.Format("{0:0.000000}", (double)res / 1000000).Replace(',','.'));

        }
    }
}


using System;
using System.Globalization;
using System.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main()
        {
            var n = int.Parse(Console.ReadLine());

            var m = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            var r = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();

            var i1 = 1000000;
            int[] result = new int[i1];
            for (int i = 0; i < i1; i++)
            {
                int you = 0;
                for (int j = 0; j < n; j++)
                {
                    if (i % m[j] == r[j])
                    {
                        you = 1;
                        break;
                    }
                }

                result[i] = you;
            }

            Console.WriteLine(result.Average().ToString(CultureInfo.InvariantCulture));
        }
    }
}


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
//using DebugerVisualizer;

namespace _105
{
	[Serializable]
	class VNodeValue<TNode>
	{
		public int Version;
		public TNode Value;

		public VNodeValue(int version)
		{
			Version = version;
		}
	}

	[Serializable]
	class VEdge<TNode, TEdge>
		where TNode : ICloneable
	{
		public TEdge Value;
		public VNode<TNode, TEdge> Source;
		public VNode<TNode, TEdge> Target;

		public override string ToString()
		{
			return Value.ToString();
		}
	}

	[Serializable]
	class VEdges<TNode, TEdge>
		where TNode : ICloneable
	{
		public int Version;
		public List<VEdge<TNode, TEdge>> Edges = new List<VEdge<TNode, TEdge>>();

		public VEdges(int version)
		{
			Version = version;
		}
	}

	[Serializable]
	class VNode<TNode, TEdge>
		where TNode : ICloneable
	{
		VGraph<TNode, TEdge> _graph;

		Stack<VNodeValue<TNode>> _valueStack = new Stack<VNodeValue<TNode>>();
		Stack<VEdges<TNode, TEdge>> _ins = new Stack<VEdges<TNode, TEdge>>();
		Stack<VEdges<TNode, TEdge>> _outs = new Stack<VEdges<TNode, TEdge>>();

		internal VNode(VGraph<TNode, TEdge> graph, TNode nodeValue)
		{
			_graph = graph;
			var newNode = new VNodeValue<TNode>(_graph.Version);
			newNode.Value = nodeValue;
			_valueStack.Push(newNode);
			_ins.Push(new VEdges<TNode, TEdge>(_graph.Version));
			_outs.Push(new VEdges<TNode, TEdge>(_graph.Version));
		}

		public TNode ReadValue
		{
			get { return _valueStack.Peek().Value; }
		}

		public TNode WriteValue
		{
			get
			{
				if (_valueStack.Peek().Version != _graph.Version)
				{
					var newVersion = new VNodeValue<TNode>(_graph.Version);
					if (_valueStack.Peek().Value != null)
						newVersion.Value = (TNode)_valueStack.Peek().Value.Clone();
					_valueStack.Push(newVersion);
					_graph.SheduleValueRollback(this);
				}

				return _valueStack.Peek().Value;
			}
		}

		public IEnumerable<VEdge<TNode, TEdge>> Ins
		{
			get
			{
				foreach (var edges in _ins)
					foreach (var e in edges.Edges)
					{
						yield return e;
					}
			}
		}

		public IEnumerable<VEdge<TNode, TEdge>> Outs
		{
			get
			{
				foreach (var edges in _outs)
					foreach (var e in edges.Edges)
					{
						yield return e;
					}
			}
		}

		public void AddIns(VEdge<TNode, TEdge> edge)
		{
			if (_ins.Peek().Version != _graph.Version)
			{
				var newVersion = new VEdges<TNode, TEdge>(_graph.Version);
				_ins.Push(newVersion);
				_graph.SheduleInEdgeRollback(this);
			}
			_ins.Peek().Edges.Add(edge);
		}

		public void AddOut(VEdge<TNode, TEdge> edge)
		{
			if (_outs.Peek().Version != _graph.Version)
			{
				var newVersion = new VEdges<TNode, TEdge>(_graph.Version);
				_outs.Push(newVersion);
				_graph.SheduleOutEdgeRollback(this);
			}
			_outs.Peek().Edges.Add(edge);
		}

		internal void RollbackValue()
		{
			_valueStack.Pop();
		}

		internal void RollbackIns()
		{
			_ins.Pop();
		}

		internal void RollbackOuts()
		{
			_outs.Pop();
		}

		public override string ToString()
		{
			return ReadValue.ToString();
		}
	}

	[Serializable]
	class VGraph<TNode, TEdge> : IDisposable
		where TNode : ICloneable
	{
		public int Version = 0;

		Stack<List<VNode<TNode, TEdge>>> _valueRollbacks = new Stack<List<VNode<TNode, TEdge>>>();
		Stack<List<VNode<TNode, TEdge>>> _inEdgeRollbacks = new Stack<List<VNode<TNode, TEdge>>>();
		Stack<List<VNode<TNode, TEdge>>> _outEdgeRollbacks = new Stack<List<VNode<TNode, TEdge>>>();

		public VGraph()
		{
			StartTransaction();
		}

		public void SheduleValueRollback(VNode<TNode, TEdge> node)
		{
			_valueRollbacks.Peek().Add(node);
		}

		public void SheduleInEdgeRollback(VNode<TNode, TEdge> node)
		{
			_inEdgeRollbacks.Peek().Add(node);
		}

		public void SheduleOutEdgeRollback(VNode<TNode, TEdge> node)
		{
			_outEdgeRollbacks.Peek().Add(node);
		}

		public VNode<TNode, TEdge> AddNode(TNode nodeValue)
		{
			return new VNode<TNode, TEdge>(this, nodeValue);
		}

		public void AddEdge(VNode<TNode, TEdge> a, VNode<TNode, TEdge> b, TEdge edgeValue)
		{
			var newEdge = new VEdge<TNode, TEdge>();
			newEdge.Source = a;
			newEdge.Target = b;
			newEdge.Value = edgeValue;

			a.AddOut(newEdge);
			b.AddIns(newEdge);
		}

		public VGraph<TNode, TEdge> StartTransaction()
		{
			this.Version++;
			_valueRollbacks.Push(new List<VNode<TNode, TEdge>>());
			_inEdgeRollbacks.Push(new List<VNode<TNode, TEdge>>());
			_outEdgeRollbacks.Push(new List<VNode<TNode, TEdge>>());
			return this;
		}

		public void Rollback()
		{
			foreach (var values in _valueRollbacks.Pop())
				values.RollbackValue();
			foreach (var values in _inEdgeRollbacks.Pop())
				values.RollbackIns();
			foreach (var values in _outEdgeRollbacks.Pop())
				values.RollbackOuts();
			this.Version--;
		}

		public void Dispose()
		{
			Rollback();
		}
	}

	//[DebuggerVisualizer(typeof(ExpressionBuilderVisualizer))]
	[Serializable]
	class GameState : IDisposable
	{
		VGraph<ExpressionNode, ExpressionPath> _graph = new VGraph<ExpressionNode, ExpressionPath>();
		Stack<List<VNode<ExpressionNode, ExpressionPath>>> nodes = new Stack<List<VNode<ExpressionNode, ExpressionPath>>>();
		Stack<VNode<ExpressionNode, ExpressionPath>[]> playerNodes = new Stack<VNode<ExpressionNode, ExpressionPath>[]>();
		VNode<ExpressionNode, ExpressionPath>[] playerStartNodes = new VNode<ExpressionNode, ExpressionPath>[3];
		int nodesCount = 0;

		public IEnumerable<VNode<ExpressionNode, ExpressionPath>> Nodes
		{
			get
			{
				foreach (var ns in nodes)
					foreach (var node in ns)
						yield return node;
			}
		}

		public void ClearTrace(Player[] players)
		{
			foreach (var node in Nodes)
			{
				node.WriteValue.Min = int.MinValue/2;
				node.WriteValue.Max = int.MaxValue/2;
			}

			for (int i = 0; i < 3; i++)
			{
				playerStartNodes[i].WriteValue.Min = playerStartNodes[i].WriteValue.Max = players[i].Start;
			}
		}

		public GameState(Player[] players)
		{
			nodes.Push(new List<VNode<ExpressionNode, ExpressionPath>>());

			playerNodes.Push(new VNode<ExpressionNode, ExpressionPath>[3]);
			for (int i = 0; i < 3; i++)
			{
				var node = _graph.AddNode(new ExpressionNode() { Id = i, Min = players[i].Start, Max = players[i].Start, Comment = "S("+ i.ToString() +")" });
				nodes.Peek().Add(node);
				playerStartNodes[i] = node;
				playerNodes.Peek()[i] = node;
			}
			nodesCount = 3;
		}

		public GameState StartTransaction()
		{
			_graph.StartTransaction();
			nodes.Push(new List<VNode<ExpressionNode, ExpressionPath>>());
			playerNodes.Push( (VNode<ExpressionNode, ExpressionPath>[])playerNodes.Peek().Clone());
			return this;
		}

		public void Dispose()
		{
			_graph.Rollback();

			nodesCount -= nodes.Pop().Count;
			playerNodes.Pop();
		}

		public int Max
		{
			get
			{
				int max = Int32.MinValue;
				foreach (var node in Nodes)
				{
					if (max < node.ReadValue.Max)
						max = node.ReadValue.Max;
				}

				return max;
			}
		}

		public VNode<ExpressionNode, ExpressionPath> AddPlayerNode(int i, string comment)
		{
			var nodeValue = new ExpressionNode() { Id = nodesCount++ };
			nodeValue.Comment = comment;
			var node = _graph.AddNode(nodeValue);
			nodes.Peek().Add(node);
			playerNodes.Peek()[i] = node;
			return node;
		}

		public VNode<ExpressionNode, ExpressionPath> GetPlayerNode(int i)
		{
			return playerNodes.Peek()[i];
		}

		public VNode<ExpressionNode, ExpressionPath> GetPlayerStartNode(int i)
		{
			return playerStartNodes[i];
		}

		//a <= b + c
		public bool AddMin(VNode<ExpressionNode, ExpressionPath> a, VNode<ExpressionNode, ExpressionPath> b, int c)
		{
			var path = new ExpressionPath() { Mark = c };
			_graph.AddEdge(b, a, path);

			if (a.ReadValue.Max > b.ReadValue.Max + c)
				a.WriteValue.Max = b.ReadValue.Max + c;

			if (b.ReadValue.Min < a.ReadValue.Min - c)
				b.WriteValue.Min = a.ReadValue.Min - c;

			if (!Trace(a))
				return false;
			if (!Trace(b))
				return false;
			if (!Validate())
				return false;

			return true;
		}

		bool Trace(VNode<ExpressionNode, ExpressionPath> a)
		{
			if (!TraceMin(this, a))
				return false;
			if (!TraceMax(this, a))
				return  false;
			return true;
		}

		static bool TraceMin(GameState state, VNode<ExpressionNode, ExpressionPath> x)
		{
			x.WriteValue.Traced = true;

			try
			{
				foreach (var vector in state.Maximize(x))
				{
					// x <= path.Max + path.Mark

					if (vector.Target.ReadValue.Traced)
					{
						if (vector.Target.ReadValue.Min < x.ReadValue.Min - vector.Mark)
							return false;
					}
					else
					{
						if (vector.Target.ReadValue.Min < x.ReadValue.Min - vector.Mark)
						{
							vector.Target.WriteValue.Min = x.ReadValue.Min - vector.Mark;
							if (!TraceMin(state, vector.Target))
								return false;
						}
					}
				}
				return true;
			}
			finally
			{
				x.WriteValue.Traced = false;
			}
		}

		static bool TraceMax(GameState state, VNode<ExpressionNode, ExpressionPath> x)
		{
			x.WriteValue.Traced = true;

			try
			{
				foreach (var vector in state.Minimize(x))
				{
					if (vector.Target.ReadValue.Traced)
					{
						if (vector.Target.ReadValue.Max > x.ReadValue.Max + vector.Mark)
							return false;
					}
					else
					{
						if (vector.Target.ReadValue.Max > x.ReadValue.Max + vector.Mark)
						{
							vector.Target.WriteValue.Max = x.ReadValue.Max + vector.Mark;
							if (!TraceMax(state, vector.Target))
								return false;
						}
					}
				}
				return true;
			}
			finally
			{
				x.WriteValue.Traced = false;
			}
		}

		public IEnumerable<Vector> Maximize(VNode<ExpressionNode, ExpressionPath> a)
		{
			return a.Ins.Select(path => new Vector(path.Value.Mark, path.Source));
		}

		public IEnumerable<Vector> Minimize(VNode<ExpressionNode, ExpressionPath> a)
		{
			return a.Outs.Select(path => new Vector(path.Value.Mark, path.Target));
		}

		public bool Validate()
		{
			foreach (var node in Nodes)
			{
				if (node.ReadValue.Min > node.ReadValue.Max)
					return false;
			}

			return true;
		}

		public override string ToString()
		{
			string result = "";

			foreach (var node in Nodes.Reverse())
			{
				result += node.ReadValue.ToString();
			}

			return result;
		}
	}

	[Serializable]
	struct Vector
	{
		public int Mark;
		public VNode<ExpressionNode, ExpressionPath> Target;

		public Vector(int mark, VNode<ExpressionNode, ExpressionPath> target)
		{
			Mark = mark;
			Target = target;
		}
	}

	[Serializable]
	internal class Player
	{
		public int Start;
		public int Walk;
		public int Throws;

		public bool alreadyWalked = false;
		public bool alreadyUpped = false;
		public bool alreadyThrowed = false;
		public bool Upped = false;
		public int Up = -1;
	}

	[Serializable]
	class ExpressionNode : ICloneable
	{
		public int Id;
		public int Min = int.MinValue/2;
		public int Max = int.MaxValue/2;
		public bool Traced = false;
		public string Comment;

		public object Clone()
		{
			return this.MemberwiseClone();
		}

		public override string ToString()
		{
			return Comment + String.Format("[{0}:{1}]", Min, Max);
		}

	}

	[Serializable]
	[ReadOnly(true)]
	struct ExpressionPath
	{
		public int Mark;

		public override string ToString()
		{
			var result = String.Format("({0})", Mark);
			return result;
		}
	}

	class Program
	{
		//static StreamReader inStream = new StreamReader("input.txt");
		//static string ReadLine()
		//{
		//    return inStream.ReadLine();
		//}

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

		static int AbsoluteMax = int.MinValue;
		static string AbsoluteMaxStr = "";

		static void Main(string[] args)
		{
			Player[] players = new Player[3];
			for (int i = 0; i < 3; i++)
			{
				players[i] = new Player();
				string[] arg = ReadLine().Split();
				players[i].Start = int.Parse(arg[0]);
				players[i].Walk = int.Parse(arg[1]);
				players[i].Throws = int.Parse(arg[2]);
			}

			var state = new GameState(players);

			Solve(state, players);
			Console.WriteLine(AbsoluteMax);
			//Console.WriteLine(AbsoluteMaxStr);
		}

		static void Solve(GameState state, Player[] players)
		{
			if (EuristicGetMax(state, players) <= AbsoluteMax)
				return;

			int max = state.Max;
			if (AbsoluteMax < max)
			{
				AbsoluteMax = max;
				AbsoluteMaxStr = state.ToString();
			}

			for (int i = 0; i < 3; i++)
			{
				using (var clone = state.StartTransaction())
				{
					DoMove(i, clone, players);
				}
			}

			for (int i = 0; i < 3; i++)
				for (int j = 0; j < 3; j++)
					if (i != j)
					{
						using (var clone = state.StartTransaction())
						{
							DoUp(i, j, clone, players);
						}
					}

			for (int i = 0; i < 3; i++)
			{
				using (var clone = state.StartTransaction())
				{
					DoThrow(i, clone, players);
				}
			}
		}

		static private void DoMove(int i, GameState state, Player[] players)
		{
			if (players[i].alreadyWalked || players[i].Up >= 0 || players[i].Upped)
				return;

			players[i].alreadyWalked = true;

			VNode<ExpressionNode, ExpressionPath> a = state.GetPlayerNode(i);
			VNode<ExpressionNode, ExpressionPath> moved = state.AddPlayerNode(i, string.Format("M({0})", i));

			if (!state.AddMin(moved, a, players[i].Walk))
				return;
			if (!state.AddMin(a, moved, players[i].Walk))
				return;

			using (var clone = state.StartTransaction())
			{
				NotEqual(players, i, clone);
			}

			players[i].alreadyWalked = false;
		}

		private static void DoThrow(int i, GameState state, Player[] players)
		{
			if (players[i].alreadyThrowed || players[i].Up < 0 || players[i].Upped)
				return;

			players[i].alreadyThrowed = true;

			int j = players[i].Up;
			players[i].Up = -1;
			players[j].Upped = false;

			VNode<ExpressionNode, ExpressionPath> a = state.GetPlayerNode(i);
			VNode<ExpressionNode, ExpressionPath> moved = state.AddPlayerNode(j, string.Format("T({0}, {1})", i, j));

			if (!state.AddMin(moved, a, players[i].Throws))
				return;
			if (!state.AddMin(a, moved, players[i].Throws))
				return;

			NotEqual(players, j, state);

			players[j].Upped = true;
			players[i].Up = j;
			players[i].alreadyThrowed = false;
		}

		private static void DoUp(int i, int j, GameState state, Player[] players)
		{
			if (players[i].alreadyUpped || players[i].Up >= 0 || players[i].Upped || players[j].Upped || i == j)
				return;

			players[i].alreadyUpped = true;
			players[i].Up = j;
			players[j].Upped = true;

			VNode<ExpressionNode, ExpressionPath> a = state.GetPlayerNode(i);
			VNode<ExpressionNode, ExpressionPath> b = state.GetPlayerNode(j);

			VNode<ExpressionNode, ExpressionPath> moved = state.AddPlayerNode(j, string.Format("U({0}, {1})", i, j));

			if (!state.AddMin(moved, a, 0))
				return;
			if (!state.AddMin(a, moved, 0))
				return;

			Equal(state, players, a, b, 1);
			Equal(state, players, a, b, -1);

			players[j].Upped = false;
			players[i].Up = -1;
			players[i].alreadyUpped = false;
		}

		//a = b + c
		private static void Equal(GameState state, Player[] players, VNode<ExpressionNode, ExpressionPath> a, VNode<ExpressionNode, ExpressionPath> b, int c)
		{
			using (var v1 = state.StartTransaction())
			{
				if (v1.AddMin(b, a, -c) && v1.AddMin(a, b, c))
					Solve(v1, players);
			}
		}

		static private void NotEqual(Player[] players, int i, GameState state)
		{
			VNode<ExpressionNode, ExpressionPath> a = state.GetPlayerNode(i); //current
			VNode<ExpressionNode, ExpressionPath> b = state.GetPlayerNode((i + 1) % 3); //not equal to
			VNode<ExpressionNode, ExpressionPath> c = state.GetPlayerNode((i + 2) % 3); //and not equal to

			using (var v1 = state.StartTransaction())
			{
				if (v1.AddMin(a, b, -1) && v1.AddMin(a, c, -1))
					Solve(v1, players);
			}

			using (var v2 = state.StartTransaction())
			{
				if (v2.AddMin(b, a, -1) && v2.AddMin(a, c, -1))
					Solve(v2, players);
			}

			using (var v3 = state.StartTransaction())
			{
				if (v3.AddMin(b, a, -1) && v3.AddMin(c, a, -1))
					Solve(v3, players);
			}

			using (var v4 = state.StartTransaction())
			{
				if (v4.AddMin(a, b, -1) && v4.AddMin(c, a, -1))
					Solve(v4, players);
			}
		}

		static int EuristicGetMax(GameState state, Player[] players)
		{
			int radius = 0;

			for (int i = 0; i < 3; i++)
			{
				if (!players[i].alreadyThrowed)
					radius += players[i].Throws;
				if (!players[i].alreadyWalked)
					radius += players[i].Walk;
				if (!players[i].alreadyUpped)
					radius += 1;
			}

			var result = Enumerable.Range(0,3).Max(i => state.GetPlayerNode(i).ReadValue.Max + radius);
			return result;
		}
	}

}


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
//using DebugerVisualizer;

namespace _105
{

	class Program
	{
		//static StreamReader inStream = new StreamReader("input.txt");
		//static string ReadLine()
		//{
		//    return inStream.ReadLine();
		//}

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

		static int AbsoluteMax = int.MinValue;
		static string AbsoluteMaxStr = "";

		static void Main(string[] args)
		{
			Player[] players = new Player[3];
			for (int i = 0; i < 3; i++)
			{
				players[i] = new Player();
				string[] arg = ReadLine().Split();
				players[i].Start = int.Parse(arg[0]);
				players[i].Walk = int.Parse(arg[1]);
				players[i].Throws = int.Parse(arg[2]);
			}

			var state = new GameState(players);

			Solve(state, players);
			Console.WriteLine(AbsoluteMax);
			//Console.WriteLine(AbsoluteMaxStr);
		}

		static void Solve(GameState state, Player[] players)
		{
			state.ClearTrace();
			for (int i = 0; i < 3; i++)
			{
				if (!TraceMin(state, state.GetPlayerStartNode(i)))
					return;
				if (!TraceMax(state, state.GetPlayerStartNode(i)))
					return;
			}

			if (!state.Validate())
				return;

			if (EuristicGetMax(state, players) <= AbsoluteMax)
				return;

			int max = state.Max;
			if (AbsoluteMax < max)
			{
				AbsoluteMax = max;
				AbsoluteMaxStr = state.ToString();
			}

			for (int i = 0; i < 3; i++)
			{
				DoMove(i, state.Clone(), players);
			}

			for (int i = 0; i < 3; i++)
				for (int j = 0; j < 3; j++)
					if (i != j)
					{
						DoUp(i, j, state.Clone(), players);
					}

			for (int i = 0; i < 3; i++)
			{
				DoThrow(i, state.Clone(), players);
			}
		}

		static private void DoMove(int i, GameState state, Player[] players)
		{
			if (players[i].alreadyWalked || players[i].Up >= 0 || players[i].Upped)
				return;

			players[i].alreadyWalked = true;

			ExpressionNode a = state.GetPlayerNode(i);
			ExpressionNode moved = state.AddPlayerNode(i);

			moved.Comment = string.Format("M({0})", i);

			state.AddMin(moved, a, players[i].Walk);
			state.AddMin(a, moved, players[i].Walk);

			NotEqual(players, i, state.Clone());

			players[i].alreadyWalked = false;
		}

		private static void DoThrow(int i, GameState state, Player[] players)
		{
			if (players[i].alreadyThrowed || players[i].Up < 0 || players[i].Upped)
				return;

			players[i].alreadyThrowed = true;

			int j = players[i].Up;
			players[i].Up = -1;
			players[j].Upped = false;

			ExpressionNode a = state.GetPlayerNode(i);

			ExpressionNode moved = state.AddPlayerNode(j);
			moved.Comment = string.Format("T({0}, {1})", i, j);

			state.AddMin(moved, a, players[i].Throws);
			state.AddMin(a, moved, players[i].Throws);

			NotEqual(players, j, state.Clone());

			players[j].Upped = true;
			players[i].Up = j;
			players[i].alreadyThrowed = false;
		}

		private static void DoUp(int i, int j, GameState state, Player[] players)
		{
			if (players[i].alreadyUpped || players[i].Up >= 0 || players[i].Upped || players[j].Upped || i == j)
				return;

			players[i].alreadyUpped = true;
			players[i].Up = j;
			players[j].Upped = true;

			ExpressionNode a = state.GetPlayerNode(i);
			ExpressionNode b = state.GetPlayerNode(j);

			ExpressionNode moved = state.AddPlayerNode(j);
			moved.Comment = string.Format("U({0}, {1})", i, j);

			state.AddMin(moved, a, 0);
			state.AddMin(a, moved, 0);

			var v1 = state.Clone();
			v1.AddMin(a, b, -1);
			v1.AddMin(b, a, 1);
			Solve(v1, players);

			var v2 = state;
			v2.AddMin(a, b, 1);
			v2.AddMin(b, a, -1);
			Solve(v2.Clone(), players);

			players[j].Upped = false;
			players[i].Up = -1;
			players[i].alreadyUpped = false;
		}

		static private void NotEqual(Player[] players, int i, GameState state)
		{
			ExpressionNode a = state.GetPlayerNode(i); //current
			ExpressionNode b = state.GetPlayerNode((i + 1) % 3); //not equal to
			ExpressionNode c = state.GetPlayerNode((i + 2) % 3); //and not equal to

			var v1 = state.Clone();
			v1.AddMin(a, b, -1);
			v1.AddMin(a, c, -1);
			Solve(v1, players);

			var v2 = state.Clone();
			v2.AddMin(b, a, -1);
			v2.AddMin(a, c, -1);
			Solve(v2, players);

			var v3 = state.Clone();
			v3.AddMin(b, a, -1);
			v3.AddMin(c, a, -1);
			Solve(v3, players);

			var v4 = state;
			v4.AddMin(a, b, -1);
			v4.AddMin(c, a, -1);
			Solve(v4, players);
		}

		static bool TraceMin(GameState state, ExpressionNode x)
		{
			x.Traced = true;

			try
			{
				foreach (var vector in state.Maximize(x))
				{
					// x <= path.Max + path.Mark

					if (vector.Target.Traced)
					{
						if (vector.Target.Min < x.Min - vector.Mark)
							return false;
					}
					else
					{
						if (vector.Target.Min < x.Min - vector.Mark)
						{
							vector.Target.Min = x.Min - vector.Mark;
							if (!TraceMin(state, vector.Target))
								return false;
						}
					}
				}
				return true;
			}
			finally
			{
				x.Traced = false;
			}
		}

		static bool TraceMax(GameState state, ExpressionNode x)
		{
			x.Traced = true;

			try
			{
				foreach (var vector in state.Minimize(x))
				{
					if (vector.Target.Traced)
					{
						if (vector.Target.Max > x.Max + vector.Mark)
							return false;
					}
					else
					{
						if (vector.Target.Max > x.Max + vector.Mark)
						{
							vector.Target.Max = x.Max + vector.Mark;
							if (!TraceMax(state, vector.Target))
								return false;
						}
					}
				}
				return true;
			}
			finally
			{
				x.Traced = false;
			}
		}

		static int EuristicGetMax(GameState state, Player[] players)
		{
			int radius = 0;

			for (int i = 0; i < 3; i++)
			{
				if (!players[i].alreadyThrowed)
					radius += players[i].Throws;
				if (!players[i].alreadyWalked)
					radius += players[i].Walk;
				if (!players[i].alreadyUpped)
					radius += 1;
			}

			var result = Enumerable.Range(0,2).Max(i => state.GetPlayerNode(i).Max + radius);
			return result;
		}
	}

	[Serializable]
	struct Vector
	{
		public int Mark;
		public ExpressionNode Target;

		public Vector(int mark, ExpressionNode target)
		{
			Mark = mark;
			Target = target;
		}
	}

	//[DebuggerVisualizer(typeof(ExpressionBuilderVisualizer))]
	[Serializable]
	class GameState
	{
		const int MaxVariables = 20;
		const int MaxDepth = 20;

		List<ExpressionNode> nodes = new List<ExpressionNode>();
		int[] playerNodes = new int[3];

		public List<ExpressionNode> Nodes
		{
			get { return nodes; }
		}

		private GameState()
		{
		}

		public void ClearTrace()
		{
			for (int i = 3; i < nodes.Count; i++)
			{
				nodes[i].Min = int.MinValue;
				nodes[i].Max = int.MaxValue;
			}
		}

		public GameState(Player[] players)
		{
			for (int i = 0; i < 3; i++)
			{
				nodes.Add(
					new ExpressionNode()
					{
						Id = i,
						Min = players[i].Start,
						Max = players[i].Start
					});
				playerNodes[i] = i;
			}
		}

		public GameState Clone()
		{
			var result = new GameState();
			result.nodes  = nodes.ConvertAll(x => x.Clone());
			result.playerNodes = (int[])playerNodes.Clone();
			return result;
		}

		public int Max
		{
			get
			{
				int max = Int32.MinValue;
				foreach (var node in nodes)
				{
					if (max < node.Max)
						max = node.Max;
				}

				return max;
			}
		}

		public ExpressionNode AddPlayerNode(int i)
		{
			var node = new ExpressionNode() { Id = nodes.Count };
			nodes.Add(node);
			playerNodes[i] = node.Id;
			return node;
		}

		public ExpressionNode GetPlayerNode(int i)
		{
			return nodes[playerNodes[i]];
		}

		public ExpressionNode GetPlayerStartNode(int i)
		{
			return nodes[i];
		}

		//a <= b + c
		public void AddMin(ExpressionNode a, ExpressionNode b, int c)
		{
			var path = new ExpressionPath() { MinId = a.Id, MaxId = b.Id, Mark = c };
			nodes[a.Id].Maximize.Add(path);
			nodes[b.Id].Minimize.Add(path);
		}

		public IEnumerable<Vector> Maximize(ExpressionNode a)
		{
			return nodes[a.Id].Maximize.Select(path => new Vector(path.Mark, nodes[path.MaxId]));
		}

		public IEnumerable<Vector> Minimize(ExpressionNode a)
		{
			return nodes[a.Id].Minimize.Select(path => new Vector(path.Mark, nodes[path.MinId]));
		}

		public bool Validate()
		{
			foreach (var node in nodes)
			{
				if (node.Min > node.Max)
					return false;

				if (node.Min == Int32.MinValue || node.Min == Int32.MaxValue)
					throw new Exception();
				if (node.Max == Int32.MinValue || node.Max == Int32.MaxValue)
					throw new Exception();
			}

			return true;
		}

		public override string ToString()
		{
			string result = "";

			foreach (var node in nodes)
			{
				result += node.ToString();
			}

			return result;
		}
	}

	[Serializable]
	internal class Player
	{
		public int Start;
		public int Walk;
		public int Throws;

		public bool alreadyWalked = false;
		public bool alreadyUpped = false;
		public bool alreadyThrowed = false;
		public bool Upped = false;
		public int Up = -1;

		public Player Clone()
		{
			var result = (Player)this.MemberwiseClone();
			return result;
		}
	}

	[Serializable]
	class ExpressionNode
	{
		public int Id;
		public List<ExpressionPath> Minimize = new List<ExpressionPath>();
		public List<ExpressionPath> Maximize = new List<ExpressionPath>();

		public int Min = Int32.MinValue;
		public int Max = Int32.MaxValue;

		public bool Traced = false;

		public string Comment;

		public ExpressionNode Clone()
		{
			var result = (ExpressionNode)this.MemberwiseClone();
			result.Minimize = new List<ExpressionPath>(Minimize);
			result.Maximize = new List<ExpressionPath>(Maximize);
			result.Minimize = Minimize.ConvertAll(x => x);
			result.Maximize = Maximize.ConvertAll(x => x);

			return result;
		}

		public override string ToString()
		{
			return Comment + String.Format("[{0}:{1}]", Min, Max);
		}

	}

	[Serializable]
	[ReadOnly(true)]
	struct ExpressionPath
	{
		public int MaxId;
		public int MinId;
		public int Mark;

		public override string ToString()
		{
			var result = String.Format("X{0} <= X{1}", MinId, MaxId);

			if (Mark > 0)
				result += string.Format(" + {0}", Mark);
			else if (Mark < 0)
				result += string.Format(" - {0}", -Mark);

			return result;
		}
	}
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
//using DebugerVisualizer;

namespace _105
{

    class Program
    {
        //static StreamReader inStream = new StreamReader("input.txt");
        //static string ReadLine()
        //{
        //    return inStream.ReadLine();
        //}

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

        static int AbsoluteMax = int.MinValue;
        static string AbsoluteMaxStr = "";

        static void Main(string[] args)
        {
            Player[] players = new Player[3];
            for (int i = 0; i < 3; i++)
            {
                players[i] = new Player();
                string[] arg = ReadLine().Split();
                players[i].Start = int.Parse(arg[0]);
                players[i].Walk = int.Parse(arg[1]);
                players[i].Throws = int.Parse(arg[2]);
                players[i].StartNode = new ExpressionNode();
                players[i].StartNode.Comment = string.Format("S({0})", i);
            }

            var builder = new ExpressionBuilder(Array.ConvertAll(players, x => x.StartNode));
            Solve(builder, Array.ConvertAll(players, x => x.StartNode), players);
            Console.WriteLine(AbsoluteMax);
            //Console.WriteLine(AbsoluteMaxStr);
        }

        static void Solve(ExpressionBuilder builder, ExpressionNode[] pNodes, Player[] players)
        {
            builder.ClearCalcs();

            for (int i = 0; i < 3; i++)
                players[i].StartNode.Min = players[i].StartNode.Max = players[i].Start;

            for (int i = 0; i < 3; i++)
            {
                if (!TraceMin(players[i].StartNode))
                    return;
                if (!TraceMax(players[i].StartNode))
                    return;
            }

            if (!builder.Validate())
                return;

            int max = builder.Max;
            if (AbsoluteMax < max)
            {
                AbsoluteMax = max;
                AbsoluteMaxStr = builder.ToString();
            }

            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                    if (i != j)
                    {
                        DoUp(i, j, builder, pNodes, players);
                    }

            for (int i = 0; i < 3; i++)
            {
                DoMove(i, builder, pNodes, players);
            }

            for (int i = 0; i < 3; i++)
            {
                DoThrow(i, builder, pNodes, players);
            }
        }

        static private void DoMove(int i, ExpressionBuilder builder, ExpressionNode[] pNodes, Player[] players)
        {
            if (players[i].alreadyWalked || players[i].Up >= 0 || players[i].Upped)
                return;

            players[i].alreadyWalked = true;

            ExpressionNode a = pNodes[i];

            builder.Start();

            ExpressionNode moved = builder.AddNode();
            pNodes[i] = moved;
            moved.Comment = string.Format("M({0})", i);

            builder.AddMin(moved, a, players[i].Walk);
            builder.AddMin(a, moved, players[i].Walk);

            NotEqual(players, i, builder, pNodes);

            builder.Rollback();
            pNodes[i] = a;
            players[i].alreadyWalked = false;
        }

        private static void DoThrow(int i, ExpressionBuilder builder, ExpressionNode[] pNodes, Player[] players)
        {
            if (players[i].alreadyThrowed || players[i].Up < 0 || players[i].Upped)
                return;

            players[i].alreadyThrowed = true;

            int j = players[i].Up;
            players[i].Up = -1;
            players[j].Upped = false;

            ExpressionNode a = pNodes[i];
            ExpressionNode b = pNodes[j];

            builder.Start();

            ExpressionNode moved = builder.AddNode();
            pNodes[j] = moved;
            moved.Comment = string.Format("T({0}, {1})", i, j);

            builder.AddMin(moved, a, players[i].Throws);
            builder.AddMin(a, moved, players[i].Throws);

            NotEqual(players, j, builder, pNodes);

            builder.Rollback();
            pNodes[j] = b;
            players[j].Upped = true;
            players[i].Up = j;
            players[i].alreadyThrowed = false;
        }

        private static void DoUp(int i, int j, ExpressionBuilder builder, ExpressionNode[] pNodes, Player[] players)
        {
            if (players[i].alreadyUpped || players[i].Up >= 0 || players[i].Upped || players[j].Upped || i == j)
                return;

            players[i].alreadyUpped = true;
            players[i].Up = j;
            players[j].Upped = true;

            ExpressionNode a = pNodes[i];
            ExpressionNode b = pNodes[j];

            builder.Start();

            ExpressionNode moved = builder.AddNode();
            pNodes[j] = moved;
            moved.Comment = string.Format("U({0}, {1})", i, j);

            builder.AddMin(moved, a, 0);
            builder.AddMin(a, moved, 0);

            builder.Start();
            builder.AddMin(a, b, -1);
            builder.AddMin(b, a, 1);
            Solve(builder, pNodes, players);
            builder.Rollback();

            builder.Start();
            builder.AddMin(a, b, 1);
            builder.AddMin(b, a, -1);
            Solve(builder, pNodes, players);
            builder.Rollback();

            builder.Rollback();
            pNodes[j] = b;
            players[j].Upped = false;
            players[i].Up = -1;
            players[i].alreadyUpped = false;
        }

        static private void NotEqual(Player[] players, int i, ExpressionBuilder builder, ExpressionNode[] pNodes)
        {
            ExpressionNode a = pNodes[i]; //current
            ExpressionNode b = pNodes[(i + 1) % 3]; //not equal to
            ExpressionNode c = pNodes[(i + 2) % 3]; //and not equal to

            builder.Start();
            builder.AddMin(a, b, -1);
            builder.AddMin(a, c, -1);
            Solve(builder, pNodes, players);
            builder.Rollback();

            builder.Start();
            builder.AddMin(b, a, -1);
            builder.AddMin(a, c, -1);
            Solve(builder, pNodes, players);
            builder.Rollback();

            builder.Start();
            builder.AddMin(b, a, -1);
            builder.AddMin(c, a, -1);
            Solve(builder, pNodes, players);
            builder.Rollback();

            builder.Start();
            builder.AddMin(a, b, -1);
            builder.AddMin(c, a, -1);
            Solve(builder, pNodes, players);
            builder.Rollback();
        }

        static bool TraceMin(ExpressionNode x)
        {
            x.Traced = true;

            try
            {
                foreach (var path in x.Maximize)
                {
                    // x <= path.Max + path.Mark

                    if (path.Max.Traced)
                    {
                        if (path.Max.Min < x.Min - path.Mark)
                            return false;
                    }
                    else
                    {
                        if (path.Max.Min < x.Min - path.Mark)
                        {
                            path.Max.Min = x.Min - path.Mark;
                            if (!TraceMin(path.Max))
                                return false;
                        }
                    }
                }
                return true;
            }
            finally
            {
                x.Traced = false;
            }
        }

        static bool TraceMax(ExpressionNode x)
        {
            x.Traced = true;

            try
            {
                foreach (var path in x.Minimize)
                {
                    if (path.Min.Traced)
                    {
                        if (path.Min.Max > x.Max + path.Mark)
                            return false;
                    }
                    else
                    {
                        if (path.Min.Max > x.Max + path.Mark)
                        {
                            path.Min.Max = x.Max + path.Mark;
                            if (!TraceMax(path.Min))
                                return false;
                        }
                    }
                }
                return true;
            }
            finally
            {
                x.Traced = false;
            }
        }
    }

    //[DebuggerVisualizer(typeof(ExpressionBuilderVisualizer))]
    [Serializable]
    class ExpressionBuilder
    {
        Stack<Actions> actions = new Stack<Actions>();
        Actions current = null;
        List<ExpressionNode> nodes = new List<ExpressionNode>();
        List<ExpressionPath> paths = new List<ExpressionPath>();

        public List<ExpressionNode> Nodes
        {
            get { return nodes; }
        }

        public List<ExpressionPath> Paths
        {
            get { return paths; }
        }

        public ExpressionBuilder(IEnumerable<ExpressionNode> startNodes)
        {
            nodes.AddRange(startNodes);
        }

        public int Max
        {
            get
            {
                int max = Int32.MinValue;
                foreach (var node in nodes)
                {
                    if (max < node.Max)
                        max = node.Max;
                }

                return max;
            }
        }

        public ExpressionNode AddNode()
        {
            var node = new ExpressionNode();
            nodes.Add(node);
            current.Nodes.Add(node);
            return node;
        }

        //a <= b + c
        public void AddMin(ExpressionNode a, ExpressionNode b, int c)
        {
            var path = new ExpressionPath() { Min = a, Max = b, Mark = c };
            paths.Add(path);
            a.Maximize.Add(path);
            b.Minimize.Add(path);
            current.Paths.Add(path);
        }

        public void Start()
        {
            current = new Actions();
            actions.Push(current);
        }

        public void Rollback()
        {
            RollbackActions(current);
            actions.Pop();
            if (actions.Count > 0)
                current = actions.Peek();
            else
                current = null;
        }

        private void RollbackActions(Actions action)
        {
            //int nc = nodes.Count;
            //int pc = paths.Count;

            if (action.Paths.Count > 0)
                paths.RemoveRange(paths.Count - action.Paths.Count, action.Paths.Count);
            if (action.Nodes.Count > 0)
                nodes.RemoveRange(nodes.Count - action.Nodes.Count, action.Nodes.Count);

            //Debug.Assert(!paths.Exists(x => action.Paths.Contains(x)));
            //Debug.Assert(!nodes.Exists(x => action.Nodes.Contains(x)));

            //System.Diagnostics.Debug.Assert(paths.Count == pc - action.Paths.Count);
            //System.Diagnostics.Debug.Assert(nodes.Count == nc - action.Nodes.Count);

            foreach (var p in action.Paths)
            {
                p.Max.Minimize.Remove(p);
                p.Min.Maximize.Remove(p);
            }
        }

        public void ClearCalcs()
        {
            foreach (var node in nodes)
            {
                node.Min = Int32.MinValue;
                node.Max = Int32.MaxValue;
                node.Traced = false;
            }
        }

        public bool Validate()
        {
            foreach (var node in nodes)
            {
                if (node.Min > node.Max)
                    return false;

                if (node.Min == Int32.MinValue || node.Min == Int32.MaxValue)
                    throw new Exception();
                if (node.Max == Int32.MinValue || node.Max == Int32.MaxValue)
                    throw new Exception();
            }

            return true;
        }

        public override string ToString()
        {
            string result = "";

            foreach (var node in nodes)
            {
                result += node.ToString();
            }

            result += "{";
            foreach (var path in paths)
            {
                result += String.Format("{0} <= {1} + {2}; ", path.Min, path.Max, path.Mark);
            }
            result += "}";

            return result;
        }
    }

    [Serializable]
    class Actions
    {
        public List<ExpressionNode> Nodes = new List<ExpressionNode>(10);
        public List<ExpressionPath> Paths = new List<ExpressionPath>(10);
    }

    [Serializable]
    internal class Player
    {
        public int Start;
        public int Walk;
        public int Throws;

        public bool alreadyWalked = false;
        public bool alreadyUpped = false;
        public bool alreadyThrowed = false;
        public bool Upped = false;
        public int Up = -1;
        public ExpressionNode StartNode;
    }

    [Serializable]
    class ExpressionNode
    {
        public List<ExpressionPath> Minimize = new List<ExpressionPath>(10);
        public List<ExpressionPath> Maximize = new List<ExpressionPath>(10);

        public int Min = Int32.MinValue;
        public int Max = Int32.MaxValue;

        public bool Traced = false;

        public string Comment;

        public override string ToString()
        {
            return Comment + String.Format("[{0}:{1}]", Min, Max);
        }
    }

    [Serializable]
    internal class ExpressionPath
    {
        public ExpressionNode Max;
        public ExpressionNode Min;
        public int Mark;

        public override string ToString()
        {
            return  String.Format("{0} <= {1} + {2}", Min, Max, Mark);
        }
    }
}


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

class Program
{
    long maxK = 1000;
    long maxPrime = 2 * 1000000 + 10;
    int[] minDiv;
    List<long> primes = new List<long>();
    void solve()
    {
        getDiv();
        long a = nextLong();
        long b = nextLong();
        long k = nextLong();
        long res = get(b, k);
        res -= get(a - 1, k);
        println(res);

    }

    private void getDiv()
    {
        minDiv = new int[maxPrime];
        for (int i = 2; i < minDiv.Length; i++)
            minDiv[i] = i;
        for (int i = 2; i < minDiv.Length; i++)
            if (minDiv[i] == i)
                for (int j = 2 * i; j < minDiv.Length; j += i)
                    if (minDiv[j] == j)
                        minDiv[j] = i;
    }

    private long get(long n, long k)
    {
        if (n <= 0)
            return 0;
        if (!prime(k))
            return 0;
        long res=0;
        if (k >= maxK)
        {

            if (k <= n)
                res++;
            for (long x = k; x * k <= n; x++)
                if (minDiv[x] >= k)
                    res++;
            return res;
        }
        else
        {
            for(int i=2;i<k;i++)
                if (minDiv[i] == i)
                {
                    primes.Add(i);
                }

            res =rec(0, n/k);
            res = n/k - res;
            primes = new List<long>();
        }
        return res;
    }

    private long rec(int at, long n)
    {
        if (at >= primes.Count)
            return 0;
        if (n < primes[at])
            return 0;
        long res = n / primes[at];
        res+=rec(at+1,n);
        res -= rec(at + 1, n / primes[at]);
        return res;

    }

    bool prime(long p)
    {
        for (int i = 2; i * i <= p; i++)
            if (p % i == 0)
                return false;
        return true;
    }
    ////////////
    private void println(int[] ar)
    {
        for (int i = 0; i < ar.Length; i++)
        {
            if (i == ar.Length - 1)
                println(ar[i]);
            else
                print(ar[i] + " ");
        }
    }
    private void println(int[] ar, bool add)
    {
        int A = 0;
        if (add)
            A++;
        for (int i = 0; i < ar.Length; i++)
        {
            if (i == ar.Length - 1)
                println(ar[i] + A);
            else
                print((ar[i] + A) + " ");
        }
    }

    private void println(string Stringst)
    {
        Console.WriteLine(Stringst);
    }
    private void println(char charnum)
    {
        Console.WriteLine(charnum);
    }
    private void println(int Intnum)
    {
        Console.WriteLine(Intnum);
    }
    private void println(long Longnum)
    {
        Console.WriteLine(Longnum);
    }
    private void println(double Doublenum)
    {
        string s = Doublenum.ToString(CultureInfo.InvariantCulture);
        Console.WriteLine(s);
    }

    private void print(string Stringst)
    {
        Console.Write(Stringst);
    }
    private void print(int Intnum)
    {
        Console.Write(Intnum);
    }
    private void print(char charnum)
    {
        Console.Write(charnum);
    }
    private void print(long Longnum)
    {
        Console.Write(Longnum);
    }
    private void print(double Doublenum)
    {
        Console.Write(Doublenum);
    }

    string[] inputLine = new string[0];
    int inputInd = 0;
    string nextLine()
    {
        return Console.ReadLine();
    }
    void readInput()
    {
        if (inputInd != inputLine.Length)
            throw new Exception();
        inputInd = 0;
        inputLine = Console.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        if (inputLine.Length == 0)
            readInput();

    }
    int nextInt()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return int.Parse(inputLine[inputInd++]);
    }
    long nextLong()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return long.Parse(inputLine[inputInd++]);
    }
    double nextDouble()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return double.Parse(inputLine[inputInd++]);
    }
    string nextString()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return inputLine[inputInd++];
    }
    static void Main(string[] args)
    {
        Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        new Program().solve();
    }
}


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

class Program
{

    void solve()
    {

    }

    ////////////
    private void println(int[] ar)
    {
        for (int i = 0; i < ar.Length; i++)
        {
            if (i == ar.Length - 1)
                println(ar[i]);
            else
                print(ar[i] + " ");
        }
    }
    private void println(int[] ar, bool add)
    {
        int A = 0;
        if (add)
            A++;
        for (int i = 0; i < ar.Length; i++)
        {
            if (i == ar.Length - 1)
                println(ar[i] + A);
            else
                print((ar[i] + A) + " ");
        }
    }

    private void println(string Stringst)
    {
        Console.WriteLine(Stringst);
    }
    private void println(char charnum)
    {
        Console.WriteLine(charnum);
    }
    private void println(int Intnum)
    {
        Console.WriteLine(Intnum);
    }
    private void println(long Longnum)
    {
        Console.WriteLine(Longnum);
    }
    private void println(double Doublenum)
    {
        string s = Doublenum.ToString(CultureInfo.InvariantCulture);
        Console.WriteLine(s);
    }

    private void print(string Stringst)
    {
        Console.Write(Stringst);
    }
    private void print(int Intnum)
    {
        Console.Write(Intnum);
    }
    private void print(char charnum)
    {
        Console.Write(charnum);
    }
    private void print(long Longnum)
    {
        Console.Write(Longnum);
    }
    private void print(double Doublenum)
    {
        Console.Write(Doublenum);
    }

    string[] inputLine = new string[0];
    int inputInd = 0;
    string nextLine()
    {
        return Console.ReadLine();
    }
    void readInput()
    {
        if (inputInd != inputLine.Length)
            throw new Exception();
        inputInd = 0;
        inputLine = Console.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        if (inputLine.Length == 0)
            readInput();

    }
    int nextInt()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return int.Parse(inputLine[inputInd++]);
    }
    long nextLong()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return long.Parse(inputLine[inputInd++]);
    }
    double nextDouble()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return double.Parse(inputLine[inputInd++]);
    }
    string nextString()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return inputLine[inputInd++];
    }
    static void Main(string[] args)
    {
        Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        new Program().solve();
    }
}


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
{
	internal class B
	{
		private int MOD = 1000000007;
		private int n;
		private long m;
		private int k;
		private int[,] dp;
		private bool[,] was;
		private int[,] bin;

		int go( int pos, int k )
		{
			if ( pos == n )
			{
				if ( k == 0 ) return 1;
				return 0;
			}
			if ( was[pos, k] )
				return dp[pos, k];
			int res = go( pos + 1, k );

			for ( int i = 1; i <= n && i <= k; ++i )
			{
				long cnt = ( ( ( ( m - pos ) % n ) == 0 ? ( m - pos ) / n - 1 : ( m - pos ) / n ) + 1 ) % MOD;
				res += pow( bin[n, i], cnt );
				res %= MOD;
			}

			was[pos, k] = true;
			return dp[pos, k] = res;
		}

		private int pow( int a, long 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;
		}

		private void Solve()
		{
			bin = new int[101, 101];
			for ( int i = 0; i <= 100; ++i )
			{
				bin[i, 0] = bin[i, i] = 1;
				for ( int j = 1; j < i; ++j ) bin[i, j] = ( bin[i - 1, j] + bin[i - 1, j - 1] ) % MOD;
			}
			n = NextInt();
			m = NextLong();
			k = NextInt();
			dp = new int[n, n * n + 1];
			was = new bool[n, n * n + 1];
			Out.WriteLine( go( 0, k ) );
		}

		#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, 20000000 );
			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 B().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.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Globalization;
using System.Collections.Generic;
using System.Threading;

namespace CodeForces
{
	internal class B
	{
		private int MOD = 1000000007;
		private int n;
		private long m;
		private int k;
		private int[,] dp;
		private bool[,] was;
		private int[,] bin;

		int go( int pos, int k )
		{
			if ( pos == n )
			{
				if ( k == 0 ) return 1;
				return 0;
			}
			if ( was[pos, k] )
				return dp[pos, k];
			int res = go( pos + 1, k );

			for ( int i = 1; i <= n && i <= k; ++i )
			{
				long cnt = ( ( ( m - pos ) % n ) == 0 ? ( m - pos ) / n - 1 : ( m - pos ) / n ) + 1;
				res += pow( bin[n, i], cnt );
				res %= MOD;
			}

			was[pos, k] = true;
			return dp[pos, k] = res;
		}

		private int pow( int a, long 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;
		}

		private void Solve()
		{
			bin = new int[101, 101];
			for ( int i = 0; i <= 100; ++i )
			{
				bin[i, 0] = bin[i, i] = 1;
				for ( int j = 1; j < i; ++j ) bin[i, j] = ( bin[i - 1, j] + bin[i - 1, j - 1] ) % MOD;
			}
			n = NextInt();
			m = NextLong();
			k = NextInt();
			dp = new int[n, n * n + 1];
			was = new bool[n, n * n + 1];
			Out.WriteLine( go( 0, k ) );
		}

		#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, 20000000 );
			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 B().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.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;

namespace Temp
{
    internal struct PointInt
    {
        public long X;

        public long Y;

        public PointInt(long x, long y)
            : this()
        {
            this.X = x;
            this.Y = y;
        }

        public PointInt(PointInt head)
            : this(head.X, head.Y)
        {
        }

        public static PointInt operator +(PointInt a, PointInt b)
        {
            return new PointInt(a.X + b.X, a.Y + b.Y);
        }

        public static PointInt operator -(PointInt a, PointInt b)
        {
            return new PointInt(a.X - b.X, a.Y - b.Y);
        }

        public static PointInt operator *(PointInt a, long k)
        {
            return new PointInt(k * a.X, k * a.Y);
        }

        public static PointInt operator *(long k, PointInt a)
        {
            return new PointInt(k * a.X, k * a.Y);
        }

        public bool IsInsideRectangle(long l, long b, long r, long t)
        {
            return (l <= X) && (X <= r) && (b <= Y) && (Y <= t);
        }
    }

    internal struct LineInt
    {
        public LineInt(PointInt a, PointInt b)
            : this()
        {
            A = a.Y - b.Y;
            B = b.X - a.X;
            C = a.X * b.Y - a.Y * b.X;
        }

        public long A, B, C;

        public bool ContainsPoint(PointInt p)
        {
            return A * p.X + B * p.Y + C == 0;
        }
    }

    internal static class Geometry
    {
        public static long VectInt(PointInt a, PointInt b)
        {
            return a.X * b.Y - a.Y * b.X;
        }

        public static long VectInt(PointInt a, PointInt b, PointInt c)
        {
            return (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X);
        }
    }

    internal class MatrixInt
    {
        private readonly long[,] m_Matrix;

        public int Size
        {
            get
            {
                return m_Matrix.GetLength(0);
            }
        }

        public long Mod { get; private set; }

        public MatrixInt(int size, long mod = 0)
        {
            m_Matrix = new long[size,size];
            Mod = mod;
        }

        public MatrixInt(long[,] matrix, long mod = 0)
        {
            this.m_Matrix = matrix;
            Mod = mod;

            for (int i = 0; i < Size; i++)
            {
                for (int j = 0; j < Size; j++)
                {
                    m_Matrix[i, j] %= mod;
                }
            }
        }

        public static MatrixInt GetIdentityMatrix(int size, long mod = 0)
        {
            long[,] matrix = new long[size,size];

            for (int i = 0; i < size; i++)
            {
                matrix[i, i] = 1;
            }

            return new MatrixInt(matrix, mod);
        }

        public long this[int i, int j]
        {
            get
            {
                return m_Matrix[i, j];
            }

            set
            {
                m_Matrix[i, j] = value;
            }
        }

        public static MatrixInt operator +(MatrixInt a, MatrixInt b)
        {
            int n = a.Size;
            long mod = Math.Max(a.Mod, b.Mod);
            long[,] c = new long[n,n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    c[i, j] = a[i, j] + b[i, j];
                }
            }

            if (mod > 0)
            {
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        c[i, j] %= mod;
                    }
                }
            }

            return new MatrixInt(c, mod);
        }

        public static MatrixInt operator *(MatrixInt a, MatrixInt b)
        {
            int n = a.Size;
            long mod = Math.Max(a.Mod, b.Mod);

            long[,] c = new long[n,n];

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    for (int k = 0; k < n; k++)
                    {
                        c[i, j] += a[i, k] * b[k, j];
                        if (mod > 0)
                        {
                            c[i, j] %= mod;
                        }
                    }
                }
            }

            return new MatrixInt(c, mod);
        }
    }

    public static class Permutations
    {
        public static int[] GetRandomPermutation(int n)
        {
            int[] p = new int[n];
            for (int i = 0; i < n; i++)
            {
                p[i] = i;
            }

            Random random = new Random();
            for (int i = n - 1; i > 0; i--)
            {
                int j = random.Next(i + 1);
                int tmp = p[i];
                p[i] = p[j];
                p[j] = tmp;
            }

            return p;
        }

        public static T[] Shuffle<T>(this T[] array)
        {
            int length = array.Length;
            int[] p = GetRandomPermutation(length);
            T[] result = new T[length];
            for (int i = 0; i < length; i++)
            {
                result[i] = array[p[i]];
            }

            return result;
        }
    }

    internal static class Algebra
    {
        public static long Phi(long n)
        {
            long result = n;
            for (long i = 2; i * i <= n; i++)
            {
                if (n % i == 0)
                {
                    while (n % i == 0)
                    {
                        n /= i;
                    }

                    result -= result / i;
                }
            }

            if (n > 1)
            {
                result -= result / n;
            }

            return result;
        }

        public static long BinPower(long a, long n, long mod)
        {
            long result = 1;

            while (n > 0)
            {
                if ((n & 1) != 0)
                {
                    result = (result * a) % mod;
                }

                a = (a * a) % mod;
                n >>= 1;
            }

            return result;
        }

        public static MatrixInt MatrixBinPower(MatrixInt a, long n)
        {
            MatrixInt result = MatrixInt.GetIdentityMatrix(a.Size, a.Mod);

            while (n > 0)
            {
                if ((n & 1) != 0)
                {
                    result *= a;
                }

                a *= a;
                n >>= 1;
            }

            return result;
        }

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

        public static long ExtendedGcd(long a, long b, out long x, out long y)
        {
            if (b == 0)
            {
                x = 1;
                y = 0;
                return a;
            }

            long x1;
            long y1;
            long d = ExtendedGcd(b, a % b, out x1, out y1);
            x = y1;
            y = x1 - (a / b) * y1;
            return d;
        }

        public static long Lcm(long a, long b)
        {
            return (a / Gcd(a, b)) * b;
        }

        public static bool[] GetPrimes(int n)
        {
            n = Math.Max(n, 2);
            bool[] prime = new bool[n + 1];
            for (int i = 2; i <= n; i++)
            {
                prime[i] = true;
            }

            for (int i = 2; i * i <= n; i++)
            {
                if (prime[i])
                {
                    if ((long)i * i <= n)
                    {
                        for (int j = i * i; j <= n; j += i)
                        {
                            prime[j] = false;
                        }
                    }
                }
            }

            return prime;
        }

        public static long GetFibonacciNumber(long n, long mod = 0)
        {
            long[,] matrix = new long[,] { { 0, 1 }, { 1, 1 } };

            MatrixInt result = MatrixBinPower(new MatrixInt(matrix, mod), n);

            return result[1, 1];
        }

        public static long[] GetFibonacciSequence(int n)
        {
            long[] result = new long[n];
            result[0] = result[1] = 1;

            for (int i = 2; i < n; i++)
            {
                result[i] = result[i - 1] + result[i - 2];
            }

            return result;
        }

        public static long GetInverseElement(long a, long mod)
        {
            long x, y;
            long g = ExtendedGcd(a, mod, out x, out y);

            if (g != 1)
            {
                return -1;
            }

            return ((x % mod) + mod) % mod;
        }

        public static long[] GetAllInverseElements(long mod)
        {
            long[] result = new long[mod];
            result[1] = 1;
            for (int i = 2; i < mod; i++)
            {
                result[i] = (mod - (((mod / i) * result[mod % i]) % mod)) % mod;
            }

            return result;
        }

        public static int GetMinimalPrimeDivisor(int n)
        {
            for (int i = 2; i * i <= n; i++)
            {
                if (n % i == 0)
                {
                    return i;
                }
            }

            return n;
        }

        public static long Sqr(long x)
        {
            return x * x;
        }

        public static int SumOfDigits(long x, long baseMod = 10)
        {
            int res = 0;
            while (x > 0)
            {
                res += (int)(x % baseMod);
                x = x / baseMod;
            }
            return res;
        }
    }

    internal static class Reader
    {
        public static void ReadInt(out int a)
        {
            int[] number = new int[1];
            ReadInt(number);
            a = number[0];
        }

        public static void ReadInt(out int a, out int b)
        {
            int[] numbers = new int[2];
            ReadInt(numbers);
            a = numbers[0];
            b = numbers[1];
        }

        public static void ReadInt(out int int1, out int int2, out int int3)
        {
            int[] numbers = new int[3];
            ReadInt(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
        }

        public static void ReadInt(out int int1, out int int2, out int int3, out int int4)
        {
            int[] numbers = new int[4];
            ReadInt(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
            int4 = numbers[3];
        }

        public static void ReadLong(out long a)
        {
            long[] number = new long[1];
            ReadLong(number);
            a = number[0];
        }

        public static void ReadLong(out long a, out long b)
        {
            long[] numbers = new long[2];
            ReadLong(numbers);
            a = numbers[0];
            b = numbers[1];
        }

        public static void ReadLong(out long int1, out long int2, out long int3)
        {
            long[] numbers = new long[3];
            ReadLong(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
        }

        public static void ReadLong(out long int1, out long int2, out long int3, out long int4)
        {
            long[] numbers = new long[4];
            ReadLong(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
            int4 = numbers[3];
        }

        public static void ReadInt(int[] numbers)
        {
            // ReSharper disable PossibleNullReferenceException
            var list = Console.ReadLine().Split();
            // ReSharper restore PossibleNullReferenceException

            int count = Math.Min(numbers.Length, list.Length);

            for (int i = 0; i < count; i++)
            {
                numbers[i] = int.Parse(list[i]);
            }
        }

        public static int[] ReadDigits()
        {
            // ReSharper disable AssignNullToNotNullAttribute
            return Console.ReadLine().Select(x => int.Parse(x.ToString())).ToArray();
            // ReSharper restore AssignNullToNotNullAttribute
        }

        public static void ReadLong(long[] numbers)
        {
            // ReSharper disable PossibleNullReferenceException
            var list = Console.ReadLine().Split();
            // ReSharper restore PossibleNullReferenceException

            int count = Math.Min(numbers.Length, list.Length);

            for (int i = 0; i < count; i++)
            {
                numbers[i] = long.Parse(list[i]);
            }
        }

        public static void ReadDouble(double[] numbers)
        {
            // ReSharper disable PossibleNullReferenceException
            var list = Console.ReadLine().Split();
            // ReSharper restore PossibleNullReferenceException

            int count = Math.Min(numbers.Length, list.Length);

            for (int i = 0; i < count; i++)
            {
                numbers[i] = double.Parse(list[i]);
            }
        }

        public static void ReadDouble(out double a, out double b)
        {
            double[] numbers = new double[2];
            ReadDouble(numbers);
            a = numbers[0];
            b = numbers[1];
        }

        public static void ReadDouble(out double int1, out double int2, out double int3)
        {
            double[] numbers = new double[3];
            ReadDouble(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
        }

        public static string ReadLine()
        {
            return Console.ReadLine();
        }
    }

    public interface IGraph
    {
        int Vertices { get; set; }

        IList<int> this[int i] { get; }

        void AddEdge(int u, int v);

        void AddOrientedEdge(int u, int v);
    }

    public class Graph : IGraph
    {
        private List<int>[] m_Edges;

        public int Vertices { get; set; }

        public IList<int> this[int i]
        {
            get
            {
                return this.m_Edges[i];
            }
        }

        public Graph(int vertices)
        {
            this.Vertices = vertices;

            this.m_Edges = new List<int>[vertices];

            for (int i = 0; i < vertices; i++)
            {
                this.m_Edges[i] = new List<int>();
            }
        }

        public void AddEdge(int u, int v)
        {
            this.AddOrientedEdge(u, v);
            this.AddOrientedEdge(v, u);
        }

        public void AddOrientedEdge(int first, int second)
        {
            this.m_Edges[first].Add(second);
        }

        public int[] Bfs(int start)
        {
            int[] d = new int[Vertices];
            for (int i = 0; i < Vertices; i++)
            {
                d[i] = -1;
            }

            Queue<int> queue = new Queue<int>();
            queue.Enqueue(start);
            d[start] = 0;

            while (queue.Count > 0)
            {
                int v = queue.Dequeue();
                foreach (int t in this.m_Edges[v].Where(t => d[t] == -1))
                {
                    queue.Enqueue(t);
                    d[t] = d[v] + 1;
                }
            }

            return d;
        }
    }

    internal class SimpleSumTable
    {
        private readonly int[,] m_Sum;

        public SimpleSumTable(int n, int m, int[,] table)
        {
            m_Sum = new int[n + 1,m + 1];

            for (int i = 1; i < n + 1; i++)
            {
                for (int j = 1; j < m + 1; j++)
                {
                    m_Sum[i, j] = m_Sum[i, j - 1] + m_Sum[i - 1, j] - m_Sum[i - 1, j - 1] + table[i - 1, j - 1];
                }
            }
        }

        public int GetSum(int l, int b, int r, int t)
        {
            return m_Sum[r + 1, t + 1] - m_Sum[r + 1, b] - m_Sum[l, t + 1] + m_Sum[l, b];
        }
    }

    internal class SegmentTreeSimpleInt<T>
    {
        public int Size { get; private set; }

        private readonly T[] m_Tree;

        private Func<T, T, T> m_Operation;

        private T m_Null;

        public SegmentTreeSimpleInt(int size, Func<T, T, T> operation, T nullElement, IList<T> array = null)
        {
            this.Size = size;
            this.m_Operation = operation;
            this.m_Null = nullElement;

            m_Tree = new T[4 * size];
            if (array != null)
            {
                this.Build(array, 1, 0, size - 1);
            }
        }

        private void Build(IList<T> array, int v, int tl, int tr)
        {
            if (tl == tr)
            {
                m_Tree[v] = array[tl];
            }
            else
            {
                int tm = (tl + tr) / 2;
                this.Build(array, 2 * v, tl, tm);
                this.Build(array, 2 * v + 1, tm + 1, tr);
                this.CalculateNode(v);
            }
        }

        public T GetSum(int l, int r)
        {
            return GetSum(1, 0, Size - 1, l, r);
        }

        private T GetSum(int v, int tl, int tr, int l, int r)
        {
            if (l > r)
            {
                return m_Null;
            }

            if (l == tl && r == tr)
            {
                return m_Tree[v];
            }

            int tm = (tl + tr) / 2;

            return this.m_Operation(
                GetSum(2 * v, tl, tm, l, Math.Min(r, tm)), GetSum(2 * v + 1, tm + 1, tr, Math.Max(l, tm + 1), r));
        }

        public void Update(int pos, T newValue)
        {
            Update(1, 0, Size - 1, pos, newValue);
        }

        private void Update(int v, int tl, int tr, int pos, T newValue)
        {
            if (tl == tr)
            {
                m_Tree[v] = newValue;
            }
            else
            {
                int tm = (tl + tr) / 2;
                if (pos <= tm)
                {
                    Update(2 * v, tl, tm, pos, newValue);
                }
                else
                {
                    Update(2 * v + 1, tm + 1, tr, pos, newValue);
                }
                this.CalculateNode(v);
            }
        }

        private void CalculateNode(int v)
        {
            m_Tree[v] = this.m_Operation(m_Tree[2 * v], m_Tree[2 * v + 1]);
        }
    }

    internal struct Pair<TFirst, TSecond>
    {
        public Pair(TFirst first, TSecond second)
            : this()
        {
            this.First = first;
            this.Second = second;
        }

        public TFirst First { set; get; }

        public TSecond Second { set; get; }
    }

    internal class FenwickTreeInt64
    {
        public FenwickTreeInt64(int size)
        {
            this.m_Size = size;
            m_Tree = new long[size];
        }

        public FenwickTreeInt64(int size, IList<long> tree)
            : this(size)
        {
            for (int i = 0; i < size; i++)
            {
                Inc(i, tree[i]);
            }
        }

        public long Sum(int r)
        {
            long res = 0;
            for (; r >= 0; r = (r & (r + 1)) - 1)
            {
                res += m_Tree[r];
            }
            return res;
        }

        public long Sum(int l, int r)
        {
            return Sum(r) - Sum(l - 1);
        }

        public void Inc(int i, long x)
        {
            for (; i < m_Size; i = i | (i + 1))
            {
                m_Tree[i] += x;
            }
        }

        public void Set(int i, long x)
        {
            Inc(i, x - Sum(i, i));
        }

        private int m_Size;

        private long[] m_Tree;
    }

    internal class AccumulativeDictionary<TKey> : Dictionary<TKey, int>
    {
        public new void Add(TKey key, int value = 1)
        {
            if (this.ContainsKey(key))
            {
                base[key] += value;
            }
            else
            {
                base.Add(key, value);
            }
        }

        public new int this[TKey key]
        {
            get
            {
                return this.ContainsKey(key) ? base[key] : 0;
            }
            set
            {
                this.Add(key, value);
            }
        }
    }

    internal class PriorityQueue<T>
    {
        public PriorityQueue(Comparison<T> comparison = null)
        {
            if (comparison == null)
            {
                if (typeof(T).GetInterfaces().Any(i => i == typeof(IComparable<T>)))
                {
                    m_Comparison = (a, b) => ((IComparable<T>)a).CompareTo(b);
                }
                else
                {
                    throw new ApplicationException("Add comparer");
                }
            }
            else
            {
                m_Comparison = comparison;
            }
        }

        public int Count { get; private set; }

        public void Enqueue(T item)
        {
            m_List.Add(item);
            m_Indexes.Add(item, this.Count);
            this.Count++;
            Up(this.Count);
        }

        public T Peek()
        {
            return m_List[0];
        }

        public T Dequeue()
        {
            if (this.Count > 0)
            {
                var result = m_List[0];

                Swap(0, this.Count - 1);
                m_Indexes.Remove(m_List[this.Count - 1]);
                m_List.RemoveAt(this.Count - 1);
                this.Count--;
                this.Down(1);

                return result;
            }
            throw new ApplicationException("Couldn't get element from empty queue");
        }

        public void Update(T item)
        {
            int index = m_Indexes[item];
            this.Up(index + 1);
        }

        private readonly List<T> m_List = new List<T>();

        private readonly Dictionary<T, int> m_Indexes = new Dictionary<T, int>();

        private readonly Comparison<T> m_Comparison;

        private void Up(int index)
        {
            while (index > 1 && m_Comparison.Invoke(m_List[index - 1], m_List[index / 2 - 1]) > 0)
            {
                this.Swap(index - 1, index / 2 - 1);

                index = index / 2;
            }
        }

        private void Down(int index)
        {
            while (2 * index <= this.Count && m_Comparison.Invoke(m_List[index - 1], m_List[2 * index - 1]) < 0
                   || 2 * index + 1 <= this.Count && m_Comparison.Invoke(m_List[index - 1], m_List[2 * index]) < 0)
            {
                if (2 * index + 1 > this.Count || m_Comparison.Invoke(m_List[2 * index - 1], m_List[2 * index]) > 0)
                {
                    this.Swap(index - 1, 2 * index - 1);
                    index = 2 * index;
                }
                else
                {
                    this.Swap(index - 1, 2 * index);
                    index = 2 * index + 1;
                }
            }
        }

        private void Swap(int i, int j)
        {
            var tmp = m_List[i];
            m_List[i] = m_List[j];
            m_List[j] = tmp;

            m_Indexes[m_List[i]] = i;
            m_Indexes[m_List[j]] = j;
        }
    }

    internal class Program
    {
        private static StreamReader m_InputStream;

        private static StreamWriter m_OutStream;

        private static void OpenFiles()
        {
            m_InputStream = File.OpenText("input.txt");
            Console.SetIn(m_InputStream);

            m_OutStream = File.CreateText("output.txt");
            Console.SetOut(m_OutStream);
        }

        private static void CloseFiles()
        {
            m_OutStream.Flush();

            m_InputStream.Dispose();
            m_OutStream.Dispose();
        }

        private static void Main()
        {
            //OpenFiles();

            new Solution().Solve();

           // CloseFiles();
        }
    }

    internal class Solution
    {
        public void Solve()
        {
            long n, m, k;
            Reader.ReadLong(out n, out m, out k);

            long mod = 1000000000 + 7;

            long[,] c = new long[n + 1,n + 1];
            for (int i = 0; i <= n; i++)
            {
                c[i, 0] = 1;
            }
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= n; j++)
                {
                    c[i, j] = c[i - 1, j - 1] + c[i - 1, j];
                    if (c[i,j] > mod)
                    {
                        c[i, j] -= mod;
                    }
                }
            }

            long[] p0 = new long[n + 1];
            for (int i = 0; i <= n; i++)
            {
                p0[i] = Algebra.BinPower(c[n, i], m / n, mod);
            }

            long[] p1 = new long[n + 1];
            for (int i = 0; i <= n; i++)
            {
                p1[i] = (p0[i] * c[n, i]) % mod;
            }

            long[,] a = new long[n + 1,(n + 1) * (n + 1)];
            a[0, 0] = 1;
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j <= k; j++)
                {
                    if (a[i,j] > 0)
                    {
                        var full = i < m % n;
                        for (int l = 0; l <= n; l++)
                        {
                            long p = full ? p1[l] : p0[l];
                            a[i + 1, j + l] = (a[i + 1, j + l] + p * a[i, j]) % mod;
                        }
                    }
                }
            }

            Console.WriteLine(a[n,k]);
        }
    }
}