using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.SymbolStore;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net.WebSockets;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Numerics;
//using System.Data;
//using System.Drawing;

namespace ConsoleApp3
{
    class Program
    {
        static int solve_req(string s)
        {
            int i = 1;
            string tren = "" + s[0];
            string prosli = "";
            int zb = 0;
            return solvereq(s, i, tren, prosli,new Dictionary<string, int>());
        }
        static int solvereq(string s, int i, string tren, string prosli, Dictionary<string,int> lookup)
        {
            if (i == s.Length)
            {
                return 0;
            }
            tren += s[i];
            string key = i + "|" + tren + "|" + prosli;
            if(!lookup.ContainsKey(key))
            {
                if (prosli.Length - tren.Length >= 0)
                {
                    if (prosli[prosli.Length - tren.Length] == tren[tren.Length - 1])
                    {
                        return lookup[key]=1 + Math.Max(solvereq(s, i + 1, tren, prosli, lookup), solvereq(s, i + 1, "", tren, lookup));
                    }
                    else return lookup[key] = Math.Max(solvereq(s, i + 1, tren, prosli, lookup), solvereq(s, i + 1, "", tren, lookup));
                }
                else return lookup[key] = Math.Max(solvereq(s, i + 1, tren, prosli, lookup), solvereq(s, i + 1, "", tren, lookup));
            }
            return lookup[key];
        }
        static void Main(string[] args)
        {
            string s = Console.ReadLine();
            Console.WriteLine(solve_req(s));
        }
    }
}