#[allow(unused)]
use std::{io, str, vec};

#[allow(unused)]
fn read<T: str::FromStr>() -> T {
    let mut s = String::new();
    io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

#[allow(unused)]
fn read_vec<T: str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace()
        .map(|e| e.parse().ok().unwrap()).collect()
}

#[allow(unused)]
fn read_vec2<T: str::FromStr>(n: u32) -> Vec<Vec<T>> {
    (0..n).map(|_| read_vec()).collect()
}

fn main() {
    let v: Vec<char> = read::<String>().chars().collect();
    println!("{:?}", re(vec![v], 0));
}

fn re(vecs: Vec<Vec<char>>, count: usize) -> usize {
    let mut nexts: Vec<Vec<char>> = vec::Vec::new();
    //println!("==========");
    //for v in &vecs {
    //    println!("{:?}", v);
    //}
    let mut is_exists = false;
    for a in vecs {
        let mut index = 0;
        let len = a.len();
        while index < len {
            match search(&a, index) {
                Ok((n, v)) => {
                    is_exists = true;
                    index = n;
                    nexts.push(v);
                },
                Err(_) => break,
            }
        }
    }
    if is_exists { re(nexts, count+2) }else{ count }
}

fn search(v: &Vec<char>, startIndex : usize) -> Result<(usize, Vec<char>), usize> {
    let mut result: Vec<char> = Vec::new();
    for i in 0..startIndex {
        result.push(v[i]);
    }
    for i in startIndex..(v.len()-1) {
        if (v[i] == '0' && v[i+1] == '1')  || (v[i] == '1' && v[i+1] == '0')  {
            for j in i+2..v.len() {
                result.push(v[j]);
            }
            return Ok((i+1, result))
        }else{
            result.push(v[i]);
        }
    }
    Err(1)
}













