#include<bits/stdc++.h>
//#pragma GCC target ("avx2")
//#pragma GCC optimization ("Ofast")
using namespace std;

#ifdef ONLINE_JUDGE
#define cerr if (false) cerr
#endif

#define fora(i, a, b) for (int i = (a); i < (b); i++)
#define ford(i, a, b) for (int i = (a); i >= (b); i--)
#define pr(x) cerr << #x << " = " << x << "\n";
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define ld(x) ((long double) x)

using ll = long long;
using ull = unsigned long long;

using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<double, double>;

using vpii = vector<pii>;
using vpll = vector<pll>;
using vpdd = vector<pdd>;

const long double PI = 3.14159265358979323;
const long long MOD = 1e9 + 7;


mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); // uniform_int_distribution<int>(0, n)(rng)

ll rnd(ll n) {
    return uniform_int_distribution<ll>(0, n)(rng);
}

long double rndLD(ll n) {
    return uniform_real_distribution<long double>(0, n)(rng);
}

struct custom_hash { // unordered_map<long long, int, custom_hash> safe_map;
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return (size_t) splitmix64(x + FIXED_RANDOM);
    }
	size_t operator()(pair<uint64_t,uint64_t> x) const {
		static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
		return (size_t) (splitmix64(x.first + FIXED_RANDOM)^(splitmix64(x.second + FIXED_RANDOM) >> 1));
	}
};

ull modmul(ull a, ull b, ull M) {
	ll ret = a * b - M * ull(1.L / M * a * b);
	return ret + M * (ret < 0) - M * (ret >= (ll)M);
}

ll power(ll b, ll e, ll mod) {
	ull ans = 1;
	for (; e; b = modmul(b, b, mod), e /= 2)
		if (e & 1) ans = modmul(ans, b, mod);
	return ans;
}

long long modInverse(long long n, long long p) {
    return power(n, p-2, p);
}

long long ncr(long long arr[], long long n, long long r, long long p) {
    return ((arr[n] * modInverse(arr[r], p))%p * modInverse(arr[n-r], p))%p;
}

bool isPrime(ull n) {
	if (n < 2 || n % 6 % 4 != 1) return (n | 1) == 3;
	ull A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022},
	    s = __builtin_ctzll(n-1), d = n >> s;
	for (ull a : A) {   // ^ count trailing zeroes
		ull p = power(a%n, d, n), i = s;
		while (p != 1 && p != n - 1 && a % n && i--)
			p = modmul(p, p, n);
		if (p != n-1 && i != s) return 0;
	}
	return 1;
}

ull pollard(ull n) {
	auto f = [n](ull x) { return modmul(x, x, n) + 1; };
	ull x = 0, y = 0, t = 0, prd = 2, i = 1, q;
	while (t++ % 40 || __gcd(prd, n) == 1) {
		if (x == y) x = ++i, y = f(x);
		if ((q = modmul(prd, max(x,y) - min(x,y), n))) prd = q;
		x = f(x), y = f(f(y));
	}
	return __gcd(prd, n);
}

vector<ull> factor(ull n) {
	if (n == 1) return {};
	if (isPrime(n)) return {n};
	ull x = pollard(n);
	auto l = factor(x), r = factor(n / x);
	l.insert(l.end(), all(r));
	return l;
}

const int MAXN = 200005;
vector<int> prime;
bool is_composite[MAXN];
void sieve(int n) {
	fill(is_composite, is_composite + n, false);
	fora(i, 2, n) {
		if (!is_composite[i]) prime.push_back (i);
		for (int j = 0; j < (int) prime.size() && i * prime[j] < n; j++) {
			is_composite[i * prime[j]] = true;
			if (i % prime[j] == 0) break;
		}
	}
}

struct Node {
    int nr;
    vector<Node*> anc;
    Node* up(int x) { return (x == 0 ? this : anc[__builtin_ctz(x - (x & (x-1)))] -> up(x & (x-1))); }
    vector<Node*> edges;
    bool visited = false;
    bool active = false;
    int distance = 1e9;
    void reset() {
        visited = false;
        active = false;
        distance = 1e9;
    }
    void hardReset() {
        anc.clear();
        edges.clear();
        visited = false;
        active = false;
        distance = 1e9;
    }
};

void dfs(Node* node) {
    if (node -> visited) {
        return;
    }
    node -> visited = true;
    node -> active = true;
    for (Node* newNode: node -> edges) {
        if (!newNode -> active) {
            newNode -> distance = min(newNode -> distance, node -> distance + 1);
        }
        if (!newNode -> visited) {
            newNode -> anc.push_back(node);
            dfs(newNode);
        }
    }
    node -> active = false;
}

void bfs(Node* node) {
    if (node -> visited) {
        return;
    }
    node -> visited = true;
    node -> distance = 0;
    queue<Node*> q;
    for (q.push(node); !q.empty(); q.pop()) {
        node = q.front();
        for (Node* newNode: node -> edges) {
            if (!newNode -> visited) {
                newNode -> visited = true;
                newNode -> distance = node -> distance + 1;
                q.push(newNode);
            }
        }
    }
}

int n,m,k,t,a,b,c,rez,sk,mas[200005];
string s;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> s;
    n = s.length();
    fora(i, 0, n) {
        sk += s[i] - '0';
        sk %= 9;
    }
    cout << (sk == 0 ? "Yes" : "No");
    return 0;
}


Measured memory_bytes: 3756