// Slower C++ solution:
#include <bits/stdc++.h>



#define int long long



using namespace std;



const int N = 5e5 + 5;

const int base = 317;

const int mod = 1e9 + 2277;



string s;

int Hash[N], pw[N], n;

bool pref[N], suff[N];



void buildHash(){

    s = "#" + s;

    pw[0] = 1;

    for (int i = 1; i < N; i++) pw[i] = (pw[i - 1] * base) % mod;

    Hash[0] = 0;

    for (int i = 1; i <= n; i++) Hash[i] = (Hash[i - 1] * base + s[i]) % mod;

}



int get (int l, int r) {

    return ((1LL * Hash[r] - 1LL * Hash[l - 1] * pw[r - l + 1]) % mod + mod) % mod;

}



signed main(){

    ios::sync_with_stdio(false);

    cin.tie(0);

    cout.tie(0);



    cin >> s;

    n = s.length();



    bool same = true;

    for (int i = 0; i < n; i++) if (s[i] != s[0]) same = false;

    if (same) {

        cout << n << "\n" << 1;

        return 0;

    }



    buildHash();

    memset(pref, 0, sizeof(pref));

    memset(suff, 0, sizeof(suff));



    for (int i = 1; i <= n; i++) {

        for (int j = i * 2; j <= n; j = j + i) {

            if (get(1, i) == get(j - i + 1, j)) pref[j] = true;

            else break;

        }

    }



    for (int i = 1; i <= n; i++) {

        for (int j = n - i * 2 + 1; j >= 1; j = j - i) {

            if (get(j, j + i - 1) == get(n - i + 1, n)) suff[j] = true;

            else break;

        }

    }



    if (!pref[n]) return cout << 1 << "\n" << 1, 0;

    int ans = 0;

    for (int i = 1; i < n; i++) if (!pref[i] && !suff[i + 1]) ans++;

    cout << 2 << "\n" << ans;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.0249479302402458x):
#include <bits/stdc++.h>

using namespace std;

typedef long long lint;

typedef unsigned long long ulint;

typedef pair<int, int> pii;

typedef pair<lint, lint> pll;

#define endl '\n'

#define next next_

#define fst first

#define sed second

#define pb push_back

#define mp make_pair

#define rint register int

#define newline putchar('\n')

#define leave_space puthchar(' ')

#define all(x) (x).begin(), (x).end()

#define reveal(x) cerr << #x << " = " << (x) << endl

#define rep(it, f, e) for (rint it = f; it <= e; ++it)

#define per(it, f, e) for (rint it = f; it >= e; --it)

const int MAXN = 5e5 + 20;

char s[MAXN], t[MAXN];

int n, fail1[MAXN], fail2[MAXN];

inline void getfail(int fail[], char s[]) {

	int j = 0;

	fail[0] = -1;

	rep (i, 1, n - 1) { 

		while (j && s[i] != s[j]) j = fail[j];

		fail[i + 1] = s[i] == s[j] ? ++j : 0;

	}

}

inline bool check_cyc1(int x) {

	return fail1[x] == 0 || x % (x - fail1[x]);

}

inline bool check_cyc2(int x) {

	if (x == 0) return false;

	return fail2[x] == 0 || x % (x - fail2[x]);

}

int main() {

	scanf("%s", s);

	n = strlen(s);

	memcpy(t, s, sizeof(t));

	reverse(t, t + n);

	getfail(fail1, s);

	getfail(fail2, t);

	int res = check_cyc1(n) ? 1 : 2;

	bool flag = true;

	rep (i, 1, n - 1) {

		if (s[i] != s[i - 1]) {

			flag = false;

			break;

		}

	}

	if (flag) {

		cout << n << endl;

		cout << 1 << endl;

	} else if (res == 1) {

		cout << 1 << endl;

		cout << 1 << endl;

	} else {

		int ans = 0;

		rep (i, 0, n - 1) {

			ans += (check_cyc1(i + 1) && check_cyc2(n - i - 1));

		}

		cout << 2 << endl;

		cout << ans << endl;

	}

	return 0;

}