You are given a ternary string (it is a string which consists only of characters '0', '1' and '2').

You can swap any two adjacent (consecutive) characters '0' and '1' (i.e. replace "01" with "10" or vice versa) or any two adjacent (consecutive) characters '1' and '2' (i.e. replace "12" with "21" or vice versa).

For example, for string "010210" we can perform the following moves: 

  * "010210" → "100210"; 
  * "010210" → "001210"; 
  * "010210" → "010120"; 
  * "010210" → "010201". 



Note than you cannot swap "02" → "20" and vice versa. You cannot perform any other operations with the given string excluding described above.

You task is to obtain the minimum possible (lexicographically) string by using these swaps arbitrary number of times (possibly, zero).

String a is lexicographically less than string b (if strings a and b have the same length) if there exists some position i (1 ≤ i ≤ |a|, where |s| is the length of the string s) such that for every j < i holds a_j = b_j, and a_i < b_i.

Input

The first line of the input contains the string s consisting only of characters '0', '1' and '2', its length is between 1 and 10^5 (inclusive).

Output

Print a single string — the minimum possible (lexicographically) string you can obtain by using the swaps described above arbitrary number of times (possibly, zero).

Examples

Input

100210


Output

001120


Input

11222121


Output

11112222


Input

20


Output

20
import java.util.*;

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.Scanner; 
import java.util.StringTokenizer; 
  
public class Graph
{ 	
static int ans=0;
	
	static int rank[];
	static int p[];
	static int max=0;
	static int a,b,c,n;
	static int dp[];
	static ArrayList<Long> arr;
    ArrayList<Graph> adj;
	int parent;
	int indeg;
	int outdeg;
	int child;
	int value;
	int vis;
	int dist;
	static Graph graph[];
	
	Graph(int val)
	{
		adj=new ArrayList<>();
		parent=-1;
		indeg=0;
		outdeg=0;
		child=-1;
		value=val;
		vis=0;
		dist=0;
		
	}
	//unordered here
	static void add_edge(int u,int v)
	{
		graph[u].adj.add(graph[v]);
		graph[v].adj.add(graph[u]);
	}
	
	static int lower_bound(int start,int end,long value) 
	{

		while(start<end)
		{
			int mid=(start+end)/2;
			if(arr.get(mid)>=value)
			end=mid;
			else start=mid+1;
		}if(arr.get(start)<value)
			return start+1;
		else
		
		return start;
	}

	static int upper_bound(int start,int end,long value) {

		while(start<end)
		{
		int mid=(start+end)/2;
		if(arr.get(mid)<=value)
			start=mid+1;
		else end=mid;
		}
		return start;   
	} 

	/*static boolean check(char [] word, int index) {
		for (char cc : word) {
		if (cc != c[index]) {
			return false;
		}
		index++;
		}
		return true;
	}*/
  static void dfs(int index)
  {
	  Graph z=graph[index];
	  z.vis=1;max++;
	  for(int i=0;i<z.adj.size();i++)
	  {
		  if(z.adj.get(i).vis==0)
		  {
			  z.adj.get(i).dist=z.dist+1;
			  //System.out.println(z.adj.get(i).dist);
			
			  dfs(z.adj.get(i).value-1);
		  }
	  }
  }
  static void initialize(int n)
  {
	  for( int i=1; i<=n; i++)
	  {		  
			rank[i]=0;
			p[i]=i;
	  }
  }//apply two heuristics to get req. time complexity
  static int findSet(int a)
  {
	  if(p[a]!=a)
	  {
		  p[a]=findSet(p[a]);
	  }
	  return p[a];
  }
  static void mergeSet(int a, int b)
  {
	  int sa=findSet(a);
	  int sb=findSet(b);
	  if(sa!=sb)
	  {
		  ans--;
		  if(rank[sa]>rank[sb])
		  {
			  p[sb]=sa;
		  }
		  else if(rank[sb]>rank[sa])
		  {
			  p[sa]=sb;
		  }
		  else
		  {
			  p[sa]=sb;
			  rank[sb]++;
		  }
	  }
  }

  
    public static void main(String[] args) 
    { 
        FastReader sc=new FastReader(); 

		
				
		
        /*Queue<Graph> q=new LinkedList<>();
        q.add(graph[index]);
        while(!q.isEmpty())
        {
            Graph z=q.peek();
            q.poll();
			z.vis=1;
           for(int i=0;i<z.adj.size();i++)
		   {
			   if(z.adj.get(i).vis==0)
			   {
				   z.adj.get(i).vis=1;
					q.add(z.adj.get(i));
			   }
                
            }
            
        }*/
		
		//min heap
		PriorityQueue<Long> min=new PriorityQueue<>();
		//in case you need max heap i'm here ;0
		//just a note you can create a class that can have compare method as well here use that in you want to sort according to a parameter
		PriorityQueue<Integer> max=new PriorityQueue<>(new Comparator<Integer>()
		{
			@Override
			public int compare(Integer o1, Integer o2)
			{
				return Integer.compare(o2,o1);
			}
		});
		String str=sc.next();
		HashMap<Character, Integer> hm=new HashMap<>();
		hm.put('0',0);
		hm.put('1',0);
		hm.put('2',0);
		for(int i=0;i<str.length();i++)
		hm.put(str.charAt(i),hm.get(str.charAt(i))+1);
		for(int i=0;i<str.length();i++)
		{
			if(str.charAt(i)=='2')
			{
				for(int j=0;j<hm.get('1');j++)
				{
					System.out.print("1");
				}
				hm.put('1',0);
			}
			if(str.charAt(i)!='1')
				System.out.print(str.charAt(i));
			else
				continue;
		}
			if(hm.get('1')>0)
			{
				for(int j=0;j<hm.get('1');j++)
				{
					System.out.print("1");
				}
			}
			
		
		
			
			
			
    }
	static class Pair
	{
		int x;
		int y;
		Pair(int a, int b)
		{
			this.x =a;
			this.y =b;
		}
	}
	
	static class FastReader 
    { BufferedReader br; 
        StringTokenizer st;  public FastReader() { 
            br = new BufferedReader(new InputStreamReader(System.in)); } 
			String next() { 
            while (st == null || !st.hasMoreElements()) 
            { try{ st = new StringTokenizer(br.readLine()); 
                } catch (IOException  e) 
                { e.printStackTrace(); 
                }} return st.nextToken(); 
        } int nextInt() { return Integer.parseInt(next()); 
        }
        long nextLong() 
        {  return Long.parseLong(next()); 
        }
        double nextDouble() 
        { return Double.parseDouble(next()); 
        } 
        String nextLine() 
        {String str = ""; 
            try
            { str = br.readLine(); 
            } 
            catch (IOException e) 
            { e.printStackTrace(); 
            } return str; }}

} 
	
	
	
	
	
	
	
		