
#include <stdio.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <string.h>
#include <bitset>
using namespace std;

/*
typedef long long ll;
bool Finish_read;
template<class T>
inline void read(T &x) {
	Finish_read=0;x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}
	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
	x*=f;Finish_read=1;
}
template<class T>
inline void print(T x) {
	if(x/10!=0)
		print(x/10);
	putchar(x%10+'0');
}
template<class T>
inline void writeln(T x) {
	if(x<0)
		putchar('-');
	x=abs(x);
	print(x);
	putchar('\n');
}
template<class T>
inline void write(T x) {
	if(x<0)
		putchar('-');
	x=abs(x);
	print(x);
}
/*================Header Template==============*/
const int mx=(1<<26);
int pos[mx],f[200010];
char s[200010];
bitset<26> x[200010];
int main() {
	scanf("%s",s+1);
	int n=strlen(s+1);
	f[0]=0;
	memset(pos,-1,sizeof pos);
	pos[0]=0;
	for(int i=1;i<=n;i++) {
		x[i]^=x[i-1];
		x[i][s[i]-'a']=1-x[i][s[i]-'a'];
		f[i]=2e9;
		int t=x[i].to_ulong(),ind=i;
		for(int j=0;j<26;j++) {
			int tmp=(1<<j)^t;
			if(pos[tmp]!=-1&&f[ind]>f[pos[tmp]])
				ind=pos[tmp];
		}
		if(pos[t]!=-1&&f[ind]>f[pos[t]])
			ind=pos[t];
		f[i]=f[ind]+1;
		if(pos[t]==-1||f[i]<f[pos[t]])
			pos[t]=i;
	}
	printf("%d\n",f[n]);
	return 0;
}
/*
int is_palindrome_candidate(vector<int> str_stat)
{
int odd_count = 0;
for(int i=0; i<26; i++)
{
if(1 == str_stat[i]%2) {
odd_count++;
if(odd_count>1)
return 0;
}		
}
return 1;
}

int main(int argc, char** argv)
{
	std::string S;
	std::cin>>S;	
	int len = S.length();
	int n = 1;
	vector<int> cut_nums(len, 0);
	vector<int> cut_pos;
	vector<vector<int>> ch_stat;
	vector<int> tmp_stat(26, 0);
	ch_stat.push_back(tmp_stat);
	vector<int> current_stat(26);
	vector<int> last_second;
	vector<int> last;
	for(int i=0; i<len; i++)
	{
		if(last.size() < 1)
		{
			tmp_stat[S[0] - 'a'] += 1;
			ch_stat.push_back(tmp_stat);
			last = tmp_stat;
			cut_nums[i] = 1;
		}
		else if(last_second.size() < 1)
		{

		}
		else
		{
			tmp_stat = last;
			tmp_stat[S[i] - 'a'] += 1;
			int ret = is_palindrome_candidate(tmp_stat);
			if(ret)
			{
				cut_nums[i] = cut_nums[i-1];
				last = tmp_stat;
				ch_stat[ch_stat.size()-1] = last;
			}
			else
			{
				if(S[i] == S[cut_pos[cut_pos.size()-2]])
				{

				}

			}
		}
		
	}
	cut_nums[0] = 1;
	last_stat[S[0] - 'a'] += 1;

	int 
	for(int i=1; i<len; i++)
	{
		current_stat = last_stat;
		current_stat[S[i] - 'a'] += 1;

		if(cut_pos.size() < 1)
			cut_nums[i] = 1;

	}
#include <stdio.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <string.h>
#include <bitset>
using namespace std;

/*
typedef long long ll;
bool Finish_read;
template<class T>
inline void read(T &x) {
	Finish_read=0;x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}
	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
	x*=f;Finish_read=1;
}
template<class T>
inline void print(T x) {
	if(x/10!=0)
		print(x/10);
	putchar(x%10+'0');
}
template<class T>
inline void writeln(T x) {
	if(x<0)
		putchar('-');
	x=abs(x);
	print(x);
	putchar('\n');
}
template<class T>
inline void write(T x) {
	if(x<0)
		putchar('-');
	x=abs(x);
	print(x);
}
/*================Header Template==============*/
const int mx=(1<<26);
int pos[mx],f[200010];
char s[200010];
bitset<26> x[200010];
int main() {
	scanf("%s",s+1);
	int n=strlen(s+1);
	f[0]=0;
	memset(pos,-1,sizeof pos);
	pos[0]=0;
	for(int i=1;i<=n;i++) {
		x[i]^=x[i-1];
		x[i][s[i]-'a']=1-x[i][s[i]-'a'];
		f[i]=2e9;
		int t=x[i].to_ulong(),ind=i;
		for(int j=0;j<26;j++) {
			int tmp=(1<<j)^t;
			if(pos[tmp]!=-1&&f[ind]>f[pos[tmp]])
				ind=pos[tmp];
		}
		if(pos[t]!=-1&&f[ind]>f[pos[t]])
			ind=pos[t];
		f[i]=f[ind]+1;
		if(pos[t]==-1||f[i]<f[pos[t]])
			pos[t]=i;
	}
	printf("%d\n",f[n]);
	return 0;
}