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 Rust (1.15.1) (judge verdict: Wrong Answer)

fn get_line() -> String {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().to_string()
}

use std::collections::HashMap;

fn main() {
    let xs: Vec<char> = get_line().chars().collect();

    let mut bs = vec![1; xs.len() + 1];
    let mut cs = vec![1; xs.len() + 1];

    let mut hbs: HashMap<char, u64> = HashMap::new();
    for (i, x) in xs.iter().enumerate() {
        if hbs.contains_key(x) {
            *hbs.get_mut(x).unwrap() += 1;
        }
        else {
            hbs.insert(*x, 1);
        }

        let mut o = false;
        let mut f = true;
        for &v in hbs.values() {
            if !o && v % 2 == 1 {
                o = true;
            }
            else if o && v % 2 == 1 {
                f = false;
                break;
            }
        }

        if !f {
            bs[i + 1] = bs[i] + 1;
        }
    }
    bs[0] = 0;

    hbs.clear();
    for i in 0..xs.len() {
        let i = xs.len() - i - 1;

        if hbs.contains_key(&xs[i]) {
            *hbs.get_mut(&xs[i]).unwrap() += 1;
        }
        else {
            hbs.insert(xs[i], 1);
        }

        let mut o = false;
        let mut f = true;
        for &v in hbs.values() {
            if !o && v % 2 == 1 {
                o = true;
            }
            else if o && v % 2 == 1 {
                f = false;
                break;
            }
        }

        if !f {
            cs[i] = cs[i + 1] + 1;
        }
    }
    cs[xs.len()] = 0;

    let mut res = xs.len() as u64;
    for i in 0..(xs.len() + 1) {
        if res > bs[i] + cs[i] {
            res = bs[i] + cs[i];
        }
    }

    println!("{}", res);
}