extern crate core;

use std::fmt;
use std::cmp::{Ordering, min, max};
use std::f32::MAX;
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut, SubAssign};
use std::collections::{BTreeMap, VecDeque, BinaryHeap, BTreeSet};
use std::fmt::{Display, Formatter, Error};
use std::env::join_paths;

fn show<T: Display>(vec: &Vec<T>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        print!("[{}", vec[0]);
        for i in 1 .. vec.len() {
            print!(", {}", vec[i]);
        }
        println!("]");
    }
}
fn show2<T: Display>(vec: &Vec<Vec<T>>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        for l in vec {
            show(l);
        }
    }
}
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! read_value{
    () => {
        read_line!().trim().parse().ok().unwrap()
    }
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
macro_rules! let_mut_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let mut $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
fn min_step(history: &Vec<i32>, current: usize, prev_is_left: bool, left_pos: i32, right_pos: i32, memo: &mut Vec<Vec<Vec<Vec<i32>>>>) -> i32 {
    if current == history.len() {
        0
    }else if memo[current][if prev_is_left {0}else {1}][left_pos as usize][right_pos as usize] >= 0{
        memo[current][if prev_is_left{0}else {1}][left_pos as usize][right_pos as usize]
    }else {
        let left = if history[current] % 3 <= right_pos {min_step(history, current + 1, true, history[current] % 3, right_pos, memo) + if prev_is_left {1}else {0}} else {std::i32::MAX};
        let right = if history[current] % 3 >= left_pos {min_step(history, current + 1, false, left_pos, history[current] % 3, memo) + if prev_is_left {0}else {1}} else {std::i32::MAX};
        memo[current][if prev_is_left{0}else {1}][left_pos as usize][right_pos as usize] = min(left, right);
        min(left, right)
    }
}
fn main() {
    loop {
        let state: String = read_line!().trim().to_string();
        if &state[..] == "#" {
            return
        }
        let state: Vec<_> = state.chars().map(|x|x.to_digit(10).unwrap() as i32 - 1).collect();
        let mut memo = vec![vec![vec![vec![-1; 3]; 3]; 2]; state.len()];
        let from_left = min_step(&state, 0, false, 0, 2, &mut memo);
        let from_right = min_step(&state, 0, true, 0, 2, &mut memo);
        println!("{}", min(from_left, from_right));
    }
}


Measured memory_bytes: 47408