Problem:
Score : 700 points

Problem Statement

We have a string s consisting of lowercase English letters.
Snuke is partitioning s into some number of non-empty substrings.
Let the subtrings obtained be s_1, s_2, ..., s_N from left to right. (Here, s = s_1 + s_2 + ... + s_N holds.)
Snuke wants to satisfy the following condition:

For each i (1 \leq i \leq N), it is possible to permute the characters in s_i and obtain a palindrome.

Find the minimum possible value of N when the partition satisfies the condition.

Constraints

1 \leq |s| \leq 2 \times 10^5

s consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

s

Output

Print the minimum possible value of N when the partition satisfies the condition.

Sample Input 1

aabxyyzz

Sample Output 1

2

The solution is to partition s as aabxyyzz = aab + xyyzz.
Here, aab can be permuted to form a palindrome aba, and xyyzz can be permuted to form a palindrome zyxyz.

Sample Input 2

byebye

Sample Output 2

1

byebye can be permuted to form a palindrome byeeyb.

Sample Input 3

abcdefghijklmnopqrstuvwxyz

Sample Output 3

26

Sample Input 4

abcabcxabcx

Sample Output 4

3

The solution is to partition s as abcabcxabcx = a + b + cabcxabcx.

Solution in C++14 (Clang 3.8.0) (judge verdict: Time Limit Exceeded)

#include<algorithm>
#include<cmath>
#include<iomanip>
#include<iostream>
#include<map>
#include<numeric>
#include<queue>
#include<set>
#include<sstream>
#include<unordered_map>
#include<unordered_set>
#include<vector>
using uint = unsigned int;
using ll = long long;
enum : int { M = (int)1e9 + 7 };
enum : ll { MLL = (ll)1e18L + 9 };
using namespace std;
#ifdef LOCAL
#include"rprint2.hpp"
#else
#define FUNC(name) template <ostream& out = cout, class... T> void name(T&&...){ }
FUNC(prints) FUNC(printe) FUNC(printw) FUNC(printew) FUNC(printb) FUNC(printd) FUNC(printde);
#endif

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    string s; cin >> s;
    auto ok = [&](vector<int> &cs){
        int a1 = 0;
        for(int i = 0; i < 26; i++){
            a1 += cs[i] % 2;
        }
        return a1 <= 1;
    };
    vector<int> cs(26);
    for(auto e : s){
        cs[e - 'a']++;
    }
    int ans = 1;
    if(ok(cs)){
        cout << ans << '\n';
        return 0;
    }
    int end = s.size();

    // vector<int> accs(end + 1);
    // int bits = 0;
    // for(size_t i = 0; i < s.size(); i++){
    //     bits ^= 1 << (s[i] - 'a');
    //     accs[i + 1] = bits;
    // }
    // auto ok2 = [&](int l, int r){
    //     int b = accs[r] ^ accs[l - 1];
    //     int num = 0;
    //     for(int i = 0; i < 30; i++){
    //         num += b & (1 << i);
    //     }
    //     return num <= 1;
    // };
    // printb(accs[end], accs[0]);
    // cout << ok2(1, end) << '\n';

    vector<int> memo(end + 1, 0);
    function<int(int)> solve = [&](int idx){
        if(idx >= end){ return 0; }
        if(memo[idx]){ return memo[idx]; }
        int idx0 = idx;
        int ret = 1e6;
        vector<int> cs3(26);
        int odds = 0;
        for(; idx < end; idx++){
            if(odds == 0){
                ret = min(ret, solve(idx + 1) + 1);
            }
            cs3[s[idx] - 'a']++;
            if(cs3[s[idx] - 'a'] % 2){
                odds++;
            }else{
                odds--;
            }
            // if(odds <= 1){
            //     ret = min(ret, solve(idx + 1) + 1);
            // }
        }
        if(odds <= 1){
            return 1;
        }
        return memo[idx0] = ret;
    };
    cout << solve(0) << '\n';
}