// Original C++ solution (slower):
#include <map>

#include <set>

#include <ctime>

#include <queue>

#include <stack>

#include <cmath>

#include <vector>

#include <bitset>

#include <cstdio>

#include <cctype>

#include <string>

#include <numeric>

#include <cstring>

#include <cassert>

#include <climits>

#include <cstdlib>

#include <iostream>

#include <algorithm>

#include <functional>

using namespace std ;

//#define int long long

#define rep(i, a, b) for (int i = (a); i <= (b); i++)

#define per(i, a, b) for (int i = (a); i >= (b); i--)

#define loop(s, v, it) for (s::iterator it = v.begin(); it != v.end(); it++)

#define cont(i, x) for (int i = head[x]; i; i = e[i].nxt)

#define clr(a) memset(a, 0, sizeof(a))

#define ass(a, sum) memset(a, sum, sizeof(a))

#define lowbit(x) (x & -x)

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

#define ub upper_bound

#define lb lower_bound

#define pq priority_queue

#define mp make_pair

#define pb push_back

#define fi first

#define se second

#define iv inline void

#define enter cout << endl

#define siz(x) ((int)x.size())

#define file(s) freopen(s".in", "r", stdin), freopen(s."out", "w", stdout)

typedef long long ll ;

typedef unsigned long long ull ;

typedef pair <int, int> pii ;

typedef vector <int> vi ;

typedef vector <pii> vii ;

typedef queue <int> qi ;

typedef queue <pii> qii ;

typedef set <int> si ;

typedef map <int, int> mii ;

typedef map <string, int> msi ;

const int N = 500010 ;

const int INF = 0x3f3f3f3f ;

const int iinf = 1 << 30 ;

const ll linf = 2e18 ;

const int MOD = 1000000007 ;

const double eps = 1e-7 ;

void print(int x) { cout << x << endl ; exit(0) ; }

void PRINT(string x) { cout << x << endl ; exit(0) ; }

void douout(double x){ printf("%lf\n", x + 0.0000000001) ; }



char s[N] ;

int f[N], g[N], nxt[N] ;

int n, ans ;



void work(int *f) {

	nxt[1] = 0 ;

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

		while (j && s[i] != s[j + 1]) j = nxt[j] ;

		if (s[i] == s[j + 1]) j++ ;

		nxt[i] = j ;

	}

	rep(i, 1, n)

	if (i % (i - nxt[i]) > 0 || nxt[i] == 0) f[i] = true ;

}



signed main(){

    scanf("%s", s + 1) ; n = strlen(s + 1) ;

	work(f) ;

	reverse(s + 1, s + n + 1) ;

	work(g) ;

	if (f[n]) {

		printf("1\n1\n") ;

		return 0 ;

	}

	rep(i, 1, n) if (f[i] && g[n - i]) ans++ ;

	if (ans == 0) printf("%d\n1\n", n) ;

	else printf("2\n%d\n", ans) ;

	return 0 ;

}



/*

写代码时请注意：

	1.ll？数组大小，边界？数据范围？

	2.精度？

	3.特判？

	4.至少做一些

思考提醒：

	1.最大值最小->二分？

	2.可以贪心么？不行dp可以么

	3.可以优化么

	4.维护区间用什么数据结构？

	5.统计方案是用dp？模了么？

	6.逆向思维？

*/




// Optimized solution to the same problem (faster):
#include <cmath>

#include <cstdio>

#include <cstring>

#include <algorithm>

using std::min; using std::max;

using std::swap; using std::sort;

typedef long long ll;



template<typename T>

void read(T &x) {

	int flag = 1; x = 0; char ch = getchar();

	while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }

	while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();

	x *= flag;

}



const int _ = 5e5 + 10, P = 1e9 + 7;

int n, p[_], s[_]; char c[_];



int chk0(int r) {

	int len = r, now = len % (len - p[r]);

	if(!now) return len / (len - p[r]) == 1;

	return 1;

}



int chk1(int l) {

	int len = n - l + 1, now = len % (len - s[l]);

	if(!now) return len / (len - s[l]) == 1;

	return 1;

}



int main () {

	scanf("%s", c + 1), n = strlen(c + 1);

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

		int j = p[i - 1];

		while(j && c[j + 1] != c[i]) j = p[j];

		j += c[j + 1] == c[i], p[i] = j;

	}

	std::reverse(c + 1, c + n + 1);

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

		int j = s[i - 1];

		while(j && c[j + 1] != c[i]) j = s[j];

		j += c[j + 1] == c[i], s[i] = j;

	}

	std::reverse(s + 1, s + n + 1);

	std::reverse(c + 1, c + n + 1);

	int now = n - p[n];

	if(now == 1) return printf("%d\n%d\n", n, 1), 0;

	if(n % now == 0 && n / now > 1) {

		printf("%d\n", 2);

		int ret = 0;

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

			if(chk0(i) && chk1(i + 1)) ++ret;

		printf("%d\n", ret);

	} else printf("%d\n%d\n", 1, 1);

	return 0;

} 


// Fastest known solution for this problem: