#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-11;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
typedef pair<ld, ld> LDP;
typedef unsigned long long ul;
string s;
vector<int> d;
const int mn = 500001;
bool leok[mn], riok[mn];
bool lesk[mn], risk[mn];
int main() {
	cin >> s;
	int n = s.length();
	int k = sqrt(n + 0.1);
	rep1(i, k) {
		if (n%i != 0)continue;
		d.push_back(i);
		d.push_back(n / i);
	}
	sort(d.begin(), d.end());
	int len = unique(d.begin(), d.end()) - d.begin();
	int m = n;
	rep(i, len) {
		int l = d[i];
		int r = n / l;
		bool valid = true;
		rep(j, r - 1) {
			string le = s.substr(j*l, l);
			string ri = s.substr((j + 1)*l, l);
			if (le != ri) {
				valid = false; break;
			}
		}
		if (valid) {
			m = l; break;
		}
	}
	if (m == 1) {
		cout << n << endl << 1 << endl;
	}
	else if (m == n) {
		cout << 1 << endl << 1 << endl;
	}
	else {
		if (n <= 400000) {
			fill(leok, leok + n + 1, true);
			fill(riok, riok + n + 1, true);
			for (int i = 2 * m; i <= n; i += m) {
				leok[i] = false;
				lesk[i] = true;
			}
			for (int i = n - 2 * m; i >= 0; i -= m) {
				riok[i] = false;
				risk[i] = true;
			}
			rep1(i, n) {
				if (lesk[i])continue;
				else {
					int le = 0, ri = i;
					while (ri + i <= n) {
						bool valid = true;
						rep(j, i) {
							if (s[le + j] != s[ri + j]) {
								valid = false; break;
							}
						}
						if (valid) {
							ri += i; le += i;
							leok[ri] = false;
							lesk[ri] = true;
						}
						else {
							lesk[ri] = true;
							break;
						}
					}
				}
			}
			rep1(i, n) {
				if (risk[n - i])continue;
				else {
					int le = n - i, ri = n;
					while (le - i >= 0) {
						bool valid = true;
						rep(j, i) {
							if (s[le + j] != s[le + j - i]) {
								valid = false; break;
							}
						}
						if (valid) {
							le -= i; ri -= i;
							riok[le] = false;
							risk[le] = true;
						}
						else {
							risk[le] = true;
							break;
						}
					}
				}
			}
			int cnt = 0;
			rep1(i, n) {
				if (leok[i] && riok[i])cnt++;
			}
			cout << 2 << endl;
			cout << cnt << endl;
		}
		else {
			fill(leok, leok + m + 1, true);
			fill(riok, riok + m + 1, true);
			rep1(i, m) {
				if (lesk[i])continue;
				else {
					int le = 0, ri = i;
					while (ri + i <= m) {
						bool valid = true;
						rep(j, i) {
							if (s[le + j] != s[ri + j]) {
								valid = false; break;
							}
						}
						if (valid) {
							ri += i; le += i;
							leok[ri] = false;
							lesk[ri] = true;
						}
						else {
							lesk[ri] = true;
							break;
						}
					}
				}
			}
			rep1(i, m) {
				if (risk[m - i])continue;
				else {
					int le = m - i, ri = m;
					while (le - i >= 0) {
						bool valid = true;
						rep(j, i) {
							if (s[le + j] != s[le + j - i]) {
								valid = false; break;
							}
						}
						if (valid) {
							le -= i; ri -= i;
							riok[le] = false;
							risk[le] = true;
						}
						else {
							risk[le] = true;
							break;
						}
					}
				}
			}
			int cnt = 0;
			int r = n / m;
			cnt += (r - 2)*(m - 1);
			if (r == 2)cnt++;
			rep1(i, m - 1) {
				if (leok[i])cnt++;
			}
			rep1(i, m - 1) {
				if (riok[i])cnt++;
			}
			cout << 2 << endl;
			cout << cnt << endl;
		}
	}
	//stop
	return 0;
}


Measured memory_bytes: 1924