#![allow(unused_imports, unused_variables, dead_code)]
use std::io::*;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

trait InputValue {
    fn parse(s: &str) -> Self;
}

fn read<T: InputValue>() -> T {
    let mut buf = String::new();
    let _ = stdin().read_line(&mut buf);
    T::parse(&buf.trim())
}

fn readnc<T: InputValue>() -> Vec<T> {
    let mut vec = vec![];
    let line: String = read();
    for token in line.split_whitespace() {
        vec.push(T::parse(token));
    }
    vec
}

fn readn<T: InputValue>(n: usize) -> Vec<T> {
    let mut vec = vec![];
    for _ in 0..n {
        vec.push(read());
    }
    vec
}

macro_rules! parse_single_value {
        ($($t:ty),*) => {
            $(
                impl InputValue for $t {
                    fn parse(s: &str) -> $t { s.parse().unwrap() }
                }
            )*
    	}
    }
parse_single_value!(i32, i64, f32, f64, usize, String);

macro_rules! parse_tuple {
    	($($t:ident),*) => {
    		impl<$($t),*> InputValue for ($($t),*) where $($t: InputValue),* {
    			fn parse(s: &str) -> ($($t),*) {
    				let mut tokens = s.split_whitespace();
    				let t = ($($t::parse(tokens.next().unwrap())),*);
    				t
    			}
    		}
    	}
    }
parse_tuple!(A, B);
parse_tuple!(A, B, C);

// ===

const INF: usize = 10000000;

fn main() {
    let s: String = read();
    let s: Vec<u8> = s.into_bytes();

    let mut map = HashMap::new();
    let mut flg = 0;
    let mut pl = 0;
    map.insert(flg, pl);
    pl += 1;

    let n = s.len();
    for i in 0..n {
        let idx = (s[i] - 'a' as u8) as usize;
        flg ^= 1<<idx;
        if !map.contains_key(&flg) {
            map.insert(flg, pl);
            pl += 1;
        }
    }

    let mut dp = vec![INF; n+100];
    let mut last = 0;
    dp[0] = 0;
    flg = 0;
    for i in 0..n {
        let idx = (s[i] - 'a' as u8) as usize;
        flg ^= 1<<idx;


        let mut best = INF;
        for l in 0..26 {
            let bf = flg ^ (1<<l);
            if map.contains_key(&bf) {
                let &bi = map.get(&bf).unwrap();
                best = min(best, dp[bi]);
            }
        }
        let &fi = map.get(&flg).unwrap();
        dp[fi] = min(dp[fi], best + 1);
        last = dp[fi];
    }

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