Problem:
Score : 300 points

Problem Statement

You are given an integer N.

For two positive integers A and B, we will define F(A,B) as the larger of the following: the number of digits in the decimal notation of A, and the number of digits in the decimal notation of B.

For example, F(3,11) = 2 since 3 has one digit and 11 has two digits.

Find the minimum value of F(A,B) as (A,B) ranges over all pairs of positive integers such that N = A \times B.

Constraints

1 \leq N \leq 10^{10}

N is an integer.

Input

The input is given from Standard Input in the following format:

N

Output

Print the minimum value of F(A,B) as (A,B) ranges over all pairs of positive integers such that N = A \times B.

Sample Input 1

10000

Sample Output 1

3

F(A,B) has a minimum value of 3 at (A,B)=(100,100).

Sample Input 2

1000003

Sample Output 2

7

There are two pairs (A,B) that satisfy the condition: (1,1000003) and (1000003,1). For these pairs, F(1,1000003)=F(1000003,1)=7.

Sample Input 3

9876543210

Sample Output 3

6

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

#pragma warning disable

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Numerics;
using System.Collections;
using System.Timers;
using System.Threading;
// using System.Threading.Tasks;

static class MainClass
{
    public static void Main(string[] args)
    {
        var N = Console.ReadLine().ToInt64();
        var numss = PrimeFactorize(N).OrderByDescending(x => x);
        var a = 1l;
        var b = 1l;
        foreach (var item in numss)
        {
            if (a < b)
                a *= item;
            else
                b *= item;
        }
        Console.WriteLine(Math.Max(Math.Floor(Math.Log10(a) + 1),Math.Floor(Math.Log10(b) + 1)));
        Console.ReadLine();
    }


    #region ライブラリ

    #region 文字列処理
    public static long ToInt64(this string str) => long.Parse(str);
    public static int ToInt32(this string str) => int.Parse(str);
    public static BigInteger ToBigInteger(this string str) => BigInteger.Parse(str);
    public static List<string> SplittedStringToList(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
    public static List<int> SplittedStringToInt32List(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();

    public static List<BigInteger> SplittedStringToBigInteger(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => BigInteger.Parse(x)).ToList();
    #endregion
    #region DeepClone
    public static T DeepClone<T>(this T src)
    {
        using (var memoryStream = new MemoryStream())
        {
            var binaryFormatter
              = new BinaryFormatter();
            binaryFormatter.Serialize(memoryStream, src);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return (T)binaryFormatter.Deserialize(memoryStream);
        }
    }
    #endregion

    public static int Gcd(int a, int b)
    {
        if (b == 0)
            return a;
        return Gcd(b, a % b);
    }
    public static BigInteger Gcd(BigInteger a, BigInteger b)
    {
        if (b == 0)
            return a;
        return Gcd(b, a % b);
    }

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

    public static BigInteger Factorial(int n)
    {
        var dp = new BigInteger[n];
        dp[0] = 1;
        for (int i = 1; i < n; i++)
        {
            dp[i] = dp[i - 1] * (i + 1);
        }
        return dp[n - 1];
    }

    public static List<long> PrimeFactorize(long n)
    {
        var bases = n;
        var num = (long)Math.Pow(n, 0.5);
        var ls = new List<long>();
        for (int i = 2; i <= num; i++)
        {
            if (n % i == 0)
            {
                n = n / i;
                ls.Add(i);
                i--;
                continue;
            }
        }
        long nnn = 1;
        foreach (var item in ls)
        {
            nnn = nnn * item;
        }
        if (nnn != bases)
            ls.Add(n);
        return ls;
    }
    public static class PrimeNumber
    {

        static long[] seedPrimes = {
        2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
    };

        public static bool IsPrime(long num)
        {
            if (num == 1)
                return false;
            if (seedPrimes.Contains(num))
                return true;
            if (seedPrimes.Any(x => num % x == 0))
                return false;

            return (num < 2000000) ? IsPrimeBruteforce(num) : IsPrimeMillarRrabin(num);
        }

        private static bool IsPrimeBruteforce(long num)
        {
            if (num == 1)
                return false;
            if (num != 2 && num % 2 == 0)
                return false;
            if (num != 3 && num % 3 == 0)
                return false;
            if (num != 5 && num % 5 == 0)
                return false;
            long i = 0;
            while (true)
            {
                foreach (var p in seedPrimes.Skip(3).Take(8))
                {
                    var primeCandidte = p + i;
                    if (primeCandidte > Math.Sqrt(num))
                        return true;
                    if (num % (primeCandidte) == 0)
                        return false;
                }
                i += 30;
            }
        }

        private static bool IsPrimeMillarRrabin(long num)
        {
            if (num <= 1)
                return false;
            if ((num & 1) == 0)
                return num == 2;

            if (num < 100 && seedPrimes.Contains((int)num))
                return true;

            var WitnessMax = GetWitnessMax(num);

            long d = num - 1;
            long s = 0;
            while ((d & 1) == 0)
            {
                s++;
                d >>= 1;
            }
            foreach (var w in seedPrimes.Take(WitnessMax))
            {
                if (!MillarRrabin(num, s, d, w))
                    return false;
            }
            return true;
        }


        private static int GetWitnessMax(long num)
        {
            if (num < 2047)
                return 1;
            if (num < 1373653)
                return 2;
            if (num < 25326001)
                return 3;
            if (num < 3215031751)
                return 4;
            if (num < 2152302898747)
                return 5;
            if (num < 3474749660383)
                return 6;
            if (num < 341550071728321)
                return 7;
            if (num < 3825123056546413051)
                return 9;
            return 12;
        }


        private static bool MillarRrabin(long num, long s, long d, long witness)
        {
            long x = ModPow(witness, d, num);
            if (x == 1)
                return true;
            for (long r = 0; r < s; r++)
            {
                if (x == num - 1)
                    return true;
                BigInteger rem;
                BigInteger.DivRem(BigInteger.Multiply(x, x), num, out rem);
                x = (long)(rem);
            }
            return false;
        }

        private static long ModPow(long baseValue, long exponent, long modulus)
        {
            return (long)BigInteger.ModPow(baseValue, exponent, modulus);
        }

    }

    // 多分約数つくるやつ
    public static List<long> Make(long n)
    {
        var ls = new List<long>();
        // ls.Add(1);
        for (int i = 1; i*i <= n; i++)
        {
            if (n % i == 0)
            {
                ls.Add(i);
                if (i != 1 && i * i != n)
                {
                    ls.Add(n / i);
                }
            }
        }
        return ls;
    }
    #region 二分探索
    public static int LowerBound<T>(this IEnumerable<T> ar, int start, int end, T value, IComparer<T> comparer)
    {
        var arr = ar.ToArray();
        int low = start;
        int high = end;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (comparer.Compare(arr[mid], value) < 0)
                low = mid + 1;
            else
                high = mid;
        }
        return low;
    }

    public static int LowerBound<T>(this IEnumerable<T> arr, T value) where T : IComparable
    {
        return LowerBound(arr, 0, arr.Count(), value, Comparer<T>.Default);
    }

    public static int UpperBound<T>(this IEnumerable<T> ar, int start, int end, T value, IComparer<T> comparer)
    {
        var arr = ar.ToArray();
        int low = start;
        int high = end;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (comparer.Compare(arr[mid], value) <= 0)
                low = mid + 1;
            else
                high = mid;
        }
        return low;
    }

    public static int UpperBound<T>(this IEnumerable<T> arr, T value)
    {
        return UpperBound(arr, 0, arr.Count(), value, Comparer<T>.Default);
    }
    #endregion
    // AOJ - Power
    public static BigInteger Power(BigInteger m,BigInteger n,int p)
    {
        BigInteger amari = 1;
        while (true)
        {
            if (n / 2 >= 1)
            {
                BigInteger b = m;
                m *= m;
                if (n % 2 == 1)
                {
                    amari *= b;
                    amari %= p;
                }
                n /= 2;
            }
            m %= p;
            if (n / 2== 0)
            {
                break;
            }
        }
        return (m * amari) % p;
    }
    #endregion

}