Problem:
Score : 700 points

Problem Statement

We have a string s consisting of lowercase English letters.
Snuke is partitioning s into some number of non-empty substrings.
Let the subtrings obtained be s_1, s_2, ..., s_N from left to right. (Here, s = s_1 + s_2 + ... + s_N holds.)
Snuke wants to satisfy the following condition:

For each i (1 \leq i \leq N), it is possible to permute the characters in s_i and obtain a palindrome.

Find the minimum possible value of N when the partition satisfies the condition.

Constraints

1 \leq |s| \leq 2 \times 10^5

s consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

s

Output

Print the minimum possible value of N when the partition satisfies the condition.

Sample Input 1

aabxyyzz

Sample Output 1

2

The solution is to partition s as aabxyyzz = aab + xyyzz.
Here, aab can be permuted to form a palindrome aba, and xyyzz can be permuted to form a palindrome zyxyz.

Sample Input 2

byebye

Sample Output 2

1

byebye can be permuted to form a palindrome byeeyb.

Sample Input 3

abcdefghijklmnopqrstuvwxyz

Sample Output 3

26

Sample Input 4

abcabcxabcx

Sample Output 4

3

The solution is to partition s as abcabcxabcx = a + b + cabcxabcx.

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.Scanner;

public class Main {

	public static int cntOdd;
	public static int[] alphabetCnt = new int[26];

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		String s = sc.next();

		for (int i = 0; i < 26; i++) {
			alphabetCnt[i] = 0;
		}

		for (int i = 0; i < s.length(); i++) {
			int alphabetIdx = (int) s.charAt(i) - 97;
			alphabetCnt[alphabetIdx] ++;
		}

		for (int i = 0; i < 26; i++) {
			if(alphabetCnt[i] % 2 == 1) {
				cntOdd++;
			}
		}

		int firstIdx = 0;
		int ans = 0;
		while (firstIdx != s.length()) {
			firstIdx = findLastIdx(firstIdx, s.length() - 1, s) + 1;
			// System.out.println(firstIdx);
			ans++;
		}

		System.out.print(ans);
	}

	public static int findLastIdx(int firstIdx, int lastIdx, String s) {
		int cntOddCopy = cntOdd;
		int[] alphabetCntCopy = new int[26];
		for (int i = 0; i < 26; i++) {
			alphabetCntCopy[i] = alphabetCnt[i];
		}
		// System.out.println(cntOddCopy);
		while (true) {
			if (cntOddCopy <= 1) {
				break;
			} else if (lastIdx == firstIdx) {
				break;
			} else {
				int alphabetIdx = (int) s.charAt(lastIdx) - 97;
				if (alphabetCntCopy[alphabetIdx] % 2 == 1) {
					alphabetCntCopy[alphabetIdx]--;
					// System.out.println("minus");
					cntOddCopy--;
				} else {
					alphabetCntCopy[alphabetIdx]--;
					// System.out.println("plus");
					cntOddCopy++;
				}
				lastIdx--;
			}
		}
		// System.out.println(cntOddCopy);
		cntOdd -= cntOddCopy;
		for (int i = firstIdx; i <= lastIdx; i++) {
			int alphabetIdx = (int) s.charAt(i) - 97;
			alphabetCnt[alphabetIdx] --;
		}
		return lastIdx;
	}
}