#include <bits/stdc++.h>
using namespace std;
ifstream ifs;
void init(string s) { ifs.open(s); }
vector<string> split(const string &str, char sep) {
  vector<string> v;
  stringstream ss(str);
  string buffer;
  while (getline(ss, buffer, sep)) v.push_back(buffer);
  return v;
}
long long int read() {
  string str;
  getline(ifs, str);
  return stoll(str);
}
string read_str() {
  string str;
  getline(ifs, str);
  return str;
}
vector<long long int> read_vec() {
  string str;
  getline(ifs, str);
  std::vector<long long int> num;
  vector<string> data = split(str, ' ');
  for (int i = 0; i < data.size(); i++) num.push_back(stoll(data[i]));
  return num;
}
vector<vector<long long int>> read_mat(long long int h) {
  string str;
  vector<vector<long long int>> num =
      vector<vector<long long int>>(h, vector<long long int>(0, 0));
  for (int i = 0; i < h; i++) {
    getline(ifs, str);
    vector<string> data = split(str, ' ');
    for (int j = 0; j < data.size(); j++) num[i].push_back(stoll(data[j]));
  }
  return num;
}
struct Dijkstra {
  long long int INF = 1000000000000000009;
  long long int MAX_V = 1000000;
  long long int st = -1;
  struct edge {
    long long int to, cost;
  };
  vector<vector<edge>> G;
  vector<long long int> pre, d;
  priority_queue<pair<long long int, long long int>,
                 vector<pair<long long int, long long int>>,
                 greater<pair<long long int, long long int>>>
      que;
  Dijkstra(long long int s) {
    G.resize(s + 2);
    pre.resize(s + 2, -1);
    d.resize(s + 2, INF);
  }
  inline void insert(long long int a, long long int b, long long int c) {
    G[a].push_back(edge{b, c});
  }
  void init() {
    for (int i = 0; i < d.size(); i++) pre[i] = -1, d[i] = INF;
  }
  void dijkstra(int start) {
    init();
    st = start;
    d[start] = 0;
    que.push(pair<long long int, long long int>(0, start));
    while (!que.empty()) {
      pair<long long int, long long int> p_now = que.top();
      que.pop();
      long long int v = p_now.second;
      if (d[v] < p_now.first) continue;
      for (int i = 0; i < G[v].size(); i++) {
        edge e = G[v][i];
        if (d[e.to] > d[v] + e.cost) {
          d[e.to] = d[v] + e.cost;
          pre[e.to] = v;
          que.push(pair<long long int, long long int>(d[e.to], e.to));
        }
      }
    }
  }
  vector<long long int> get_path(int now) {
    vector<long long int> ret;
    while (now != -1) {
      ret.push_back(now);
      now = pre[now];
    }
    return ret;
  }
};
int main(int argc, char const *argv[]) {
  string s;
  std::cin >> s;
  long long int n = s.size(), num = 0;
  map<long long int, long long int> mp;
  vector<long long int> m(n);
  mp.emplace(0, 0);
  for (int i = 0; i < n; i++) {
    num ^= (1 << (s[i] - 'a'));
    m[i] = num;
    if (mp.find(num) == mp.end()) mp.emplace(num, i + 1);
  }
  Dijkstra dj(200001);
  for (int i = 1; i <= n; i++) {
    dj.insert(i - 1, i, 1);
    for (int j = 0; j < 27; j++) {
      long long int t = m[i - 1];
      t = (j == 26 ? t : t ^ (1 << j));
      if (mp.find(t) == mp.end() || mp.at(t) >= i) continue;
      dj.insert(mp.at(t), i, (j == 26 ? 0 : 1));
    }
  }
  dj.dijkstra(0);
  std::cout << (dj.d[n] == 0 ? 1 : dj.d[n]) << '\n';
  return 0;
}
