Problem:
Score : 200 points

Problem Statement

You are going to take the entrance examination of Kyoto University tomorrow
and have decided to memorize a set of strings S that is expected to appear in the examination.
Since it is really tough to memorize S as it is,
you have decided to memorize a single string T that efficiently contains all the strings in S.

You have already confirmed the following conditions for S and T are satisfied.

Every string in S is a consecutive subsequence(1) in T .

For every pair of strings x, y (x \neq y) in S ,
x is not a subsequence(2) of y.

Note that (1) is ''consecutive subsequence'', while (2) is ''subsequence''.

The next day, you opened the problem booklet at the examination
and found that you can get a full score only if you remember S.
However, You have forgot how to reconstruct S from T .
Since all you remember is that T satisfies the above conditions,
first you have decided to find the maximum possible number of elements in S .

Constraints

1 \leq |T| \leq 10^5

T consists of only lowercase letters.

Partial points

30 points will be awarded for passing the test set satisfying the condition: 1 \leq |T| \leq 50 .

Another 30 points will be awarded for passing the test set satisfying the condition: 1 \leq |T| \leq 10^3.

Input

The input is given from Standard Input in the following format:

T

The input only consists of T on one line.

Output

Print the maximum number of elements inS .

Sample Input 1

abcabc

Sample Output 1

3

In this case, ab，ca and bc are an example of the optimum answers.

Sample Input 2

abracadabra

Sample Output 2

7

Sample Input 3

abcbabbcabbc

Sample Output 3

8

Sample Input 4

bbcacbcbcabbabacccbbcacbaaababbacabaaccbccabcaabba

Sample Output 4

44

Solution in C (GCC 5.4.1) (judge verdict: Accepted)

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<inttypes.h>
#include<string.h>

typedef int32_t i32;
typedef int64_t i64;

#define F 2

const i32 prime[2] = {1000000033, 1000000087};
const i32 rad = 27;

typedef struct hashNode {
  i32 val[F];
} node;

int cmp (const void *a, const void *b) {
  node *p = (node *) a;
  node *q = (node *) b;
  for (i32 i = 0; i < F; ++i) {
    i32 d = p->val[i] - q->val[i];
    if (d != 0) {
      return d < 0 ? -1 : 1;
    }
  }
  return 0;
}

i32 modPow (i32 r, i32 n, i32 mod) {
  i32 t = 1;
  i32 s = r;
  while (n > 0) {
    if (n & 1) t = (i64) t * s % mod;
    s = (i64) s * s % mod;
    n >>= 1;
  }
  return t;
}

void run (void) {
  char *s = (char *) calloc (100000 + 1, sizeof (char));
  scanf("%s", s);
  const i32 n = strlen (s);
  node *p = (node *) calloc (n, sizeof (node));
  i32 l = 0;
  i32 r = n;
  while (r - l > 1) {
    const i32 m = (l + r) / 2;
    const i32 len = m;
    i32 inv[F];
    node t;
    for (i32 i = 0; i < F; ++i) {
      t.val[i] = 0;
      inv[i] = modPow (rad, len - 1, prime[i]);
    }
    for (i32 i = 0; i < len - 1; ++i) {
      i32 d = s[i] - 'a' + 1;
      for (i32 k = 0; k < F; ++k) {
	t.val[k] = ((i64) t.val[k] * rad + d) % prime[k];
      }
    }
    i32 plen = 0;
    for (i32 i = len - 1; i < n; ++i) {
      i32 d = s[i] - 'a' + 1;
      for (i32 k = 0; k < F; ++k) {
	t.val[k] = ((i64) t.val[k] * rad + d) % prime[k];
      }
      p[plen++] = t;
      d = s[i - len + 1] - 'a' + 1;
      for (i32 k = 0; k < F; ++k) {
	t.val[k] = (t.val[k] - (i64) d * inv[k] % prime[k] + prime[k]) % prime[k];
      }
    }
    qsort (p, plen, sizeof (node), cmp);
    i32 i;
    for (i = 0; i < plen - 1; ++i) {
      if (cmp (p + i, p + i + 1) == 0) {
	break;
      }
    }
    if (i < plen - 1) {
      l = m;
    } else {
      r = m;
    }
  }
  printf("%" PRIi32 "\n", n - r + 1);
}

int main (void) {
  run ();
  return 0;
}