#![allow(dead_code, unused_imports)]

use std::fmt::Debug;
use std::str::FromStr;

fn read_stdin() -> String {
    let mut s = String::new();
    std::io::stdin()
        .read_line(&mut s)
        .expect("cannot read stdin");
    s.trim().to_string()
}

fn read<T>() -> T
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    read_stdin().parse::<T>().unwrap()
}

fn read_usize() -> usize {
    read::<usize>()
}

fn read_2<A, B>() -> (A, B)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    (a, b)
}

fn read_3<A, B, C>() -> (A, B, C)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    (a, b, c)
}

fn read_4<A, B, C, D>() -> (A, B, C, D)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
    D: FromStr,
    <D as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    let d = s.next().unwrap().parse::<D>().unwrap();
    (a, b, c, d)
}

fn read_multiple<T: FromStr>() -> Vec<T>
where
    <T as FromStr>::Err: Debug,
{
    read_stdin()
        .split_whitespace()
        .map(|x| x.parse::<T>().expect("cannot parse stdin"))
        .collect()
}

/// NOTE: sort iter beforehand if required
fn count<T>(iter: &mut impl Iterator<Item = T>) -> Vec<(T, usize)>
where
    T: std::cmp::Ord,
{
    let iter = iter.collect::<Vec<_>>();
    //iter.sort();
    let (mut v, o, c) =
        iter.into_iter()
            .fold((Vec::new(), None, 0), |(mut v, last, count), item| {
                if let Some(o) = last {
                    if item == o {
                        (v, Some(o), count + 1)
                    } else {
                        v.push((o, count));
                        (v, Some(item), 1)
                    }
                } else {
                    (v, Some(item), 1)
                }
            });
    if let Some(i) = o {
        v.push((i, c));
    }
    v
}

fn max_subarray(v: impl Iterator<Item = i64>) -> (i64, (usize, usize)) {
    //assert!(v.len() > 0);
    let mut best_sum = 0;
    let (mut best_start, mut best_end) = (0, 0);
    let mut current_sum = 0;
    let mut current_start = 0;
    for (end, val) in v.enumerate() {
        if current_sum <= 0 {
            current_start = end;
            current_sum = val;
        } else {
            current_sum += val;
        }
        if current_sum > best_sum {
            best_sum = current_sum;
            best_start = current_start;
            best_end = end + 1;
        }
    }
    (best_sum, (best_start, best_end))
}

fn gcd(a: u64, b: u64) -> u64 {
    let mut a = a;
    let mut b = b;
    while a != b {
        if a > b {
            a = a - b
        } else {
            b = b - a
        }
    }
    a
}

fn factorize(mut n: u64) -> Vec<u64> {
    if n <= 3 {
        return vec![n];
    }
    let mut v = Vec::new();
    while n % 2 == 0 {
        n /= 2;
        v.push(2);
    }
    while n % 3 == 0 {
        n /= 3;
        v.push(3);
    }
    let mut f = 6;
    while (f - 1) * (f - 1) <= n {
        while n % (f - 1) == 0 {
            n /= f - 1;
            v.push(f - 1);
        }
        while n % (f + 1) == 0 {
            n /= f + 1;
            v.push(f + 1);
        }
        f += 6;
    }
    if n > 1 {
        v.push(n);
    }
    v
}

fn compact_factors(n: u64) -> Vec<(u64, usize)> {
    count(&mut factorize(n).into_iter())
}

fn all_factors(n: u64) -> Vec<u64> {
    let factors = compact_factors(n);
    let mut v = vec![1];
    for (fac, num) in factors {
        let ori = v.clone();
        for i in 1..num + 1 {
            v.append(
                &mut ori
                    .clone()
                    .into_iter()
                    .map(|f| f * fac.pow(i as u32))
                    .collect::<Vec<_>>(),
            )
        }
    }
    v.sort();
    v
}

use std::cmp::{max, min};
use std::collections::VecDeque;

fn first_factor(n: u32) -> u32 {
    if n % 2 == 0 {
        return 2;
    }
    if n % 3 == 0 {
        return 3;
    }
    let mut f = 6;
    while (f - 1) * (f - 1) <= n {
        if n % (f - 1) == 0 {
            return f - 1;
        }
        if n % (f + 1) == 0 {
            return f + 1;
        }
        f += 6;
    }
    return n;
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let s = read_stdin();
    let mut sum = 0;
    for c in s.chars() {
        sum += c.to_string().parse::<u8>().unwrap() as u32;
    }
    if sum % 9 == 0 {
        println!("Yes")
    } else {
        println!("No")
    }
    Ok(())
}


Measured memory_bytes: 2368