#include <bits/stdc++.h>
using namespace std;
const double PI = 3.14159265358979323846;
const double EPS = 1e-9;
const long long INF = 10e17;
double equal(double a, double b) { return fabs(a - b) < DBL_EPSILON; }
std::istream &operator>>(std::istream &in, set<int> &o) {
  int a;
  in >> a;
  o.insert(a);
  return in;
}
std::istream &operator>>(std::istream &in, queue<int> &o) {
  long long a;
  in >> a;
  o.push(a);
  return in;
}
bool contain(set<int> &s, int a) { return s.find(a) != s.end(); }
bool is_kaibun(vector<int> &hs, int i, int j) {
  int k = hs[j] ^ (i == 0 ? 0 : hs[i - 1]);
  int f = __builtin_popcount(k);
  return f <= 1;
}
int main() {
  string s;
  cin >> s;
  int n = s.size();
  vector<int> hs(n, 0);
  for (int i = 0; i < (n); ++i) {
    if (i == 0) {
      char c = s[i];
      int j = c - 'a';
      int next = 1 << j;
      hs[0] = next;
    } else {
      char c = s[i];
      int j = c - 'a';
      int next = hs[i - 1] ^ (1 << j);
      hs[i] = next;
    }
  }
  vector<int> dp(n, -1);
  map<int, int> cache;
  cache[0] = -1;
  for (int i = 0; i < (n); ++i)
    if (cache.find(hs[i]) == cache.end()) cache[hs[i]] = i;
  auto set = [&](int i, int k) {
    if (dp[i] == -1)
      dp[i] = k;
    else
      dp[i] = min(dp[i], k);
  };
  auto get = [&](int i) {
    if (i == -1) return 0;
    return dp[i];
  };
  for (int i = 0; i < n; i++) {
    {
      dp[i] = get(i - 1) + 1;
      int current = hs[i];
      int j = cache[current];
      set(i, get(j) + 1);
    }
    for (int a = 0; a < (26); ++a) {
      int current = (1 << a) ^ hs[i];
      if (cache.find(current) == cache.end() || cache[current] > i) continue;
      int j = cache[current];
      set(i, get(j) + 1);
    }
  }
  cout << dp[n - 1] << endl;
}
