#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10;
/**
小根堆,size个元素的序列满足 k[i] <= k[2 * i] && k[i] <= k[2 * i + 1] (1 <= i <= size / 2)
每次去除堆顶元素,只需要重新调整为堆即可
push一个元素,相当于在对应的层上插入一个元素,这条链上下面的元素对应向下移
pop一个元素 将堆顶元素和最后一个元素交换,再重新调整堆
调整堆 由于除了堆顶元素之外,其余结点都符合堆的条件,所以只需要把堆顶元素调整到合适的位置即可,
交换的时候 只会影响一边,所以复杂度就相当于深度
*/
int total_cnt;
struct Heap {
int data[MAXN];
int size;
void clear(){size = 0;}
int get_size(){return size;}
bool is_empty(){return size == 0;}
void swim(int pos){
while(pos << 1 <= size){
int l = pos << 1;
if(l + 1 <= size && data[l + 1] < data[l]) l++;
if(data[l] < data[pos]){
swap(data[l],data[pos]);pos = l;
}else break;
}
}
void push(int value){
data[++size] = value;
int pos = size;
while(pos > 1){
if(data[pos >> 1] > data[pos]){
swap(data[pos >> 1],data[pos]);
pos >>= 1;
}else break;
}
}
int top(){return data[1];}
void pop(){
swap(data[1],data[size]);size--;
swim(1);
}
} h ;
char s[1010];
/**
hdu 1106测试
*/
int main(){
while(~scanf("%s",s)){
int len = strlen(s);
h.clear();
int sum = 0;
for(int i = 0;i < len;i++){
if(s[i] != '5') sum = sum * 10 + s[i] - '0';
else{
if(i && s[i-1] != '5') h.push(sum);
sum = 0;
}
}
if(s[len-1] != '5') h.push(sum);
while(!h.is_empty()){
if(h.get_size() == 1) printf("%d
",h.top());
else printf("%d ",h.top());
h.pop();
}
}
return 0;
}