#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1e6 + 5;
char s[MAXN];
int n = 0;
int tot = 1, last = 1;
struct Suffix_Automaton {
int len, fth;
int ch[26];
Suffix_Automaton() {//NOLINT
len = fth = 0;
for (int &i :ch)i = 0;
}
} sam[MAXN * 2];//NOLINT
struct Edge {
int to, next;
} edge[MAXN * 2];
int start[MAXN * 2];
long long sum[MAXN * 2];
long long ans = 0;
inline void Build(int c) {
int p = last, np = last = ++tot;
sam[np].len = sam[p].len + 1;
sum[np] = 1;
for (; p && !sam[p].ch[c]; p = sam[p].fth)
sam[p].ch[c] = np;
if (!p) {
sam[np].fth = 1;
return;
}
int q = sam[p].ch[c];
if (sam[q].len == sam[p].len + 1) {
sam[np].fth = q;
return;
}
int nq = ++tot;
sam[nq] = sam[q];
sam[nq].len = sam[p].len + 1;
sam[q].fth = sam[np].fth = nq;
for (; p && sam[p].ch[c] == q; p = sam[p].fth)
sam[p].ch[c] = nq;
}
void dfs(int p) {
for (int i = start[p]; i; i = edge[i].next) {
dfs(edge[i].to);
sum[p] += sum[edge[i].to];
}
if (sum[p] >= 2)ans = max(ans, sum[p] * sam[p].len);
}
signed main() {
scanf("%s", s + 1);
n = strlen(s + 1);
for (int i = 1; i <= n; i++)Build(s[i] - 'a');
for (int i = 2; i <= tot; i++) {
edge[i] = {i, start[sam[i].fth]};
start[sam[i].fth] = i;
}
dfs(1);
printf("%lld\n", ans);
return 0;
}