#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <complex>
#include <functional>
#include <utility>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cctype>

using namespace std;

#define dump(n) cout<<"# "<<#n<<"="<<(n)<<endl
#define debug(n) cout<<__FILE__<<","<<__LINE__<<": # "<<#n<<"="<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,n) repi(i,0,n)
#define iter(c) __typeof((c).begin())
#define tr(c,i) for(iter(c) i=(c).begin();i!=(c).end();i++)
#define allof(c) (c).begin(),(c).end()
#define mp make_pair

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int,int> pii;

bool search(int n,vi& hist)
{
	if(n==4)
		return true;
	
	rep(i,9){
		if(hist[i]>=3){
			hist[i]-=3;
			if(search(n+1,hist)){
				//printf("%d %d %d\n",i,i,i);
				return true;
			}
			hist[i]+=3;
		}
		else if(i<=6 && hist[i] && hist[i+1] && hist[i+2]){
			rep(j,3)
				hist[i+j]--;
			if(search(n+1,hist)){
				//printf("%d %d %d\n",i,i+1,i+2);
				return true;
			}
			rep(j,3)
				hist[i+j]++;
		}
	}
	return false;
}

bool solve(const vi& a)
{
	vi hist(9);
	rep(i,a.size())
		hist[a[i]]++;
	
	//if(*max_element(allof(hist))>=5)
	//	return false;
	
	rep(i,9){
		if(hist[i]>=2){
			hist[i]-=2;
			if(search(0,hist)){
				//printf("(%d %d)\n",i,i);
				return true;
			}
			hist[i]+=2;
		}
	}
	
	return false;
}

string solve_ando(const vi& _a)
{
	vi a(_a);
	vi res;
	//
	vi hist(9);
	rep(i,a.size())
		hist[a[i]]++;
	//
	rep(i,9){
		//
		if(hist[i]>=4)
			continue;
		//
		a.push_back(i);
		if(solve(a))
			res.push_back(i+1);
		a.pop_back();
	}
	
	ostringstream oss;
	if(res.size()==0)
		oss<<"0";
	else{
		rep(i,res.size())
			oss<<(i==0?"":" ")<<res[i];
	}
	return oss.str();
}

int hai[9];

bool search_oki()
{
	if(accumulate(hai, hai+9, 0)==2 && *max_element(hai, hai+9)==2)
		return true;

	rep(i, 9){
		if(!hai[i]) continue;
		bool res = false;
		if(hai[i]>=3){
			hai[i] -= 3;
			res = search_oki();
			hai[i] += 3;
		}
		if(i<7 && hai[i] && hai[i+1] && hai[i+2]){
			hai[i]--;
			hai[i+1]--;
			hai[i+2]--;
			res = search_oki();
			hai[i]++;
			hai[i+1]++;
			hai[i+2]++;
		}
		if(res) return true;
	}
	return false;
}

string solve_oki(const vi& a)
{
	fill(hai, hai+10, 0);
	//char c;
	rep(i, 13){
		//if(scanf(" %c", &c) == EOF)
		//	return 0;
		//hai[c-'1']++;
		hai[a[i]]++;
	}
	vi ans;
	rep(i, 9){
		if(hai[i]>=4) continue;

		hai[i]++;
		if(search_oki())
			ans.push_back(i+1);
		hai[i]--;
	}

	ostringstream oss;
	if(ans.empty())
		oss<<0;
	else{
		rep(i, ans.size()){
			oss<<ans[i];
			if(i<(int)ans.size()-1)
				oss<<" ";
		}
	}
	return oss.str();
}

int main()
{
	for(string s;getline(cin,s);){
		sort(allof(s));
		
		vi a(13);
		rep(i,s.size())
			a[i]=s[i]-1-'0';
		
		string res_ando=solve_ando(a);
		cout<<res_ando<<endl;
		//string res_oki=solve_oki(a);
		//if(res_ando==res_oki)
		//	cout<<"equal ("<<res_ando<<")"<<endl;
		//else{
		//	cout<<"not equal!"<<endl;
		//	dump(s);
		//	dump(res_ando);
		//	dump(res_oki);
		//	return 1;
		//}
		////cout<<solve_ando(a);
		////cout<<solve_oki(a);
	}
	
	return 0;
}

Measured memory_bytes: 0