#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
struct SAM {
  int len, ch[26], par, cnt;
} sam[N << 1];
void dfs(int u);
void insert(int x);
void add(int u, int v);
int head[N << 1], nxt[N << 1], to[N << 1], cnt;
int n, p, tot, ans[N][2], anstot;
bool suf[N << 1];
char s[N];
int main() {
  int i, u;
  scanf("%s", s + 1);
  n = strlen(s + 1);
  u = p = tot = 1;
  for (i = 1; i <= n; ++i) insert(s[i] - 'A');
  while (p > 1) {
    suf[p] = true;
    p = sam[p].par;
  }
  for (i = 2; i <= tot; ++i) add(sam[i].par, i);
  dfs(1);
  for (i = u = 1; i <= n; ++i) {
    u = sam[u].ch[s[i] - 'A'];
    if (suf[u]) {
      ans[++anstot][0] = i;
      ans[anstot][1] = sam[u].cnt;
    }
  }
  printf("%d\n", anstot);
  for (i = 1; i <= anstot; ++i) printf("%d %d\n", ans[i][0], ans[i][1]);
  return 0;
}
void dfs(int u) {
  int i, v;
  for (i = head[u]; i; i = nxt[i]) {
    v = to[i];
    dfs(v);
    sam[u].cnt += sam[v].cnt;
  }
}
void insert(int x) {
  int np = ++tot;
  sam[np].len = sam[p].len + 1;
  sam[np].cnt = 1;
  while (p && !sam[p].ch[x]) {
    sam[p].ch[x] = np;
    p = sam[p].par;
  }
  if (!p)
    sam[np].par = 1;
  else {
    int q = sam[p].ch[x];
    if (sam[q].len == sam[p].len + 1)
      sam[np].par = q;
    else {
      int nq = ++tot;
      sam[nq].len = sam[p].len + 1;
      memcpy(sam[nq].ch, sam[q].ch, sizeof(sam[q].ch));
      sam[nq].par = sam[q].par;
      sam[q].par = sam[np].par = nq;
      while (p && sam[p].ch[x] == q) {
        sam[p].ch[x] = nq;
        p = sam[p].par;
      }
    }
  }
  p = np;
}
void add(int u, int v) {
  nxt[++cnt] = head[u];
  head[u] = cnt;
  to[cnt] = v;
}
