Problem:
Score : 900 points

Problem Statement

Let x be a string of length at least 1.
We will call x a good string, if for any string y and any integer k (k \geq 2), the string obtained by concatenating k copies of y is different from x.
For example, a, bbc and cdcdc are good strings, while aa, bbbb and cdcdcd are not.

Let w be a string of length at least 1.
For a sequence F=(\,f_1,\,f_2,\,...,\,f_m) consisting of m elements,
we will call F a good representation of w, if the following conditions are both satisfied:

For any i \, (1 \leq i \leq m), f_i is a good string.

The string obtained by concatenating f_1,\,f_2,\,...,\,f_m in this order, is w.

For example, when w=aabb, there are five good representations of w:

(aabb)

(a,abb)

(aab,b)

(a,ab,b)

(a,a,b,b)

Among the good representations of w, the ones with the smallest number of elements are called the best representations of w.
For example, there are only one best representation of w=aabb: (aabb).

You are given a string w. Find the following:

the number of elements of a best representation of w

the number of the best representations of w, modulo 1000000007 \, (=10^9+7)

(It is guaranteed that a good representation of w always exists.)

Constraints

1 \leq |w| \leq 500000 \, (=5 \times 10^5)

w consists of lowercase letters (a-z).

Partial Score

400 points will be awarded for passing the test set satisfying 1 \leq |w| \leq 4000.

Input

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

w

Output

Print 2 lines.

In the first line, print the number of elements of a best representation of w.

In the second line, print the number of the best representations of w, modulo 1000000007.

Sample Input 1

aab

Sample Output 1

1
1

Sample Input 2

bcbc

Sample Output 2

2
3

In this case, there are 3 best representations of 2 elements:

(b,cbc)

(bc,bc)

(bcb,c)

Sample Input 3

ddd

Sample Output 3

3
1

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Math;
using MethodImplAttribute = System.Runtime.CompilerServices.MethodImplAttribute;
using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions;

public static class P
{
    public static void Main()
    {
        string s = Console.ReadLine();
        RollingHash rh = new RollingHash(s);
        if (s.Distinct().Count() == 1)
        {
            Console.WriteLine(s.Length);
            Console.WriteLine(1);
            return;
        }
        bool[] isBad = new bool[s.Length];
        for (int i = 1; i < s.Length; i++)
        {
            var hash = rh[0..i];
            for (int j = i * 2; j <= s.Length; j += i)
            {
                if (rh[(j - i)..j] != hash) break;
                isBad[j - 1] = true;
            }
        }
        if (!isBad.Last())
        {
            Console.WriteLine(1);
            Console.WriteLine(1);
            return;
        }
        bool[] isBadFromTail = new bool[s.Length];
        for (int i = 1; i < s.Length; i++)
        {
            var hash = rh[^i..];
            for (int j = i * 2; j <= s.Length; j += i)
            {
                if (rh[^j..^(j - i)] != hash) break;
                isBadFromTail[^j] = true;
            }
        }
        int res = 0;
        for (int i = 1; i < s.Length; i++)
        {
            if (isBad[i - 1] || isBadFromTail[i]) continue;
            res++;
        }
        Console.WriteLine(2);
        Console.WriteLine(res);
    }
}


class RollingHash
{
    const ulong MASK30 = (1UL << 30) - 1;
    const ulong MASK31 = (1UL << 31) - 1;
    const ulong MOD = (1UL << 61) - 1;
    const ulong POSITIVIZER = MOD * ((1UL << 3) - 1);
    static uint Base;
    static ulong[] powMemo = new ulong[500000 + 1];
    static RollingHash()
    {
        Base = (uint)new Random().Next(129, int.MaxValue);
        powMemo[0] = 1;
        for (int i = 1; i < powMemo.Length; i++)
            powMemo[i] = CalcMod(Mul(powMemo[i - 1], Base));
    }

    ulong[] hash;

    public int Length => hash.Length - 1;
    public RollingHash(string s)
    {
        hash = new ulong[s.Length + 1];
        for (int i = 0; i < s.Length; i++)
            hash[i + 1] = CalcMod(Mul(hash[i], Base) + s[i]);
    }

    public ulong Slice(int begin, int length)
    {
        return CalcMod(hash[begin + length] + POSITIVIZER - Mul(hash[begin], powMemo[length]));
    }

    private static ulong Mul(ulong l, ulong r)
    {
        var lu = l >> 31;
        var ld = l & MASK31;
        var ru = r >> 31;
        var rd = r & MASK31;
        var middleBit = ld * ru + lu * rd;
        return ((lu * ru) << 1) + ld * rd + ((middleBit & MASK30) << 31) + (middleBit >> 30);
    }

    private static ulong Mul(ulong l, uint r)
    {
        var lu = l >> 31;
        var rd = r & MASK31;
        var middleBit = lu * rd;
        return (l & MASK31) * rd + ((middleBit & MASK30) << 31) + (middleBit >> 30);
    }

    private static ulong CalcMod(ulong val)
    {
        val = (val & MOD) + (val >> 61);
        if (val >= MOD) val -= MOD;
        return val;
    }
}