Vasya has got an undirected graph consisting of $$$n$$$ vertices and $$$m$$$ edges. This graph doesn't contain any self-loops or multiple edges. Self-loop is an edge connecting a vertex to itself. Multiple edges are a pair of edges such that they connect the same pair of vertices. Since the graph is undirected, the pair of edges $$$(1, 2)$$$ and $$$(2, 1)$$$ is considered to be multiple edges. Isolated vertex of the graph is a vertex such that there is no edge connecting this vertex to any other vertex.Vasya wants to know the minimum and maximum possible number of isolated vertices in an undirected graph consisting of $$$n$$$ vertices and $$$m$$$ edges.

The only line contains two integers $$$n$$$ and $$$m~(1 \le n \le 10^5, 0 \le m \le \frac{n (n - 1)}{2})$$$. It is guaranteed that there exists a graph without any self-loops or multiple edges with such number of vertices and edges.

In the only line print two numbers $$$min$$$ and $$$max$$$ — the minimum and maximum number of isolated vertices, respectively.

NoteIn the first example it is possible to construct a graph with $$$0$$$ isolated vertices: for example, it should contain edges $$$(1, 2)$$$ and $$$(3, 4)$$$. To get one isolated vertex, we may construct a graph with edges $$$(1, 2)$$$ and $$$(1, 3)$$$. In the second example the graph will always contain exactly one isolated vertex.

using System;
using System.Linq;

namespace CSharp
{
    class _1065B
    {
        public static void Main()
        {
            var tokens = Console.ReadLine().Split();

            int n = int.Parse(tokens[0]);
            long m = long.Parse(tokens[1]);

            long min = Math.Max(0, n - 2 * m);
            long max = n - Enumerable.Range(0, n + 1).First(i => (long)i * (i - 1) / 2 >= m);

            Console.WriteLine($"{min} {max}");
        }
    }
}

using System;
using System.Collections;
using CompLib.Util;

public class Program
{
    private int N;
    private long M;

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

        /*
         * N頂点M辺
         *
         * 孤立頂点最大数、最小数
         */

        long min, max;
        // 最小
        if (M == 0)
        {
            min = N;
        }
        else
        {
            min = Math.Max(0, N - 2 * M);
        }

        if (M == 0)
        {
            max = N;
        }
        else
        {
            long tmp = M;
            max = N;

            for (long i = 2; i <= N; i++)
            {
                // i頂点完全グラフ
                long e = (i - 1) * i / 2;
                if (tmp <= e)
                {
                    max -= i;
                    break;
                }
            }
        }

        Console.WriteLine($"{min} {max}");
    }

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

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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

using System;
using System.Collections.Generic;

namespace G6
{
    class Program
    {
        static void Main(string[] args)
        {
            long n, m;
            string[] sins = Console.ReadLine().Trim(' ').Split(' ');
            n = long.Parse(sins[0]);
            m = long.Parse(sins[1]);

            if (n != 1)
            {
                if (m != 0)
                {
                    long summ = 1;
                    long answerMax = n - 2;
                    for (int i = 2; i <= n; i++)
                    {
                        if (summ < m)
                        {
                            answerMax--;
                        }
                        else
                        {
                            break;
                        }
                        summ += i;
                    }

                    long AnswerMin = 0;
                    if (n % 2 == 0)
                    {
                        if (m < n / 2)
                            AnswerMin = n - m * 2;
                    }
                    else
                    {
                        if (m < (n + 1) / 2)
                            AnswerMin = n - m * 2;
                    }
                    Console.Write(AnswerMin + " " + answerMax);
                }
                else
                {
                    Console.Write(n + " " + n);
                }
            }
            else
            {
                Console.Write("1 1");
            }
            //Console.ReadKey();
        }
    }
}

using System;
using System.Collections;
using System.IO;

namespace Codeforces
{
    public class Program
    {
        public static void Main()
        {
            var input = Console.ReadLine().Split();
            long n = long.Parse(input[0]), m = long.Parse(input[1]);
            long min = n-2*m;
            Console.WriteLine(Math.Max(0, min));

            long set = 1;
            long edges = m;
            while (edges > 0)
            {
                edges -= Math.Min(set, edges);
                set++;
            }
            Console.WriteLine(set == 1 ? n : n - set);
        }
    }
}

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

class Program
{
    public void Run()
    {
         var Elems = Console.ReadLine().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(long.Parse).ToArray();
       long n = Elems[0];
       long m = Elems[1];
               long max = 0;
               long count = 0;
               long counter = 0;
               if (m == 0) Console.WriteLine("{0} {1}", n, n);
               else
               {
                   while (true)
                   {
                       count++;
                       if (m <= counter)
                       {
                           max = count;
                           break;
                       }
                       counter += count;
                   }
                   Console.WriteLine("{0} {1}", Math.Max(0, n - m * 2), n - max);
               }
        /*var Elems = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int n = Elems[0];
        int k = Elems[1];
        var heights = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int max = heights.Max();
        int[] h = new int[max + 2];
        for (int i = 0; i<n; i++)
        {
            h[1]++;
            h[heights[i]+1]--;
        }
        int counter = 0;
        for(int i = 0; i<h.Length; i++)
        {
            counter += h[i];
            h[i] = counter;
        }
        long s = 0;
        long tmp = 0;
        int c=0;
        h[0] = h[1];
        int j = h.Length - 2;
        while (h[j]!=h[j-1])
            while (true)
            {
                tmp += h[j];
                if (tmp > k)
                {
                    s ++;
                    tmp = 0;
                    break;
                }
                j--;
            }
        Console.WriteLine(s);*/

            }

static void Main()
    {
                new Program().Run();
    }
}

using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		string[] str = Console.ReadLine().Split();
		long N = long.Parse(str[0]);
		long M = long.Parse(str[1]);
		long min = Math.Max(0,N - M*2);
		long max = N;
		if(M >= 1){
			long ct = 0;
			long i = 0;
			while(ct < M){
				i += 1;
				ct += i;
			}
			max = Math.Max(0,max-i-1);
		}
		Console.WriteLine(min+" "+max);
	}
}

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

class Solver
{
    public Scanner sc;
    public void Solve()
    {
        long N, M;
        sc.Make(out N, out M);
        var min = Max(0, N - 2 * M);
        int i;var now = 0L;
        if (M == 0) Fail($"{min} {N}");
        for (i = 0; i < N; i++)
        {
            now += i;
            if (now >= M) break;
        }
        Console.WriteLine($"{min} {N-i-1}");
    }
}

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

#endregion

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

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

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

        private static void Solve()
        {
            long n = Next();
            long m = Next();

            writer.Write(Math.Max(0, n - 2*m));
            writer.Write(' ');

            for (var i = (long) Math.Sqrt(2*m);; i++)
            {
                if (i*(i - 1)/2 >= m)
                {
                    writer.WriteLine(n - i);
                    break;
                }
            }
        }

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

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

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] S = Console.ReadLine().Split();
            long n = Convert.ToInt64(S[0]);
            long m = Convert.ToInt64(S[1]);
            if (m == 0) Console.WriteLine(n + " " + n);
            else Console.WriteLine(Math.Max(0, n - (m * 2)) + " " + Math.Max(0, n - F(n, m)));
        }

        static int F(long r, long m)
        {
            long tp = 0;
            long s = 0;
            for (int i = 1; i <= r + 1; i++)
            {
                s += tp++;
                if (s >= m) return i;
            }
            return 0;
        }
    }
}

#if DEBUG
using System.Reflection;
using System.Threading.Tasks;
#endif

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

#if DEBUG
using System.Diagnostics;
#endif

namespace ed52b
{
    class Program
    {
        static string _inputFilename = "input.txt";
        static string _outputFilename = "output.txt";
        static bool _useFileInput = false;
        const string _delim = "!";

        static void Main(string[] args)
        {
            StreamWriter file = null;
#if DEBUG
            var testNumber = 0;
            var timer = new Stopwatch();
            foreach (var test in GetTests())
            {

                timer.Start();

                var defaultColor = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine($"<!-- TEST #{testNumber} -->");
                Console.ForegroundColor = defaultColor;
                Console.SetIn(test);

#else
            if (_useFileInput)
            {
                Console.SetIn(File.OpenText(_inputFilename));
                file = new StreamWriter(_outputFilename);
                Console.SetOut(file);
            }
#endif

            try
            {
#if DEBUG
                Solution(testNumber);
#else
                Solution(0);
#endif
            }
            finally
            {
#if DEBUG
#else
                if (_useFileInput)
                {
                    file.Close();
                }
#endif
            }

#if DEBUG
                timer.Stop();

                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine($"<!-- TEST #{testNumber} FINISHED IN {timer.Elapsed.ToString(@"ss\:fff")}-->");
                Console.ForegroundColor = defaultColor;

                timer.Reset();
                testNumber++;
            }
#endif
        }

        static void Solution(int testNumber)
        {
            #region SOLUTION
            var d = ReadLongArray();
            var n = d[0];
            var m = d[1];

            var min = Math.Max(0, n - (m * 2));

            var l = 0L;
            var r = n;
            while (true)
            {
                if (l == r)
                {
                    break;
                }

                var mid = l + (r - l + 1) / 2;
                var rem = n - mid;
                var maxE = rem * (rem - 1) / 2;
                if (m <= maxE)
                {
                    l = mid;
                }
                else
                {
                    r = mid - 1;
                }
            }

            Console.WriteLine("{0} {1}", min, l);

            //var n = readInt();
            //var m = readInt();

            //var a = readIntArray();
            //var b = readIntArray();
            #endregion
        }

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

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

        static int[] ReadIntArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => int.Parse(i)).ToArray();
        }

        static long[] ReadLongArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => long.Parse(i)).ToArray();
        }

#if DEBUG
        static IEnumerable<TextReader> GetTests()
        {
            var tests = new List<string>();
            var resName = Assembly.GetCallingAssembly().GetManifestResourceNames()[0];
            using (var resource = new StreamReader(Assembly.GetCallingAssembly().GetManifestResourceStream(resName)))
            {
                while (true)
                {
                    var nextText = new StringBuilder();
                    var endOfFile = false;
                    while (true)
                    {
                        var line = resource.ReadLine();

                        endOfFile = line == null;
                        if (endOfFile)
                        {
                            break;
                        }

                        if (line.Equals(_delim, StringComparison.Ordinal))
                        {
                            break;
                        }

                        nextText.AppendLine(line);
                    }

                    yield return new StringReader(nextText.ToString());

                    if (endOfFile)
                    {
                        break;
                    }
                }
            }
        }
#endif
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class testcodeforces
{
    public static void Main()
    {
        int t = 1;

        for (int i = 0; i < t; i++)
        {
            var array = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
            long min = array[0] - (2 * array[1]);

            min = Math.Max(0, min);

            long max = 0;
            long node = 1;

            if (array[1] == 0)
            {
                max = array[0];
            }
            else
            {

                for (node = 1; node <= array[0]; node++)
                {
                    if ((node * (node - 1) / 2) >= array[1])
                    {
                        break;
                    }
                }

                node = Math.Min(array[0], node);
                max = array[0] - node;
            }

            //max = Math.Max(0, max);

            Console.WriteLine("" + min + " " + max);
        }
    }
}

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

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){

		Console.WriteLine("{0} {1}", MinV(), MaxV());

	}

	long MinV(){
		return Math.Max(N - 2 * M, 0);
	}

	long MaxV(){
		for(int i=(int)N;i>=0;i--){
			var rest = N - i;
			var mm = rest * (rest - 1) / 2;
			if(mm >= M) return (long) i;
		}
		return 0;
	}

	long N,M;
	public Sol(){
		var d = rla();
		N = d[0]; M = d[1];
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}

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

namespace W0lf
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] str = Console.ReadLine().Split(' ');
            long n = long.Parse(str[0]), m = long.Parse(str[1]), a = 0, b = 0;
            a = Math.Max(n - m * 2, 0);
            if(n == 1) b = a;
            else if(m == 1) b = n - 2;
            else if(m == 0) b = a;
            else
            {
                for(long i = 2; i < n; i++)
                {
                    if(m > (i * (i - 1)) / 2 && m <= ((i + 1) * i) / 2)
                    {
                        b = n - (i + 1);
                        break;
                    }
                }
            }
            Console.WriteLine(a + " " + b);
            Console.ReadLine();
        }
    }
}

/*
csc -debug B.cs && mono --debug B.exe <<< "4 2"
*/

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

public class HelloWorld {
    static public void Main () {
        SolveCodeForces();
    }

    public static void SolveCodeForces() {
        var arr = Console.ReadLine().Split().Select(ulong.Parse).ToArray();
        var n = arr[0];
        var m = arr[1];

        if (m == 0) {
            System.Console.WriteLine("{0} {1}", n, n);
            return;
        }
        if (n == 1) {
            System.Console.WriteLine("{0} {1}", n, n);
            return;
        }

        var min = n <= 2ul * m ? 0ul : (n - 2ul * m);
        var max = n;

        for (var x = 1ul; x <= n; x++) {
            if ((x % 2ul == 0 && (x / 2ul * (x - 1ul)) >= m)
                || (x % 2ul == 1 && ((x - 1ul) / 2ul * x) >= m)) {
                max = n - x;
                break;
            }
        }

        System.Console.WriteLine("{0} {1}", min, max);
    }
}

public static class Helpers {
    public static T[] CreateArray<T>(int length, Func<int, T> itemCreate) {
        var result = new T[length];
        for (var i = 0; i < result.Length; i++)
            result[i] = itemCreate(i);
        return result;
    }
}

using System;
using System.Linq;

namespace ProblemWatermelon
{
    class Program
    {
        static void Main(string[] args)
        {
            long[] inputs = Console.ReadLine().Split(' ').Select(s => long.Parse(s)).ToArray();
            long vertices = inputs[0];
            long edges = inputs[1];

            long min = vertices - edges * 2;
            //if (vertices % 2 != 0)
            //    min++;

            if (min < 0)
                min = 0;

            long max = vertices;
            if (edges > 0)
            {
                double sqrtpart = 1 - (4 * -edges * 2);
                max = vertices - (long)(Math.Ceiling((1 + Math.Sqrt(sqrtpart)) / 2));
            }

            if (max < 0)
                max = 0;

            Console.WriteLine(min + " " + max);
        }
    }
}

using System;

namespace B
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] stringArray = Console.ReadLine().Split();
            long n = Int64.Parse(stringArray[0]);
            long m = Int64.Parse(stringArray[1]);
            long min = Math.Max(n - m * 2, 0);
            long k = (long)Math.Sqrt(2 * m);

            while (k * (k - 1) / 2 < m)
                k++;

            long max = n - k;

            Console.WriteLine($"{min} {max}");
            Console.Read();
        }
    }
}

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

namespace Codeforces
{
	static class Program
	{

		static void Main(string[] args)
		{
			var nm = Console.ReadLine().Split().Select(long.Parse).ToList();
			long min = nm[0], max = nm[0];
			long rem = nm[1], cur = 0;
			if (nm[1] != 0)
			{
				min = nm[0] - nm[1] * 2;

				while(rem > 0)
				{
					var d = Math.Min(cur, rem);
					cur++;
					rem -= d;
				}
				if(cur != 1) max = nm[0] - cur;
			}
			Console.WriteLine($"{Math.Max(min, 0)} {Math.Max(max, 0)}");
			Console.ReadLine();
		}
	}
}

using System;
using System.Collections.Generic;
using static System.Console;
using static System.Math;

public class Hello{
    public static void Main(){
        string[] input = ReadLine().Split(' ');
        int tyouten = int.Parse(input[0]);
        long hen = long.Parse(input[1]);

        if(tyouten == 1){
            WriteLine("1 1");
        }else if(hen == 0){
            WriteLine("{0} {1}",tyouten,tyouten);
        }else{

        //min
        int tyoutemp = (tyouten+1)/2;
        int oe = tyouten%2;
        long tempmin = (tyoutemp - hen)*2-oe;
        long min = Max(tempmin,0);

        //Max
        long check = 0;
        for(long i=2;i<=tyouten;i++){
            long saidai = (i*(i-1))/2; //頂点i個に対して使える辺の最大値
            if(saidai >= hen){
                check = i;
                break;
//                WriteLine(saidai);
            }
        }
        long max = tyouten - check;
        WriteLine("{0} {1}",min,max);

        }
    }
}

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

namespace ConsoleApp97
{
    class Program
    {
        static void Main(string[] args)
        {
            long[] first = Console.ReadLine().Split(' ').Select(long.Parse).ToArray();
            long n = first[0];
            long k = first[1];

            if( n == 1)
            {
                Console.WriteLine("1 1");
            }
            else
            {
                if( k == 0)
                    Console.WriteLine( n + " " + n);
                else
                {
                    long min = n - k * 2;
                    if (min < 0)
                        min = 0;
                    long count = 1;
                    long index = 1;
                    while( k > 0)
                    {
                        // делаем циклы.
                        if (k - count >= 0)
                        {
                            k -= count;
                            index++;
                            count++;
                        }
                        else
                            break;
                    }
                    // ребро 1, смежная вершина одна
                    //2 вершины в цикле + 1 ребро еще
                    if (k > 0)
                        index++;
                    long max = n - index;
                    Console.WriteLine(min + " " + max);
                }

            }

            int aaa = 5;
            //1 2 9
            //10 1 1
        }
    }
}

using System;

public class Program
{
    public static void Main()
    {
        var line = Console.ReadLine().Split(' ');
        var vertexes = ulong.Parse(line[0]);
        var edges = ulong.Parse(line[1]);

        if (edges == 0)
        {
            Console.WriteLine($"{vertexes} {vertexes}");
            return;
        }

        ulong v;
        for (v = 1; v <= vertexes; ++v)
        {
            var v2 = v - 1;
            if (v2 * (v2 + 1) / 2 >= edges)
            {
                break;
            }
        }

        ulong max = 0;
        if (v == vertexes + 1)
        {
            max = 0;
        }
        else
        {
            max = vertexes - v;
        }

        ulong totalRequired = vertexes % 2 == 0 ? vertexes / 2 : (vertexes / 2) + 1;
        ulong min = 0;

        if (totalRequired <= edges)
        {
            min = 0;
        }
        else
        {
            var missing = (totalRequired - edges);
            if (vertexes % 2 == 0)
            {
                min = missing * 2;
            }
            else
            {
                min = ((missing - 1) * 2) + 1;
            }
        }

        Console.WriteLine($"{min} {max}");
    }
}

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

class Program
{
    class T
    {
        public int X;
        public int Y;

        public T(int x, int y)
        {
            X = x;
            Y = y;
        }
    }
    //////////////////////////////////////////////////

    long tutu(long n, long m)
    {
        for (long i = n; i > 0; i--)
        {
            if (i * (i - 1) < 2 * m)
            {
                return i;
            }
        }
        return 0;
    }

    //////////////////////////////////////////////////
    void Solution()
    {
        var n = rl;
        var m = rl;

        if (m == 0)
        {
            wsp(n);
            wln(n);
            return;
        }

        long min = 0;

        if (n > 2 * m)
        {
            min = n - 2 * m;
        }

            long z = tutu(n, m);
            m = m - z * (z - 1) / 2;
            n = n - z-1;

        wsp(min);
        wln(n);

    }
    //////////////////////////////////////////////////

    struct P : IComparable<P>
    {
        public long X;
        public long Y;

        public P(long x, long y)
        {
            X = x;
            Y = y;
        }

        public int CompareTo(P other) => X != other.X ? X.CompareTo(other.X) : Y.CompareTo(other.Y);
        public static int Comparison(P p1, P p2) => p1.CompareTo(p2);

        public static bool operator ==(P p1, P p2) => (p1.X == p2.X) && (p1.Y == p2.Y);
        public static bool operator !=(P p1, P p2) => (p1.X != p2.X) || (p1.Y != p2.Y);

        public static P operator +(P p1, P p2) => new P(p1.X + p2.X, p1.Y + p2.Y);
        public static P operator -(P p1, P p2) => new P(p1.X - p2.X, p1.Y - p2.Y);
    }

    void swap<T>(ref T o1, ref T o2) { var o = o1; o1 = o2; o2 = o; }
    long gcd(long a, long b) => (b != 0) ? gcd(b, a % b) : a;
    long lcm(long a, long b) => a / gcd(a, b) * b;

    long rast2(long x1, long y1, long x2, long y2) => (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    long rast2(P p1, P p2) => (p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y);
    long ccw(P p1, P p2, P p3) => p1.X * p2.Y + p1.Y * p3.X + p2.X * p3.Y - p2.Y * p3.X - p3.Y * p1.X - p1.Y * p2.X;

    StringBuilder _sb = new StringBuilder();
    void wln() { _sb.AppendLine(); }
    void wln<T>(T o) { _sb.AppendLine(o.ToString()); }
    void wsp<T>(T o) { _sb.Append(o).Append(" "); }
    void wrt<T>(T o) { _sb.Append(o); }
    void wln(double o) { _sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0:F12}", o)); }
    void wsp(double o) { _sb.Append(string.Format(CultureInfo.InvariantCulture, "{0:F12} ", o)); }
    void wrt(double o) { _sb.Append(string.Format(CultureInfo.InvariantCulture, "{0:F12}", o)); }

    List<P> rpa(int n)
    {
        var res = new List<P>(n);
        for (int i = 0; i < n; i++)
            res.Add(new P(rl, rl));
        return res;
    }

    int ri
    {
        get
        {
            _read(); while (_str[_ind] == ' ') ++_ind;
            int sign = 1; if (_str[_ind] == '-') { sign = -1; ++_ind; }
            int p = 0;
            while (_ind < _count && _str[_ind] != ' ') p = p * 10 + _str[_ind++] - '0';
            while (_ind < _count && _str[_ind] == ' ') ++_ind; return p * sign;
        }
    }
    long rl
    {
        get
        {
            _read(); while (_str[_ind] == ' ') ++_ind;
            int sign = 1; if (_str[_ind] == '-') { sign = -1; ++_ind; }
            long p = 0;
            while (_ind < _count && _str[_ind] != ' ') p = p * 10 + _str[_ind++] - '0';
            while (_ind < _count && _str[_ind] == ' ') ++_ind; return p * sign;
        }
    }
    double rd
    {
        get
        {
            _read(); while (_str[_ind] == ' ') ++_ind; int sign = 1; if (_str[_ind] == '-') { sign = -1; ++_ind; }
            long p = 0, q = 1; while (_ind < _count && _str[_ind] != ' ' && _str[_ind] != '.') p = p * 10 + _str[_ind++] - '0';
            if (_ind < _count && _str[_ind] == '.') { ++_ind; while (_ind < _count && _str[_ind] != ' ') { p = p * 10 + _str[_ind++] - '0'; q *= 10; } }
            while (_ind < _count && _str[_ind] == ' ') ++_ind; return (double)p / q * sign;
        }
    }
    string rs
    {
        get
        {
            _read(); while (_ind < _count && _str[_ind] == ' ') ++_ind;
            var tmp = _str.IndexOf(' ', _ind);
            if (tmp == -1) { var res = _str.Substring(_ind); _count = 0; _ind = 0; return res; }
            var s = _str.Substring(_ind, tmp - _ind); _ind = tmp + 1;
            while (_ind < _count && _str[_ind] == ' ') ++_ind; return s;
        }
    }

    List<int> ria(int n)
    {
        var res = new int[n];
        for (int k = 0; k < n;)
        {
            var s = Console.ReadLine(); var m = s.Length;
            for (int i = 0; i < m && k < n; ++i)
            {
                while (i < m && s[i] == ' ') ++i; if (i == m) break; int sign = 1; if (s[i] == '-') { sign = -1; ++i; }
                int p = 0; while (i < m && s[i] != ' ') p = p * 10 + s[i++] - '0'; res[k++] = p * sign;
            }
        }
        _count = 0; _ind = 0; return res.ToList();
    }
    List<long> rla(int n)
    {
        var res = new long[n];
        for (int k = 0; k < n;)
        {
            var s = Console.ReadLine(); var m = s.Length;
            for (int i = 0; i < m && k < n; ++i)
            {
                while (i < m && s[i] == ' ') ++i; if (i == m) break; int sign = 1; if (s[i] == '-') { sign = -1; ++i; }
                long p = 0; while (i < m && s[i] != ' ') p = p * 10 + s[i++] - '0'; res[k++] = p * sign;
            }
        }
        _count = 0; _ind = 0; return res.ToList();
    }
    List<double> rda(int n)
    {
        var res = new double[n];
        for (int k = 0; k < n;)
        {
            var s = Console.ReadLine(); var m = s.Length;
            for (int i = 0; i < m && k < n; ++i)
            {
                while (i < m && s[i] == ' ') ++i; if (i == m) break; int sign = 1; if (s[i] == '-') { sign = -1; ++i; }
                long p = 0, q = 1; while (i < m && s[i] != ' ' && s[i] != '.') p = p * 10 + s[i++] - '0';
                if (i < m && s[i] == '.') { ++i; while (i < m && s[i] != ' ') { p = p * 10 + s[i++] - '0'; q *= 10; } }
                res[k++] = (double)p / q * sign;
            }
        }
        _count = 0; _ind = 0; return res.ToList();
    }
    List<string> rsa(int n) { var res = new string[n]; for (int k = 0; k < n; ++k) res[k] = Console.ReadLine(); _count = 0; _ind = 0; return res.ToList(); }
    string _str = null; int _count = 0; int _ind = 0;
    void _read() { if (_ind == _count) { _str = Console.ReadLine(); _count = _str.Length; _ind = 0; } }
    static void Main(string[] args) { new Program().Main(); }
    void Main()
    {
        //Console.SetIn(new StreamReader("input.txt")); Console.SetOut(new StreamWriter("output.txt"));
        Solution();
        Console.Write(_sb);
        //Console.In.Close(); Console.Out.Close();
    }
}

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

namespace IsolatedVertices {
    class IoslatedVertices {
        static void Main( string[] args ) {
            var input = Console.ReadLine().Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            var n = Int64.Parse( input[ 0 ] );
            var m = Int64.Parse( input[ 1 ] );

            var minimum = Math.Max( n - ( 2 * m ), 0 );
            var maximum = (Int64) 0;
            if( m == 0 ) { maximum = n; } else if( m == 1 ) {
                maximum = n - 2;
            } else {

                var tableStart = (Int64) Math.Floor( Math.Sqrt( 2 * m ) );

                Int64 entry = 0;
                Int64 k = tableStart;
                while( entry < m ) {
                    entry = ( k * ( k - 1 ) ) / 2;
                    k++;
                };

                maximum = Math.Max( n - (k - 1), 0 );
            }

            Console.WriteLine( minimum + " " + maximum );
        }
    }
}

using System;

namespace CSharp
{
    class _1065B
    {
        public static void Main()
        {
            var tokens = Console.ReadLine().Split();

            long n = long.Parse(tokens[0]);
            long m = long.Parse(tokens[1]);

            long min = Math.Max(0, n - 2 * m);
            long max = n - (long)Math.Floor(Math.Sqrt(2 * m) + 1);

            Console.WriteLine($"{min} {max}");
        }
    }
}

using System;
using System.Collections.Generic;

namespace G6
{
    class Program
    {
        static void Main(string[] args)
        {
            long n, m;
            string[] sins = Console.ReadLine().Trim(' ').Split(' ');
            n = long.Parse(sins[0]);
            m = long.Parse(sins[1]);

            if (n != 1)
            {
                if (m != 0)
                {
                    long summ = 1;
                    long answerMax = n - 2;
                    for (int i = 2; i <= n; i++)
                    {
                        if (summ < m)
                            answerMax--;
                        else
                            break;
                        summ += i;
                    }

                    long AnswerMin = n - m * 2;
                    Console.Write(AnswerMin + " " + answerMax);
                }
                else
                    Console.Write(n + " " + n);
            }
            else
                Console.Write("1 1");
        }
    }
}

using System;
using System.Collections.Generic;

namespace G6
{
    class Program
    {
        static void Main(string[] args)
        {
            long n, m;
            string[] sins = Console.ReadLine().Trim(' ').Split(' ');
            n = long.Parse(sins[0]);
            m = long.Parse(sins[1]);

            if (n != 1)
            {
                if (m != 0)
                {
                    long summ = 1;
                    long answerMax = n-2;
                    for (int i = 2; i <= n; i++)
                    {
                        if (summ < m)
                        {
                            answerMax--;
                        }
                        else
                        {
                            break;
                        }
                        summ += i;
                    }

                    long AnswerMin = 0;
                    if (n % 2 == 0)
                    {
                        if (m < n / 2)
                            AnswerMin = n - m*2;
                    }
                    else
                    {
                        if (m < (n+1) / 2)
                            AnswerMin = n - m*2;
                    }
                    Console.Write(AnswerMin + " " + answerMax);
                }
                else
                {
                    Console.Write(n + " " + n);
                }
            }
            else
            {
                Console.Write("0 0");
            }
            //Console.ReadKey();
        }
    }
}

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

namespace CodeforcesRounds
{
    class A
    {
        static void Main(string[] args)
        {
            var input = Console.ReadLine().Split(' ');
            long n = long.Parse(input[0]), m = long.Parse(input[1]);
            if (m == 0)
            {
                Console.WriteLine(n + " " + n);
                return;
            }
            var first = (n - 2 * m);
            var second = n - m - 1;
            Console.Write(first < 0 ? 0 : first);
            Console.Write(" ");
            Console.WriteLine(second < 0 ? 0 : second);
        }
    }
}

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

namespace CodeforcesRounds
{
    class A
    {
        static void Main(string[] args)
        {
            var input = Console.ReadLine().Split(' ');
            long n = long.Parse(input[0]), m = long.Parse(input[1]);
            if (m == 0)
            {
                Console.WriteLine(n + " " + n);
                return;
            }
            var first = (n - 2 * m);
            var second = n - Math.Max(m, n-1);
            Console.Write(first < 0 ? 0 : first);
            Console.Write(" ");
            Console.WriteLine(second < 0 ? 0 : second);
        }
    }
}

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

namespace CodeforcesRounds
{
    class A
    {
        static void Main(string[] args)
        {
            var input = Console.ReadLine().Split(' ');
            long n = long.Parse(input[0]), m = long.Parse(input[1]);
            if (m == 0)
            {
                Console.WriteLine(n + " " + n);
                return;
            }
            Console.Write((n - 2 * m) + " ");
            Console.WriteLine(n - m - 1);
        }
    }
}

using System;
using System.Collections;
using System.IO;

namespace Codeforces
{
    public class Program
    {
        public static void Main()
        {
            var input = Console.ReadLine().Split();
            long n = long.Parse(input[0]), m = long.Parse(input[1]);
            long min = n-2*m;
            Console.WriteLine(Math.Max(0, min));

            long set = 1;
            long edges = n;
            while (edges > 0)
            {
                edges -= Math.Min(set, edges);
                set++;
            }
            Console.WriteLine(set == 1 ? n : n - set);
        }
    }
}

using System;
using System.Collections;
using System.IO;

namespace Codeforces
{
    public class Program
    {
        public static void Main()
        {
            var input = Console.ReadLine().Split();
            long n = long.Parse(input[0]), m = long.Parse(input[1]);
            long min = n-2*m;
            Console.WriteLine(Math.Max(0, min));

            long set = 1;
            long edges = n;
            while (edges > 0)
            {
                set++;
                edges -= Math.Min(set, edges);
            }
            Console.WriteLine(set == 1 ? n : n - set);
        }
    }
}

using System;
using System.Collections;
using System.IO;

namespace Codeforces
{
    public class Program
    {
        public static void Main()
        {
            var input = Console.ReadLine().Split();
            int n = int.Parse(input[0]), m = int.Parse(input[1]);
            var min = n-2*m;
            Console.WriteLine(Math.Max(0, min));

            var set = 1;
            var edges = 0;
            for (int i = 0; i < m; i++)
            {
                if (set*(set-1)/2 < edges)
                {
                    set++;
                }
                edges++;
            }
            Console.WriteLine(set == 1 ? n : n - set);
        }
    }
}

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

namespace CodeforcesRounds
{
    class A
    {
        static void Main(string[] args)
        {
            var input = Console.ReadLine().Split(' ');
            long n = long.Parse(input[0]), m = long.Parse(input[1]);
            Console.Write((n - 2 * m) + " ");
            Console.WriteLine(n - m - 1);
        }
    }
}

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

class Solver
{
    public Scanner sc;
    public void Solve()
    {
        long N, M;
        sc.Make(out N, out M);
        var min = Max(0, (N + 1) / 2 - M);
        int i;var now = 0L;
        if (M == 0) Fail($"{min} {N}");
        for (i = 0; i < N; i++)
        {
            now += i;
            if (now >= M) break;
        }
        Console.WriteLine($"{min} {N-i-1}");
    }
}

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

#endregion

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

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] S = Console.ReadLine().Split();
            long n = Convert.ToInt64(S[0]);
            long m = Convert.ToInt64(S[1]);
            if (m == 0) Console.WriteLine(n+" "+n);
            else Console.WriteLine(Math.Max(0, n - m * 2) + " " + Math.Max(0, n - 1 - m));
        }
    }
}

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

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] S = Console.ReadLine().Split();
            long n = Convert.ToInt64(S[0]);
            long m = Convert.ToInt64(S[1]);
            if (m == 0) Console.WriteLine(n + " " + n);
            else Console.WriteLine(Math.Max(0, n - (m - 2)) + " " + Math.Max(0, n - F(m)));
        }

        static int F(long r)
        {
            long c = r * 2;
            for (int i = 1; i <= r + 1; i++)
            {
                if (i * (i - 1) == c) return i;
                else if (i * (i - 1) > c) return i;
            }
            return 0;
        }
    }
}

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

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] S = Console.ReadLine().Split();
            long n = Convert.ToInt64(S[0]);
            long m = Convert.ToInt64(S[1]);
            if (n == 1 && m == 0) Console.WriteLine("1 1");
            else Console.WriteLine(Math.Max(0, n - m * 2) + " " + Math.Max(0, n - 1 - m));
        }
    }
}

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

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] S = Console.ReadLine().Split();
            long n = Convert.ToInt64(S[0]);
            long m = Convert.ToInt64(S[1]);

            Console.WriteLine(Math.Max(0, n - m * 2) + " " + (n - 1 - m));

        }
    }
}

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

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] S = Console.ReadLine().Split();
            long n = Convert.ToInt64(S[0]);
            long m = Convert.ToInt64(S[1]);
            if (n == 1 && m == 0) Console.WriteLine("1 1");
            else Console.WriteLine(Math.Max(0, n - m * 2) + " " + Math.Max(0, n - 1 - (m / 2 + (m % 2))));
        }
    }
}

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

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] S = Console.ReadLine().Split();
            long n = Convert.ToInt64(S[0]);
            long m = Convert.ToInt64(S[1]);
            if (m == 0) Console.WriteLine(n + " " + n);
            else Console.WriteLine(Math.Max(0, n - (m * 2)) + " " + Math.Max(0, n - F(n)));
        }

        static int F(long r)
        {
            long tp = 1;
            long s = 0;
            for (int i = 1; i <= r + 1; i++)
            {
                s += tp++;
                if (s >= r) return i;
            }
            return 0;
        }
    }
}

#if DEBUG
using System.Reflection;
using System.Threading.Tasks;
#endif

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

#if DEBUG
using System.Diagnostics;
#endif

namespace ed52b
{
    class Program
    {
        static string _inputFilename = "input.txt";
        static string _outputFilename = "output.txt";
        static bool _useFileInput = false;
        const string _delim = "!";

        static void Main(string[] args)
        {
            StreamWriter file = null;
#if DEBUG
            var testNumber = 0;
            var timer = new Stopwatch();
            foreach (var test in GetTests())
            {

                timer.Start();

                var defaultColor = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine($"<!-- TEST #{testNumber} -->");
                Console.ForegroundColor = defaultColor;
                Console.SetIn(test);

#else
            if (_useFileInput)
            {
                Console.SetIn(File.OpenText(_inputFilename));
                file = new StreamWriter(_outputFilename);
                Console.SetOut(file);
            }
#endif

            try
            {
#if DEBUG
                Solution(testNumber);
#else
                Solution(0);
#endif
            }
            finally
            {
#if DEBUG
#else
                if (_useFileInput)
                {
                    file.Close();
                }
#endif
            }

#if DEBUG
                timer.Stop();

                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine($"<!-- TEST #{testNumber} FINISHED IN {timer.Elapsed.ToString(@"ss\:fff")}-->");
                Console.ForegroundColor = defaultColor;

                timer.Reset();
                testNumber++;
            }
#endif
        }

        static void Solution(int testNumber)
        {
            #region SOLUTION
            var d = ReadLongArray();
            var n = d[0];
            var m = d[1];

            var min = Math.Max(0, n - (m * 2));

            var l = 0L;
            var r = n;
            while (true)
            {
                if (l == r)
                {
                    break;
                }

                var mid = l + (r - l + 1) / 2;
                var rem = n - mid;
                var maxE = rem * (rem - 1) / 2;
                if (m <= maxE && m >= maxE - 1)
                {
                    l = mid;
                }
                else
                {
                    r = mid - 1;
                }
            }

            Console.WriteLine("{0} {1}", min, l);

            //var n = readInt();
            //var m = readInt();

            //var a = readIntArray();
            //var b = readIntArray();
            #endregion
        }

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

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

        static int[] ReadIntArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => int.Parse(i)).ToArray();
        }

        static long[] ReadLongArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => long.Parse(i)).ToArray();
        }

#if DEBUG
        static IEnumerable<TextReader> GetTests()
        {
            var tests = new List<string>();
            var resName = Assembly.GetCallingAssembly().GetManifestResourceNames()[0];
            using (var resource = new StreamReader(Assembly.GetCallingAssembly().GetManifestResourceStream(resName)))
            {
                while (true)
                {
                    var nextText = new StringBuilder();
                    var endOfFile = false;
                    while (true)
                    {
                        var line = resource.ReadLine();

                        endOfFile = line == null;
                        if (endOfFile)
                        {
                            break;
                        }

                        if (line.Equals(_delim, StringComparison.Ordinal))
                        {
                            break;
                        }

                        nextText.AppendLine(line);
                    }

                    yield return new StringReader(nextText.ToString());

                    if (endOfFile)
                    {
                        break;
                    }
                }
            }
        }
#endif
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class testcodeforces
{
    public static void Main()
    {
        int t = 1;

        for (int i = 0; i < t; i++)
        {
            var array = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
            long min = array[0] - (2 * array[1]);

            min = Math.Max(0, min);

            long max = 0;
            int node = 0;

            for (node = 0; node < array[0]; node++)
            {
                if ((node * (node - 1) / 2) >= array[1])
                {
                    break;
                }
            }

            max = array[0] - node;

            max = Math.Max(0, max);

            Console.WriteLine("" + min + " " + max);
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class testcodeforces
{
    public static void Main()
    {
        int t = 1;

        for (int i = 0; i < t; i++)
        {
            var array = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
            long min = array[0] - (2 * array[1]);

            min = Math.Max(0, min);

            long max = 0;
            int node = 1;

            if (array[1] == 0)
            {
                max = array[0];
            }
            else
            {

                for (node = 1; node <= array[0]; node++)
                {
                    if ((node * (node - 1) / 2) >= array[1])
                    {
                        break;
                    }
                }

                max = array[0] - node;
            }

            //max = Math.Max(0, max);

            Console.WriteLine("" + min + " " + max);
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class testcodeforces
{
    public static void Main()
    {
        int t = 1;

        for (int i = 0; i < t; i++)
        {
            var array = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
            long min = array[0] - (2 * array[1]);

            min = Math.Max(0, min);

            long max = 0;
            int node = 0;

            if (array[1] == 0)
            {
                max = array[0];
            }
            else
            {

                for (node = 1; node <= array[0]; node++)
                {
                    if ((node * (node - 1) / 2) >= array[1])
                    {
                        break;
                    }
                }

                max = array[0] - node;
            }

            //max = Math.Max(0, max);

            Console.WriteLine("" + min + " " + max);
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class testcodeforces
{
    public static void Main()
    {
        int t = 1;

        for (int i = 0; i < t; i++)
        {
            var array = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
            long min = array[0] - (2 * array[1]);

            min = Math.Max(0, min);

            long max = 0;
            int node = 0;

            for (node = 1; node <= array[0]; node++)
            {
                if ((node * (node - 1) / 2) >= array[1])
                {
                    break;
                }
            }

            max = array[0] - node;

            //max = Math.Max(0, max);

            Console.WriteLine("" + min + " " + max);
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class testcodeforces
{
    public static void Main()
    {
        int t = 1;

        for (int i = 0; i < t; i++)
        {
            var array = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
            long min = array[0] - (2 * array[1]);

            long max = 0;
            int node = 0;

            for (node = 0; node < array[0]; node++)
            {
                if ((node * (node - 1) / 2) >= array[1])
                {
                    break;
                }
            }

            max = array[0] - node;

            Console.WriteLine("" + min + " " + max);
        }
    }
}

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

namespace W0lf
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] s = Console.ReadLine().Split(' ');
            int n = int.Parse(s[0]), m = int.Parse(s[1]), a = 0, b = 0;
            a = n - (m * 2);
            if(m != 0) b = n - m - 1;
            else b = a;
            Console.WriteLine(a + " " + b);
            Console.ReadLine();
        }
    }
}

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

namespace W0lf
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] s = Console.ReadLine().Split(' ');
            int n = int.Parse(s[0]), m = int.Parse(s[1]), a = 0, b = 0;
            a = n - (m * 2);
            b = n - m - 1;
            Console.WriteLine(a + " " + b);
            Console.ReadLine();
        }
    }
}

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

namespace W0lf
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] str = Console.ReadLine().Split(' ');
            long n = long.Parse(str[0]), m = long.Parse(str[1]), a = 0, b = 0;
            a = Math.Max(n - m * 2, 0);
            if(n == 1) b = 0;
            else if(m == 1) b = n - 2;
            else if(m == 0) b = a;
            else
            {
                for(long i = 2; i < n; i++)
                {
                    if(m > (i * (i - 1)) / 2 && m <= ((i + 1) * i) / 2)
                    {
                        b = n - (i + 1);
                        break;
                    }
                }
            }
            Console.WriteLine(a + " " + b);
            Console.ReadLine();
        }
    }
}

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

namespace W0lf
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] str = Console.ReadLine().Split(' ');
            long n = long.Parse(str[0]), m = long.Parse(str[1]), a = 0, b = 0;
            a = Math.Max(n - m * 2, 0);
            if(n == 1) b = 0;
            else if(m == 1) b = n - 2;
            else
            {
                for(long i = 2; i < n; i++)
                {
                    if(m > (i * (i - 1)) / 2 && m <= ((i + 1) * i) / 2)
                    {
                        b = n - (i + 1);
                        break;
                    }
                }
            }
            Console.WriteLine(a + " " + b);
            Console.ReadLine();
        }
    }
}

/*
csc -debug B.cs && mono --debug B.exe <<< "4 2"
*/

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

public class HelloWorld {
    static public void Main () {
        SolveCodeForces();
    }

    public static void SolveCodeForces() {
        var arr = Console.ReadLine().Split().Select(long.Parse).ToArray();
        var n = arr[0];
        var m = arr[1];

        var min = Math.Max(0, n - 2 * m);
        var max = 0L;

        if (m > 0)
            for (var x = 1; x <= n; x++) {
                if (x * (x - 1) / 2 >= m) {
                    max = n - x;
                    break;
                }
            }

        System.Console.WriteLine("{0} {1}", min, max);
    }
}

public static class Helpers {
    public static T[] CreateArray<T>(int length, Func<int, T> itemCreate) {
        var result = new T[length];
        for (var i = 0; i < result.Length; i++)
            result[i] = itemCreate(i);
        return result;
    }
}

/*
csc -debug B.cs && mono --debug B.exe <<< "4 2"
*/

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

public class HelloWorld {
    static public void Main () {
        SolveCodeForces();
    }

    public static void SolveCodeForces() {
        var arr = Console.ReadLine().Split().Select(long.Parse).ToArray();
        var n = arr[0];
        var m = arr[1];

        if (m == 0) {
            System.Console.WriteLine("{0} {1}", n, n);
            return;
        }
        if (n == 1) {
            System.Console.WriteLine("{0} {1}", n, n);
            return;
        }

        var min = Math.Max(0, n - 2 * m);
        var max = n;

        for (var x = 1; x <= n; x++) {
            if (x * (x - 1) / 2 >= m) {
                max = n - x;
                break;
            }
        }

        System.Console.WriteLine("{0} {1}", min, max);
    }
}

public static class Helpers {
    public static T[] CreateArray<T>(int length, Func<int, T> itemCreate) {
        var result = new T[length];
        for (var i = 0; i < result.Length; i++)
            result[i] = itemCreate(i);
        return result;
    }
}

using System;

class MainClass {
  public static void Main (string[] args) {
    string[] stringArray = Console.ReadLine().Split();
    long n = Int32.Parse(stringArray[0]);
    long m = Int32.Parse(stringArray[1]);
    long min = n - m * 2;
    long max = n - 1 - m;

    Console.WriteLine($"{min} {max}");
  }
}

using System;

class MainClass {
  public static void Main (string[] args) {
    string[] stringArray = Console.ReadLine().Split();
    long n = Int32.Parse(stringArray[0]);
    long m = Int32.Parse(stringArray[1]);
    long min = Math.Max(n - m * 2, 0);
    long k = (long)Math.Sqrt(2 * m);

    while ((k * k - 1) / 2 < m)
      k++;

    long max = n - k;

    Console.WriteLine($"{min} {max}");
  }
}

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

namespace Codeforces
{
	static class Program
	{

		static void Main(string[] args)
		{
			var nm = Console.ReadLine().Split().Select(int.Parse).ToList();
			int min = 0, max = 0;

			if (nm[1] != 0)
			{
				min = nm[0] - nm[1] * 2;
				max = nm[0] - 1 - nm[1];
			}
			Console.WriteLine($"{Math.Max(min, 0)} {Math.Max(max, 0)}");
			Console.ReadLine();
		}
	}
}

using System;
using System.Collections.Generic;
using static System.Console;
using static System.Math;

public class Hello{
    public static void Main(){
        string[] input = ReadLine().Split(' ');
        int tyouten = int.Parse(input[0]);
        long hen = long.Parse(input[1]);

        if(tyouten == 1){
            WriteLine("1 1");
        }else if(hen == 0){
            WriteLine("{0} {1}",tyouten,tyouten);
        }else{

        //min
        int tyoutemp = (tyouten+1)/2;
        int oe = tyouten%2;
        long tempmin = (tyoutemp - hen)*2-oe;
        long min = Max(tempmin,0);
        Write("{0} ",min);

        //Max
        int check = 0;
        for(int i=2;i<=tyouten;i++){
            long saidai = (i*(i-1))/2; //頂点i個に対して使える辺の最大値
            if(saidai >= hen){
                check = i;
                break;
            }
        }
        int max = tyouten - check;
        WriteLine(max);

        }
    }
}

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

namespace ConsoleApp97
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] first = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            long n = first[0];
            long k = first[1];

            if( n == 1)
            {
                Console.WriteLine("1 1");
            }
            else
            {
                if( k == 0)
                    Console.WriteLine( n + " " + n);
                else
                {
                    long min = n - k * 2;

                    if (min < 0)
                        min = 0;
                    // 2 0
                    long max = n - k - 1;
                    Console.WriteLine(min + " " + max);

                }

            }

            int aaa = 5;
            //1 2 9
            //10 1 1
        }
    }
}

using System;

public class Program
{
    public static void Main()
    {
        var line = Console.ReadLine().Split(' ');
        var vertexes = ulong.Parse(line[0]);
        var edges = ulong.Parse(line[1]);

        if (edges == 0)
        {
            Console.WriteLine($"{vertexes} {vertexes}");
        }

        ulong v;
        for (v = 1; v <= vertexes; ++v)
        {
            if ((v - 1) * ((v - 1) + 1) / 2 >= edges)
            {
                break;
            }
        }

        ulong max = vertexes - v;

        ulong totalRequired = vertexes % 2 == 0 ? vertexes / 2 : vertexes / 2 + 1;
        ulong min = 0;

        if (totalRequired <= edges)
        {
            min = 0;
        }
        else
        {
            var missing = (totalRequired - edges);
            if (vertexes % 2 == 0)
            {
                min = missing * 2;
            }
            else
            {
                min = (missing - 1) * 2 + 1;
            }
        }

        Console.WriteLine($"{min} {max}");
    }
}

using System;

public class Program
{
    public static void Main()
    {
        var line = Console.ReadLine().Split(' ');
        var vertexes = ulong.Parse(line[0]);
        var edges = ulong.Parse(line[1]);

        if (edges == 0)
        {
            Console.WriteLine($"{vertexes} {vertexes}");
        }

        ulong v;
        for (v = 1; v <= vertexes; ++v)
        {
            if ((v -1) * ((v -1) + 1) / 2 >= edges)
            {
                break;
            }
        }

        var max = vertexes - v;

        if (vertexes % 2 == 0)
        {
            if (edges > vertexes / 2)
            {
                Console.WriteLine($"0 {max}");
            }
            else
            {
                Console.WriteLine($"{(vertexes / 2 - edges) * 2} {max}");
            }
        }
        else
        {
            if (edges == (vertexes / 2) + 1)
            {
                Console.WriteLine($"0 {max}");
            }
            else if (edges == (vertexes / 2))
            {
                Console.WriteLine($"1 {max}");
            }
            else
            {
                Console.WriteLine($"{((vertexes / 2 - edges)) * 2 + 1} {max}");
            }
        }
    }
}

using System;

public class Program
{
    public static void Main()
    {
        var line = Console.ReadLine().Split(' ');
        var vertexes = ulong.Parse(line[0]);
        var edges = ulong.Parse(line[1]);

        if (edges == 0)
        {
            Console.WriteLine($"{vertexes} {vertexes}");
        }

        ulong v;
        for (v = 1; v <= vertexes; ++v)
        {
            if ((v - 1) * ((v - 1) + 1) / 2 >= edges)
            {
                break;
            }
        }

        ulong max = 0;
        if (v == vertexes + 1)
        {
            max = 0;
        }
        else
        {
            max = vertexes - v;
        }

        ulong totalRequired = vertexes % 2 == 0 ? vertexes / 2 : vertexes / 2 + 1;
        ulong min = 0;

        if (totalRequired <= edges)
        {
            min = 0;
        }
        else
        {
            var missing = (totalRequired - edges);
            if (vertexes % 2 == 0)
            {
                min = missing * 2;
            }
            else
            {
                min = (missing - 1) * 2 + 1;
            }
        }

        Console.WriteLine($"{min} {max}");
    }
}

using System;

public class Program
{
    public static void Main()
    {
        var line = Console.ReadLine().Split(' ');
        var vertexes = ulong.Parse(line[0]);
        var edges = ulong.Parse(line[1]);

        if (edges == 0)
        {
            Console.WriteLine($"{vertexes} {vertexes}");
        }

        ulong v;
        for (v = 1; v <= vertexes; ++v)
        {
            if (v * (v + 1) / 2 > edges)
            {
                break;
            }
        }

        var max = v - 1;

        if (vertexes % 2 == 0)
        {
            if (edges > vertexes / 2)
            {
                Console.WriteLine($"0 {max}");
            }
            else
            {
                Console.WriteLine($"{(vertexes / 2 - edges) * 2} {max}");
            }
        }
        else
        {
            if (edges == (vertexes / 2) + 1)
            {
                Console.WriteLine($"0 {max}");
            }
            else if (edges == (vertexes / 2))
            {
                Console.WriteLine($"1 {max}");
            }
            else
            {
                Console.WriteLine($"{((vertexes / 2 - edges)) * 2 + 1} {max}");
            }
        }
    }
}

using System;

public class Program
{
    public static void Main()
    {
        var line = Console.ReadLine().Split(' ');
        var vertexes = ulong.Parse(line[0]);
        var edges = ulong.Parse(line[1]);

        if (edges == 0)
        {
            Console.WriteLine($"{vertexes} {vertexes}");
        }

        ulong v;
        for (v = 1; v <= vertexes; ++v)
        {
            if ((v - 1) * ((v - 1) + 1) / 2 >= edges)
            {
                break;
            }
        }

        var max = vertexes - v;

        var totalRequired = vertexes % 2 == 0 ? vertexes / 2 : vertexes / 2 + 1;

        var min = totalRequired <= edges ? 0 : totalRequired - edges;

        Console.WriteLine($"{min} {max}");
    }
}

using System;

public class Program
{
    public static void Main()
    {
        var line = Console.ReadLine().Split(' ');
        var n = ulong.Parse(line[0]);
        var m = ulong.Parse(line[1]);

        if (m == 0)
        {
            Console.WriteLine($"{n} {n}");
        }

        ulong v;
        ulong s = 0;

        for (v = 0; s <= m && v <= n; ++v)
        {
            s += v;
        }

        var max = v >= n ? 0 : n - v;

        if (n % 2 == 0)
        {
            if (m > n / 2)
            {
                Console.WriteLine($"0 {max}");
            }
            else
            {
                Console.WriteLine($"{(n / 2 - m) * 2} {max}");
            }
        }
        else
        {
            if (m == (n / 2) + 1)
            {
                Console.WriteLine($"0 {max}");
            }
            else if (m == (n / 2))
            {
                Console.WriteLine($"1 {max}");
            }
            else
            {
                Console.WriteLine($"{((n / 2 - m)) * 2 + 1} {max}");
            }
        }
    }
}