#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <numeric>
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <fstream>
using namespace std;
//const int N = 5;
//const int M = 11;
//int table[N][M];
//int r[N][M];
const int M = 12;
int t[M];
int r[M];

// for debug ツテツーツブツδ仰づーツ表ツ篠ヲ
void disp_t (void )
{
	int j;

	for (j = 0; j < M; ++j){
		cout << setw(2) << t[j];
	} // end for
	cout << endl;
}

void record_t (void )
{
	for (int i = 0; i < M; ++i){
		r[i] = t[i];
	} // end for
}

void restore_t (void )
{
	for (int i = 0; i < M; ++i){
		t[i] = r[i];
	} // end for
} 
	
int count_t (void )
{
	int res = 0;
	for (int i = 0; i < M; ++i){
		res += t[i];
	} // end for

	return res;
}

bool dfs (int row, bool head )
{
	if (row > 9 ){
		if (count_t() == 0 ){		
			return true;
		}else{
			return false;
		} // end if
	} // end if

	// is not hai?
	if (t[row] == 0 ){
		if (dfs (row+1, head ) ){
			return true;
		} // end if
	} // end if
	
	// is head ?
	if (!head && t[row] == 2 ){
		head = true;
		t[row] -= 2;
		if (dfs (row, head ) ){
			return true;
		} // end if
		t[row] += 2;
		head = false;
	} // end if

	// is kou-tu?
	if (t[row] == 3 ){
		t[row] -= 3;
		if (dfs (row+1, head ) ){
			return true;
		} // end if
		t[row] += 3;
	} // end if

	// is dyun-tu?
	if (t[row] > 0 && t[row+1] > 0 && t[row+2] > 0 ){
		t[row]--; t[row+1]--; t[row+2]--;
		if (dfs (row, head ) ){
			return true;
		} // end if
		t[row]++; t[row+1]++; t[row+2]++;
	} // end if

	return false;
}	

int main()
{
//	cut here before submit 
//	freopen("testcase.pz", "r", stdin);
//	freopen ("testcase.puzzle", "r", stdin );

	string str = "";

	while (getline (cin, str ) ){

		if (str.empty() ){
			break;
		} // end if
		set <int> res;
		vector <int> pai (13, 0 );
		map <int, int> num;
		int i,j,k;

		for (i = 0; i < 13; ++i){
			pai[i] = str[i] - '0';
			++num[pai[i]];
		} // end for

		sort (pai.begin(), pai.end() );

		// for debug ツソツーツトツつオツつスツ個仰嘉環づーツ表ツ篠ヲ
//		for (i = 0; i < 13; ++i){
//			cout << pai[i] << ' ';
//		} // end for
//		cout << endl;

		memset (t, 0, sizeof(t ) );
		// make table with same number counting
		for (i = 1; i <= 9; ++i){
			 t[i] = num[i];
		} // end for

		for (i = 1; i <= 9; ++i){
			if (t[i] < 4){
				// record table
				record_t();

				++t[i];
				// for debug
//				disp_t();

				// decide whether puzzle complete or not
				if (dfs (1, false) ){
//					cout << "OK" << endl;
					res.insert (i);
				}else{
//					cout << "NG" << endl;
				} // end if

				// for debug
//				disp_t();

				// restore table
				restore_t();
				// for debug

//				disp_t();
			} // end if
		} // end for

		// printout result
		if (res.empty() ){
			cout << '0' << endl;
		}else{
			int size = res.size();
			set<int>::iterator itr = res.begin();
		 	for (i = 0; itr != res.end(); ++itr, ++i ){
				cout << (*itr);
				if (i != size - 1){
					cout << ' ';
				} // end if
			} // end for
			cout << endl;
		} // end if
	} // end while

	return 0;
}