#include <bits/stdc++.h>
using namespace std;
char s[222222];
int dat[222222];
int vis[222222];
map<int, vector<int>> pos;
map<int, vector<int>> parent;
int getparent(vector<int> &vt, int t) {
  return vt[t] == t ? t : vt[t] = getparent(vt, vt[t]);
}
void merge(vector<int> &vt, int a, int b) {
  a = getparent(vt, a);
  b = getparent(vt, b);
  vt[min(a, b)] = max(a, b);
}
int main() {
  scanf("%s", s + 1);
  int len = strlen(s + 1);
  for (int i = 1; i <= len; i++) {
    dat[i] = dat[i - 1] ^ (1 << (s[i] - 'a'));
    pos[dat[i]].push_back(i);
  }
  for (auto &e : pos) {
    parent[e.first].resize(e.second.size() + 1);
    for (int j = 0; j <= e.second.size(); j++) parent[e.first][j] = j;
  }
  queue<int> que;
  for (int x : pos[0]) {
    vis[x] = 1;
    que.push(x);
  }
  for (int i = 0; i < 26; i++) {
    if (pos.count(1 << i) == 0) continue;
    for (int x : pos[1 << i]) {
      vis[x] = 1;
      que.push(x);
    }
  }
  while (que.empty() == false) {
    int x = que.front();
    que.pop();
    for (int i = 0; i < 26; i++) {
      int nxt = dat[x] ^ (1 << i);
      if (pos.count(nxt) == 0) continue;
      int p =
          upper_bound(pos[nxt].begin(), pos[nxt].end(), x) - pos[nxt].begin();
      for (p = getparent(parent[nxt], p); p < pos[nxt].size();
           merge(parent[nxt], p, p + 1), p = getparent(parent[nxt], p)) {
        int y = pos[nxt][p];
        if (vis[y] == 0) {
          vis[y] = vis[x] + 1;
          que.push(y);
        }
      }
    }
  }
  printf("%d\n", vis[len]);
}
