#include<iostream>
#include<fstream>
#include<string>
#include<map>
#include<vector>
#include<stack>

struct veza
{
    int l_granica;
    int d_granica;
    int snaga;
    int savijanje;  //Gde bi string morao biti savijen kako bi se veza uspotstavila
    int index;
};

struct node
{
    veza* v;
    std::vector<node*> sve_veze;
    std::vector<node*> sve_vise_veze;
    int ukupna_snaga = 0;
};

int main()
{
    std::string ulaz;
    std::cin >> ulaz;
    std::map<char, std::vector<int>> slova; //Svako pojavljivanje svakog slova
    std::vector<veza> veze;
    std::map<int, std::vector<veza>> veze_po_savijenom;   //Mapa veza gde je kljuc kako su savijene
    std::map<veza*, node> veze_veza;

    for(int i = 0; i < ulaz.length(); i++)
        slova[ulaz[i]].push_back(i);

    //Stvaranje veza izmedju slova
    int index = 0;
    for(auto& memb : slova)
    {
        std::vector<int>& pozicije = memb.second;
        for(int i = 0; i < pozicije.size()-1; i++)
            for(int j = i+1; j < pozicije.size(); j++)
            {
                if((pozicije[j] - pozicije[i]) & 1)
                {
                    veza temp = {pozicije[i], pozicije[j], 1, pozicije[i] + (pozicije[j] - pozicije[i])/2, index++};
                    veze.push_back(temp);
                    veze_po_savijenom[pozicije[i] + (pozicije[j] - pozicije[i])/2].push_back(temp);
                }
            }
    }

    for(auto& v : veze_po_savijenom)
    {
        std::vector<veza>& vektor_veza = v.second;
        int povecanje = 1;
        for(int i = 0; i < vektor_veza.size()-1; i++)
        {
            for(int j = i+1; j < vektor_veza.size(); j++)
            {
                if(vektor_veza[i].l_granica < vektor_veza[j].l_granica)
                    veze[vektor_veza[i].index].snaga++;
                else
                    veze[vektor_veza[j].index].snaga++;
            }
        }
    }

    for(auto& v : veze)
    {
        veze_veza[&v] = {&v};
    }

    for(auto& vv : veze_veza)
    {
        node& nv1 = vv.second;
        for(auto& vv2 : veze_veza)
        {
            node& nv2 = vv2.second;
            if(nv2.v->d_granica <= nv1.v->savijanje && nv1.v->l_granica > nv2.v->savijanje)
            {
                nv1.sve_veze.push_back(&nv2);
                nv2.sve_vise_veze.push_back(&nv1);
            }
        }
    }

    std::vector<node*> pocetne_tacke;

    for(auto& vv : veze_veza)
    {
        if(vv.second.sve_veze.size() == 0)
            pocetne_tacke.push_back(&vv.second);
    }
    
    int max = 0;

    for(auto& p : pocetne_tacke)
    {
        p->ukupna_snaga = p->v->snaga;
        std::stack<node*> sledeci;
        sledeci.push(p);
        while(sledeci.size() > 0)
        {
            node* trenutna = sledeci.top();
            sledeci.pop();
            for(auto& moguce_sledece : trenutna->sve_vise_veze)
            {
                if(moguce_sledece->ukupna_snaga < moguce_sledece->v->snaga + trenutna->ukupna_snaga)
                {
                    moguce_sledece->ukupna_snaga = moguce_sledece->v->snaga + trenutna->ukupna_snaga;
                    sledeci.push(moguce_sledece);
                }
            }
            if(trenutna->sve_vise_veze.size() == 0)
                max = (max > trenutna->ukupna_snaga)? max : trenutna->ukupna_snaga;
        }
    }

    std::cout << max << "\n";

    return 0;
}