#include <bits/stdc++.h>
using namespace std;
long long int INF = 100000000000000000LL;
struct edge {
  int to;
  long long int cost;
};
typedef pair<long long int, int> P;
vector<edge> G[210000];
long long int d[210000];
void shortest_path(int s, int V) {
  priority_queue<P, vector<P>, greater<P> > que;
  for (int i = 0; i < V; i++) {
    d[i] = INF;
  }
  d[s] = 0;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first) {
      continue;
    }
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (d[e.to] > e.cost + d[v]) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}
vector<pair<int, int> > v;
int main() {
  string str;
  cin >> str;
  for (int i = 0; i < str.size(); i++) {
    edge e1;
    e1.to = i + 1;
    e1.cost = 1;
    G[i].push_back(e1);
  }
  for (int c = 0; c <= 26; c++) {
    v.erase(v.begin(), v.end());
    pair<int, int> hoge;
    hoge.first = 0;
    hoge.second = 0;
    v.push_back(hoge);
    int cur = 0;
    for (int i = 0; i < str.size(); i++) {
      if (str[i] != 'a' + c) {
        cur = (cur ^ (1 << (str[i] - 'a')));
        pair<int, int> p;
        p.first = cur;
        p.second = i;
        v.push_back(p);
      }
    }
    sort(v.begin(), v.end());
    int from = 0;
    for (int i = 0; i < v.size() - 1; i++) {
      if (v[i].first != v[i + 1].first) {
        if (from != v[i].second) {
          edge e;
          e.to = v[i].second + 1;
          e.cost = 1;
          if (c == 26) {
            e.cost--;
          }
          G[from + 1].push_back(e);
          string ss = "a ";
          ss[0] = 'a' + c;
        }
        from = v[i + 1].second;
      }
    }
  }
  shortest_path(0, str.size() + 1);
  for (int i = 0; i <= str.size(); i++) {
  }
  d[str.size()] = max(d[str.size()], 1LL);
  cout << d[str.size()] << endl;
  return 0;
}
