#include <algorithm>
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

struct SuffixArray {
    string s;
    vector<int> sa, rev;
    SuffixArray(const string &str) : s(str) {
        s += '$';
        int n = s.size();
        sa.resize(n);
        iota(begin(sa), end(sa), 0);
        sort(begin(sa), end(sa), [&](int a, int b) {
            return s[a] == s[b] ? a > b : s[a] < s[b];
        });
        vector<int> classes(n), c(begin(s), end(s)), cnt(n);
        for (int len = 1; len < n; len <<= 1) {
            for (int i = 0; i < n; i++) {
                classes[sa[i]] = i;
                if (i == 0 || c[sa[i-1]] != c[sa[i]]) continue;
                if (sa[i-1] + len < n && c[sa[i-1] + len/2] == c[sa[i] + len/2]) {
                    classes[sa[i]] = classes[sa[i-1]];
                }
            }
            iota(begin(cnt), end(cnt), 0);
            copy(begin(sa), end(sa), begin(c));
            for(int i = 0; i < n; i++) {
                int s1 = c[i] - len;
                if (s1 >= 0) sa[cnt[classes[s1]]++] = s1;
            }
            classes.swap(c);
        }
        rev.resize(n);
        for (int i = 0; i < n; i++) rev[sa[i]] = i;
    }
    int operator[](int i) const { return sa[i]; }
    bool lt_substr(string &t, int si, int ti) {
        int sn = s.size(), tn = t.size();
        while (si < sn && ti < tn) {
            if (s[si] < t[ti]) return true;
            if (s[si] > t[ti]) return false;
            si++, ti++;
        }
        return si == sn && ti < tn;
    }
    int lower_bound(string &t) {
        int l = 0, r = s.size();
        while (l + 1 < r) {
            int m = (l + r) >> 1;
            (lt_substr(t, sa[m], 0) ? l : r) = m;
        }
        return r;
    }
    int upper_bound(string &t) {
        t.back()++;
        int res = lower_bound(t);
        t.back()--;
        return res;
    }
    // O(|T|*log|S|)
    int count(string &t) { return upper_bound(t) - lower_bound(t); }
};
struct LongestCommonPrefix {
    SuffixArray sa;
    vector<int> ht;
    vector<vector<int>> dat;
    LongestCommonPrefix(string &s) : sa(s) {
        int n = s.length();
        vector<int> lcp(n);
        int t = 0;
        lcp[0] = 0;
        for (int i = 0; i < n; i++) {
            int j = sa[sa.rev[i] - 1];
            if (t > 0) t--;
            while (j + t < n && i + t < n && sa.s[j + t] == sa.s[i + t]) t++;
            lcp[sa.rev[i] - 1] = t;
        }
        int h = 1;
        while ((1 << h) < n) h++;
        dat.assign(h, vector<int>(n));
        ht.assign(n + 1, 0);
        for (int j = 2; j <= n; j++) ht[j] = ht[j >> 1] + 1;
        for (int j = 0; j < n; j++) dat[0][j] = lcp[j];
        for (int i = 1, p = 1; i < h; i++, p <<= 1)
            for (int j = 0; j < n; j++)
                dat[i][j] = min(dat[i - 1][j], dat[i - 1][min(j + p, n - 1)]);
    }
    int query(int a, int b) {       // a, b are indices for suffix array
        if (a > b) swap(a, b);
        int l = b - a;
        return min(dat[ht[l]][a], dat[ht[l]][b - (1 << ht[l])]);
    }
    int lcp(int a, int b) {         // lcp of s.sutstr(a) and s.substr(b)
        return query(sa.rev[a], sa.rev[b]);
    }
};

vector<vector<int>> divisors_table(int n) {     // except for n
    vector<vector<int>> divisors(n + 1);
    for (int i = 1; i <= n; i++) {
        for (int j = i + i; j <= n; j += i) divisors[j].emplace_back(i);;
    }
    return divisors;
}

int main() {
    string s; cin >> s;
    int n = s.length();
    if (s == string(n, s[0])) return !(cout << n << endl << 1 << endl);
    LongestCommonPrefix lcp(s);
    auto ds = divisors_table(n);
    {
        bool good = true;
        for (int d: ds[n]) if (lcp.lcp(0, d) >= n - d) good = false;
        if (good) return !(cout << 1 << endl << 1 << endl);
    }
    vector<int> good(n, true), doog(n, true);
    for (int i = 1; i < n; i++) for (int d: ds[i]) {
        if (lcp.lcp(0, d) >= i - d) good[i] = false;
        if (lcp.lcp(n - i, n - i + d) >= i - d) doog[n - i] = false;
    }
    int cnt = 0;
    for (int i = 1; i < n; i++) cnt += good[i] && doog[i];
    cout << 2 << endl << cnt << endl;
    return 0;
}


Measured memory_bytes: 103724