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++14 (GCC 5.4.1) (judge verdict: Accepted)

#include "bits/stdc++.h"
using namespace std;
#define FOR(i,j,k) for(int (i)=(j);(i)<(int)(k);++(i))
#define rep(i,j) FOR(i,0,j)
#define each(x,y) for(auto &(x):(y))
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define debug(x) cout<<#x<<": "<<(x)<<endl
#define smax(x,y) (x)=max((x),(y))
#define smin(x,y) (x)=min((x),(y))
#define MEM(x,y) memset((x),(y),sizeof (x))
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;

struct RollingHash{
    static const int C = 31, C2 = 29, P = 1000000007, P2 = 1000000009;
    int _n;
    vector<long long> pw, pw2, hs, hs2;

    RollingHash(){}
    RollingHash(const string &st)
        :_n((int)st.size()), pw(_n+1),pw2(_n+1),hs(_n+1),hs2(_n+1)
    {
        pw[0] = pw2[0] = 1;
        for(int i = 0; i < _n; ++i){
            pw[i+1] = (pw[i]*C)%P;
            pw2[i+1] = (pw2[i]*C2)%P2;
            hs[i+1] = (C*hs[i]+st[i])%P;
            hs2[i+1] = (C2*hs2[i]+st[i])%P2;
        }
    }

    // [l, r)
    pii getHash(int l, int r){
        int res, res2;
        res = (hs[r] - hs[l] * pw[r - l]) % P;
        res2 = (hs2[r] - hs2[l]*pw2[r-l])%P2;
        if(res < 0)res += P;
        if(res2 < 0)res2 += P2;
        return make_pair(res, res2);
    }
};

string nstr(){
    static const int MAX_LEN = 500001;
    static char res_[MAX_LEN];
    scanf("%s",res_);
    return string(res_);
}

vector<vector<int>> divisorsAll(int n){
    vector<vector<int>> res(n + 1);
    for(int i = 1; i <= n; ++i){
        for(int j = i; j <= n; j+=i){
            res[j].push_back(i);
        }
    }
    return res;
}

RollingHash rh;
vector<vector<int>> di;

int f(int l, int r){
    int len = r - l;
    rep(i, sz(di[len]) - 1){
        int d = di[len][i];
        if(rh.getHash(l, r - d) == rh.getHash(l + d, r)){
            return 0;
        }
    }
    return 1;
}

int main(){
    string S = nstr();
    int N = sz(S);
    if(count(all(S), S[0]) == N){
        printf("%d\n%d\n", N, 1);
        return 0;
    }
    rh = RollingHash(S);
    di = divisorsAll(N);
    if(f(0, N)){
        printf("%d\n%d\n", 1, 1);
        return 0;
    }

    int ans = 0;
    for(int x = 1; x < N; ++x){
        if(f(0, x) && f(x, N)){
            ans++;
        }
    }
    printf("%d\n%d\n", 2, ans);
}