#include <bits/stdc++.h>
using namespace std;
template <typename T>
T BigMod(T b, T p, T m) {
  if (p == 0) return 1;
  if (p % 2 == 0) {
    T s = BigMod(b, p / 2, m);
    return ((s % m) * (s % m)) % m;
  }
  return ((b % m) * (BigMod(b, p - 1, m) % m)) % m;
}
template <typename T>
T ModInv(T b, T m) {
  return BigMod(b, m - 2, m);
}
template <typename T>
T gcd(T a, T b) {
  if (!b) return a;
  return gcd(b, a % b);
}
char s[100003];
long long b1[100003], b2[100003], fh1[100003], fh2[100003];
long long wa[100003], wb[100003], wws[100003], wv[100003];
long long rnk[100003], height[100003];
long long sa[100003], data[100003], n;
char str[100003];
vector<pair<long long, long long> > ans;
long long cmp(long long *r, long long a, long long b, long long l) {
  return (r[a] == r[b]) && (r[a + l] == r[b + l]);
}
void SA(long long *r, long long *sa, long long n, long long m) {
  long long i, j, p, *x = wa, *y = wb, *t;
  for (i = 0; i < m; i++) wws[i] = 0;
  for (i = 0; i < n; i++) wws[x[i] = r[i]]++;
  for (i = 1; i < m; i++) wws[i] += wws[i - 1];
  for (i = n - 1; i >= 0; i--) sa[--wws[x[i]]] = i;
  for (j = 1, p = 1; p < n; j *= 2, m = p) {
    for (p = 0, i = n - j; i < n; i++) y[p++] = i;
    for (i = 0; i < n; i++)
      if (sa[i] >= j) y[p++] = sa[i] - j;
    for (i = 0; i < n; i++) wv[i] = x[y[i]];
    for (i = 0; i < m; i++) wws[i] = 0;
    for (i = 0; i < n; i++) wws[wv[i]]++;
    for (i = 1; i < m; i++) wws[i] += wws[i - 1];
    for (i = n - 1; i >= 0; i--) sa[--wws[wv[i]]] = y[i];
    for (t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i++)
      x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++;
  }
}
void LCP(long long *r, long long *sa, long long n) {
  long long i, j, k = 0;
  for (i = 1; i <= n; i++) rnk[sa[i]] = i;
  for (i = 0; i < n; height[rnk[i++]] = k)
    for (k ? k-- : 0, j = sa[rnk[i] - 1]; r[i + k] == r[j + k]; k++)
      ;
}
void pre() {
  b1[0] = 1;
  b2[0] = 1;
  long long i;
  for (i = 1; i <= 100003 - 2; i++) {
    b1[i] = (b1[i - 1] * 10000019) % 1000000007;
    b2[i] = (b2[i - 1] * 10000103) % 1000000021;
  }
}
int sp[100003][18];
void sparse(int n) {
  int i, j;
  for (i = 0; i <= n; i++) sp[i][0] = i;
  for (i = 1; (1 << i) <= n; i++) {
    for (j = 0; j + (1 << i) - 1 < n; j++) {
      if (height[sp[j][i - 1]] < height[sp[j + (1 << (i - 1))][i - 1]])
        sp[j][i] = sp[j][i - 1];
      else
        sp[j][i] = sp[j + (1 << (i - 1))][i - 1];
    }
  }
  return;
}
long long spval(long long lo, long long hi) {
  long long tot = hi - lo + 1;
  long long rng = log2(tot);
  return min(height[sp[lo][rng]], height[sp[lo + tot - (1 << rng)][rng]]);
}
long long bs(long long lo, long long hi, long long len) {
  long long md, tmp, val, res = -1;
  ;
  tmp = lo;
  while (lo <= hi) {
    md = (lo + hi) >> 1ll;
    val = spval(tmp, md);
    if (val >= len) {
      res = md;
      lo = md + 1;
    } else
      hi = md - 1;
  }
  return res;
}
int main() {
  pre();
  long long i, n1, n2, sz, x, idx;
  scanf("%s", &s);
  sz = strlen(s);
  n1 = n2 = 0;
  for (i = 0; i <= sz - 1; i++) {
    n1 = (((n1 * 10000019) % 1000000007) + (s[i] - 'A' + 1)) % 1000000007;
    n2 = (((n2 * 10000103) % 1000000021) + (s[i] - 'A' + 1)) % 1000000021;
    fh1[i] = n1;
    fh2[i] = n2;
  }
  n1 = n2 = 0;
  idx = 0;
  while (s[idx]) {
    data[idx] = (int)s[idx];
    idx++;
  }
  data[idx] = 0;
  SA(data, sa, idx + 1, (int)'Z' + 2);
  LCP(data, sa, idx);
  for (i = 0; i <= idx - 1; i++) {
    height[i] = height[i + 1];
    sa[i] = sa[i + 1];
  }
  sparse(idx);
  long long l, sth1, edh1, sth2, edh2, ind;
  for (i = 0; i <= idx - 1; i++) {
    x = sa[i];
    l = sz - x;
    sth1 = fh1[l - 1];
    sth2 = fh2[l - 1];
    edh1 = fh1[sz - 1] - ((fh1[sz - 1 - l] * b1[l]) % 1000000007);
    if (edh1 < 0) edh1 = (edh1 + 1000000007) % 1000000007;
    edh2 = fh2[sz - 1] - ((fh2[sz - 1 - l] * b2[l]) % 1000000021);
    if (edh2 < 0) edh2 = (edh2 + 1000000021) % 1000000021;
    if (sth1 != edh1 || sth2 != edh2) continue;
    ind = bs(i + 1, idx - 1, l);
    (ind == -1) ? ans.push_back(make_pair(l, 1))
                : ans.push_back(make_pair(l, ind - i + 1));
  }
  sort(ans.begin(), ans.end());
  sz = ans.size();
  printf("%lld\n", sz);
  for (i = 0; i <= sz - 1; i++)
    printf("%lld %lld\n", ans[i].first, ans[i].second);
  return 0;
}
