#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <unordered_map>
#include <limits.h>
using namespace std;
#define ll long long

bool CVRST(const string& number)
{
	auto digit_counts = vector<int>(10);
	for (size_t i = 0; i < number.size(); i++)
	{
		int current_digit = number[i] - '0';
		if (i == 0)
			digit_counts[current_digit]++;
		else if (digit_counts[current_digit] != 0 && number[i-1] != '0' + current_digit)
			return false;
		else
			digit_counts[current_digit]++;
	}
	return true;
}

ll recurse(string& number, int position)
{
	if (position == number.size())
	{
		if (CVRST(number))
			return 0;
		else
			return -1;
	}
	else
	{
		int starting_digit = number[position] - '0';
		ll min_value = LLONG_MAX;
		bool possible = false;
		for (int i = 0; i <= 9; i++)
		{
			number[position] = '0' + i;
			ll operation_count = recurse(number, position + 1);
			if (operation_count != -1)
			{
				if (starting_digit == i)
					min_value = min(min_value, operation_count);
				else
					min_value = min(min_value, operation_count + 1);
				possible = true;
			}
		}
		number[position] = '0' + starting_digit;
		if (possible)
			return min_value;
	}
	return -1;
}

ll solve(string number)
{
	vector<int> digit_map(number.size(), -1);
	vector<int> translated_input(number.size());
	int unique_count = 0;
	for (int i = number.size()-1; i >= 0; i--)
	{
		int current_digit = number[i] - '0';
		if (digit_map[current_digit] == -1)
		{
			digit_map[current_digit] = unique_count;
			unique_count++;
		}
	}

	vector<vector<ll>> dp(unique_count);
	for (size_t i = 0; i < unique_count; i++)
		dp[i] = vector<ll>(number.size());


	ll solution = LLONG_MAX;
	mt19937 rng = mt19937(random_device()());

	for (size_t trial_no = 0; trial_no < (5*1e6) / number.size(); trial_no++)
	{
		for (size_t i = 0; i < number.size(); i++)
		{
			int current_digit = number[i] - '0';
			translated_input[i] = digit_map[current_digit];
		}

		// Add base case
		for (size_t row = 0; row < unique_count; row++)
		{
			if (translated_input[0] == row)
				dp[row][0] = 0;
			else
				dp[row][0] = 1;
		}

		for (size_t col = 1; col < number.size(); col++)
		{
			for (size_t row = 0; row < unique_count; row++)
			{
				ll continue_segment = dp[row][col - 1];
				ll start_new_segment = LLONG_MAX;
				if (row < unique_count - 1)
					start_new_segment = dp[row + 1][col - 1];

				dp[row][col] = min(continue_segment, start_new_segment);
				if (translated_input[col] != row)
					dp[row][col]++;
			}
		}

		for (size_t row = 0; row < unique_count; row++)
			solution = min(solution, dp[row][number.size() - 1]);

		int i = rng() % digit_map.size();
		while (digit_map[i] == -1)
		{
			i = rng() % digit_map.size();
		}
		int j = rng() % digit_map.size();
		while (digit_map[j] == -1)
		{
			j = rng() % digit_map.size();
		}
		swap(digit_map[i], digit_map[j]);	
	}
	
	return solution;
}

ll brute_force(string number)
{
	return recurse(number, 0);
}

ll solve_only_zeros_and_ones(const string& s, ll count0, ll count1)
{
	ll zeros_left = 0, zeros_right = count0;
	ll ones_left = 0, ones_right = count1;
	ll solution = LLONG_MAX;
	for (size_t border_position = 0; border_position < s.size(); border_position++)
	{
		// If left segment all zeros and right segment all ones
		ll changes1 = ones_left + zeros_right;
		// If right segment all zeros and left segment all zeros
		ll changes2 = zeros_left + ones_right;
		solution = min(solution, min(changes1, changes2));
		if (s[border_position] == '0')
		{
			zeros_left++;
			zeros_right--;
		}
		else
		{
			ones_left++;
			ones_right--;
		}
	}
	return solution;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	string s; cin >> s;
	if (s.size() <= 6)
	{
		cout << brute_force(s);
		return 0;
	}
	ll count0 = count(s.begin(), s.end(), '0');
	ll count1 = count(s.begin(), s.end(), '1');
	if (count0 + count1 == s.size())
	{
		cout << solve_only_zeros_and_ones(s, count0, count1);
		return 0;
	}
	cout << solve(s);
	return 0;
}