#include <bits/stdc++.h>
using namespace std;
long long int MOD = 1000000007;
long double EPS = 1e-9;
template <class second, class T>
ostream& operator<<(ostream& os, const pair<second, T>& p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <class T>
ostream& operator<<(ostream& os, const vector<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, const unordered_set<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class second, class T>
ostream& operator<<(ostream& os, const unordered_map<second, T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, const set<T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class second, class T>
ostream& operator<<(ostream& os, const map<second, T>& p) {
  os << "[ ";
  for (auto& it : p) os << it << " ";
  return os << "]";
}
template <class T>
void dbs(string str, T t) {
  cerr << str << " : " << t << "\n";
}
template <class T, class... second>
void dbs(string str, T t, second... s) {
  int idx = str.find(',');
  cerr << str.substr(0, idx) << " : " << t << ",";
  dbs(str.substr(idx + 1), s...);
}
template <class T>
void prc(T a, T b) {
  cerr << "[";
  for (T i = a; i != b; ++i) {
    if (i != a) cerr << ", ";
    cerr << *i;
  }
  cerr << "]\n";
}
void pre() {}
vector<long long int> z_function(string& s) {
  long long int n = s.length();
  vector<long long int> z(n);
  for (long long int i = 1, l = 0, r = 0; i < n; ++i) {
    if (i <= r) {
      z[i] = min(r - i + 1, z[i - l]);
    }
    while (i + z[i] < n && s[z[i]] == s[i + z[i]]) {
      ++z[i];
    }
    if (i + z[i] - 1 > r) {
      l = i, r = i + z[i] - 1;
    }
  }
  return z;
}
void solve() {
  string s;
  cin >> s;
  vector<long long int> zz = z_function(s);
  zz[0] = s.length();
  map<int, int> mp;
  for (long long int i = 0; i < s.length(); ++i) {
    if (zz[i]) mp[zz[i]]++;
  }
  vector<pair<long long int, long long int> > arr((mp).begin(), (mp).end());
  reverse((arr).begin(), (arr).end());
  for (int i = 1; i < arr.size(); i++) {
    arr[i].second += arr[i - 1].second;
  }
  reverse((arr).begin(), (arr).end());
  vector<pair<long long int, long long int> > fin;
  for (auto v : arr) {
    if (zz[s.length() - v.first] == v.first) fin.emplace_back(v);
  }
  cout << fin.size() << '\n';
  for (long long int i = 0; i < fin.size(); ++i) {
    cout << fin[i].first << " " << fin[i].second << '\n';
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  pre();
  int t = 1;
  for (int i = 1; i <= t; i++) {
    solve();
  }
}
