#include <bits/stdc++.h>
#include <boost/format.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/optional.hpp>

#ifdef DEBUG
#include "libs/debug.cpp"
#define DEBUG 1
#else
#define DEBUG 0
#endif

#define rep(i, n) repr((i), 0, (n))
#define repr(i, a, t) reps((i), (a), (t), 1)
#define reps(i, a, t, s) for (long long (i) = (a); (i) < (long long)(t); (i) += (s))
#define rrep(i, n) rrepr((i), (n), 0)
#define rrepr(i, a, t) rreps((i), (a), (t), 1)
#define rreps(i, a, t, s) for (long long (i) = (a) - 1; (i) >= (long long)(t); (i) -= (s))
#define each(v, c) for (auto &&(v) : (c))
#define all(c) (c).begin(), (c).end()

using namespace std;
namespace mp = boost::multiprecision;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using ml = mp::cpp_int;
template<typename T>
using optional = boost::optional<T>;
const auto none = boost::none;
const long long MOD = 1e9 + 7;
const long long INF = 1e18;

unordered_map<string, ll> memo;

ll solve(ll l,
         ll r,
         unordered_map<char, ll> &total,
         vector<unordered_map<char, ll>> &lefts,
         vector<unordered_map<char, ll>> &rights) {
  string lr = to_string(l) + "," + to_string(r);
  if (memo.count(lr)) return memo[lr];
  if (l + 1 == r) return memo[lr] = 1;

  unordered_map<char, ll> counts;
  repr (c, 'a', 'z' + 1) counts[c] = total[c] - lefts[l][c] - rights[r - 1][c];
  ll odds = 0;
  repr (c, 'a', 'z' + 1) odds += counts[c] % 2;
  if (odds <= 1) return memo[lr] = 1;

  ll ret = INF;
  repr (i, l + 1, r) {
    ret = min(ret, solve(l, i, total, lefts, rights) + solve(i, r, total, lefts, rights));
  }
  return memo[lr] = ret;
}

int main() {
  cout << fixed << setprecision(10);
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  ifstream ifs;
  if (DEBUG) {
    ifs.open("src/_in.txt");
    cin.rdbuf(ifs.rdbuf());
  }

  string S;
  cin >> S;
  ll N = S.size();

  vector<unordered_map<char, ll>> lefts;
  vector<unordered_map<char, ll>> rights;
  unordered_map<char, ll> total;
  rep (i, N) {
    unordered_map<char, ll> zeros;
    repr (c, 'a', 'z' + 1) zeros[c] = 0;
    lefts.emplace_back(zeros);
  }
  rep (i, N) {
    unordered_map<char, ll> zeros;
    repr (c, 'a', 'z' + 1) zeros[c] = 0;
    rights.emplace_back(zeros);
  }

  repr (i, 1, N) {
    repr (c, 'a', 'z' + 1) {
      lefts[i][c] = lefts[i - 1][c] + (S[i - 1] == c);
    }
  }
  rrep (i, N - 1) {
    repr (c, 'a', 'z' + 1) {
      rights[i][c] = rights[i + 1][c] + (S[i + 1] == c);
    }
  }

  each (c, S) {
    if (total.count(c)) {
      total[c] += 1;
    } else {
      total[c] = 1;
    }
  }

  ll ans = solve(0, N, total, lefts, rights);
  cout << ans << "\n";

}