#include <bits/stdc++.h>
using namespace std;
const int MAX_L = (int)1e6 + 5;
char str[MAX_L];
int z[MAX_L], len, occurs[MAX_L];
set<pair<int, int> > s;
set<int> exis;
void z_func() {
  static int k, l, r, i, j;
  z[0] = len;
  k = -1;
  l = -1;
  r = -1;
  for (i = 1; i < len; i++)
    if (i > r) {
      for (j = 0; i + j < len && str[i + j] == str[j]; j++) {
      }
      z[i] = j;
      if (z[i]) tie(k, l, r) = make_tuple(i, i, i + z[i] - 1);
    } else {
      if (z[i - l] < r - i) {
        z[i] = z[i - l];
      } else {
        for (z[i] = r - i; str[i + z[i]] == str[z[i]]; z[i]++) {
        }
        tie(k, l, r) = make_tuple(i, i, i + z[i] - 1);
      }
    }
}
int main() {
  scanf("%s", str);
  len = strlen(str);
  z_func();
  for (int i = 0; i < len; i++)
    if (z[i]) occurs[z[i]]++;
  for (int i = 0; i < len; i++)
    if (i + z[i] == len) exis.insert(z[i]);
  for (int i = len - 1; i > 0; i--) occurs[i] = occurs[i + 1] + occurs[i];
  for (int i = len; i >= 1; i--)
    if (exis.count(i) && occurs[i] != occurs[i + 1]) s.insert({i, occurs[i]});
  printf("%d\n", s.size());
  for (auto& x : s) printf("%d %d\n", x.first, x.second);
}
