/*YYC is Thinking Here*/
#include<bits/stdc++.h>
#define int long long
#define mids(l,r) const auto mid = l + r >> 1
#define ls (x<<1)
#define rs (ls|1)
#define lb(x) x&-x
#define cint const int&
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e6+10;
struct { int len, p, nxt[26]; }t[maxn];
struct { int nxt,v; }edge[maxn<<1];
int cnt,lst,siz[maxn]; char s[maxn];
inline void push(char c) {
int cur = ++cnt;
siz[cur] = 1;
t[cur].len = t[lst].len + 1;
int p = lst;
while(p && !t[p].nxt[c]) {
t[p].nxt[c] = cur;
p = t[p].p;
}
const int q = t[p].nxt[c];
if(!q) t[p].nxt[c] = cur, t[cur].p = 0;
else {
if(t[p].len + 1 == t[q].len) {
t[cur].p = q;
} else {
const int cl = ++cnt;
t[cl] = t[q];
t[cl].len = t[p].len + 1;
t[q].p = t[cur].p = cl;
while(t[p].nxt[cl] == q) {
t[p].nxt[c] = cl;
p = t[p].p;
}
}
}
lst = cur;
}
int head[maxn],ec;
inline void addedge(int u,int v) {
edge[++ec] = {head[u],v};
head[u] = ec;
}
int dfs(int u) {
int ans = 0;
for(int i = head[u];i;i=edge[i].nxt) {
const int v = edge[i].v;
dfs(v);
siz[u] += siz[v];
if(siz[v] > 1) ans = max(ans,siz[v] * t[v].len);
}
return ans;
}
signed main() {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios::sync_with_stdio(0),cin.tie(0);
cin>>s+1;
for(int i = 1;s[i];++i) push(s[i]-'a');
for(int i = 1;i<=cnt;++i) addedge(t[i].p,i);
cout<<dfs(0);
}
/*
* I love it all
* Go forward,move forward !
*/