using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;
using CodeforcesRound581Div2.Questions;

namespace CodeforcesRound581Div2.Questions
{
    public class QuestionD1 : AtCoderQuestionBase
    {
        [MethodImpl(MethodImplOptions.AggressiveOptimization)]
        public override void Solve(IOManager io)
        {
            var rawS = io.ReadString();
            var s = new int[rawS.Length];
            for (int i = 0; i < rawS.Length; i++)
            {
                s[i] = rawS[i] - '0';
            }

            s.AsSpan().Reverse();
            Span<int> lisS = new int[s.Length];
            var t = new int[s.Length];
            Span<int> lisT = new int[t.Length];

            lisS.Fill(int.MinValue);
            lisT.Fill(int.MinValue);

            for (int i = 0; i < s.Length; i++)
            {
                var sIndex = lisS.GetLessThanIndex(s[i]);
                var tIndex = lisT.GetLessThanIndex(t[i]);

                if (sIndex != tIndex)
                {
                    t[i] = 1;
                    tIndex = lisT.GetLessThanIndex(t[i]);
                }

                lisS[sIndex] = s[i];
                lisT[tIndex] = t[i];
            }

            t.AsSpan().Reverse();

            foreach (var ti in t)
            {
                io.Write(ti);
            }

            io.WriteLine("");
        }
    }
}

namespace CodeforcesRound581Div2
{
    class Program
    {
        static void Main(string[] args)
        {
            IAtCoderQuestion question = new QuestionD1();
            using var io = new IOManager(Console.OpenStandardInput(), Console.OpenStandardOutput());
            question.Solve(io);
        }
    }
}

#region Base Class

namespace CodeforcesRound581Div2.Questions
{
    public interface IAtCoderQuestion
    {
        string Solve(string input);
        void Solve(IOManager io);
    }

    public abstract class AtCoderQuestionBase : IAtCoderQuestion
    {
        public string Solve(string input)
        {
            var inputStream = new MemoryStream(Encoding.UTF8.GetBytes(input));
            var outputStream = new MemoryStream();
            using var manager = new IOManager(inputStream, outputStream);

            Solve(manager);
            manager.Flush();

            outputStream.Seek(0, SeekOrigin.Begin);
            var reader = new StreamReader(outputStream);
            return reader.ReadToEnd();
        }

        public abstract void Solve(IOManager io);
    }
}

#endregion

#region Utils

namespace CodeforcesRound581Div2
{
    public class IOManager : IDisposable
    {
        private readonly BinaryReader _reader;
        private readonly StreamWriter _writer;
        private bool _disposedValue;
        private byte[] _buffer = new byte[1024];
        private int _length;
        private int _cursor;
        private bool _eof;

        const char ValidFirstChar = '!';
        const char ValidLastChar = '~';

        public IOManager(Stream input, Stream output)
        {
            _reader = new BinaryReader(input);
            _writer = new StreamWriter(output) { AutoFlush = false };
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private char ReadAscii()
        {
            if (_cursor == _length)
            {
                _cursor = 0;
                _length = _reader.Read(_buffer);

                if (_length == 0)
                {
                    if (!_eof)
                    {
                        _eof = true;
                        return char.MinValue;
                    }
                    else
                    {
                        ThrowEndOfStreamException();
                    }
                }
            }

            return (char)_buffer[_cursor++];
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public char ReadChar()
        {
            char c;
            while (!IsValidChar(c = ReadAscii())) { }
            return c;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public string ReadString()
        {
            var builder = new StringBuilder();
            char c;
            while (!IsValidChar(c = ReadAscii())) { }

            do
            {
                builder.Append(c);
            } while (IsValidChar(c = ReadAscii()));

            return builder.ToString();
        }

        public int ReadInt() => (int)ReadLong();

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public long ReadLong()
        {
            long result = 0;
            bool isPositive = true;
            char c;

            while (!IsNumericChar(c = ReadAscii())) { }

            if (c == '-')
            {
                isPositive = false;
                c = ReadAscii();
            }

            do
            {
                result *= 10;
                result += c - '0';
            } while (IsNumericChar(c = ReadAscii()));

            return isPositive ? result : -result;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private Span<char> ReadChunk(Span<char> span)
        {
            var i = 0;
            char c;
            while (!IsValidChar(c = ReadAscii())) { }

            do
            {
                span[i++] = c;
            } while (IsValidChar(c = ReadAscii()));

            return span.Slice(0, i);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public double ReadDouble() => double.Parse(ReadChunk(stackalloc char[32]));

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public decimal ReadDecimal() => decimal.Parse(ReadChunk(stackalloc char[32]));

        public int[] ReadIntArray(int n)
        {
            var a = new int[n];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = ReadInt();
            }
            return a;
        }

        public long[] ReadLongArray(int n)
        {
            var a = new long[n];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = ReadLong();
            }
            return a;
        }

        public double[] ReadDoubleArray(int n)
        {
            var a = new double[n];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = ReadDouble();
            }
            return a;
        }

        public decimal[] ReadDecimalArray(int n)
        {
            var a = new decimal[n];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = ReadDecimal();
            }
            return a;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Write<T>(T value) => _writer.Write(value.ToString());

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void WriteLine<T>(T value) => _writer.WriteLine(value.ToString());

        public void WriteLine<T>(IEnumerable<T> values, char separator)
        {
            var e = values.GetEnumerator();
            if (e.MoveNext())
            {
                _writer.Write(e.Current.ToString());

                while (e.MoveNext())
                {
                    _writer.Write(separator);
                    _writer.Write(e.Current.ToString());
                }
            }

            _writer.WriteLine();
        }

        public void WriteLine<T>(T[] values, char separator) => WriteLine((ReadOnlySpan<T>)values, separator);
        public void WriteLine<T>(Span<T> values, char separator) => WriteLine((ReadOnlySpan<T>)values, separator);

        public void WriteLine<T>(ReadOnlySpan<T> values, char separator)
        {
            for (int i = 0; i < values.Length - 1; i++)
            {
                _writer.Write(values[i]);
                _writer.Write(separator);
            }

            if (values.Length > 0)
            {
                _writer.Write(values[^1]);
            }

            _writer.WriteLine();
        }

        public void Flush() => _writer.Flush();

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static bool IsValidChar(char c) => ValidFirstChar <= c && c <= ValidLastChar;

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static bool IsNumericChar(char c) => ('0' <= c && c <= '9') || c == '-';

        private void ThrowEndOfStreamException() => throw new EndOfStreamException();

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposedValue)
            {
                if (disposing)
                {
                    _reader.Dispose();
                    _writer.Flush();
                    _writer.Dispose();
                }

                _disposedValue = true;
            }
        }

        public void Dispose()
        {
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
    }

    public static class UtilExtensions
    {
        public static bool ChangeMax<T>(ref this T value, T other) where T : struct, IComparable<T>
        {
            if (value.CompareTo(other) < 0)
            {
                value = other;
                return true;
            }
            return false;
        }

        public static bool ChangeMin<T>(ref this T value, T other) where T : struct, IComparable<T>
        {
            if (value.CompareTo(other) > 0)
            {
                value = other;
                return true;
            }
            return false;
        }

        public static void SwapIfLargerThan<T>(ref this T a, ref T b) where T : struct, IComparable<T>
        {
            if (a.CompareTo(b) > 0)
            {
                (a, b) = (b, a);
            }
        }

        public static void SwapIfSmallerThan<T>(ref this T a, ref T b) where T : struct, IComparable<T>
        {
            if (a.CompareTo(b) < 0)
            {
                (a, b) = (b, a);
            }
        }

        public static void Sort<T>(this T[] array) where T : IComparable<T> => Array.Sort(array);
        public static void Sort<T>(this T[] array, Comparison<T> comparison) => Array.Sort(array, comparison);
    }

    public static class CollectionExtensions
    {
        private class ArrayWrapper<T>
        {
#pragma warning disable CS0649
            public T[] Array;
#pragma warning restore CS0649
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static Span<T> AsSpan<T>(this List<T> list)
        {
            return Unsafe.As<ArrayWrapper<T>>(list).Array.AsSpan(0, list.Count);
        }

        public static void Fill<T>(this T[] array, T value) => array.AsSpan().Fill(value);
        public static void Fill<T>(this T[,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0], array.Length).Fill(value);
        public static void Fill<T>(this T[,,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0, 0], array.Length).Fill(value);
        public static void Fill<T>(this T[,,,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0, 0, 0], array.Length).Fill(value);
    }

    public static class SearchExtensions
    {
        struct LowerBoundComparer<T> : IComparer<T> where T : IComparable<T>
        {
            public int Compare(T x, T y) => 0 <= x.CompareTo(y) ? 1 : -1;
        }

        struct UpperBoundComparer<T> : IComparer<T> where T : IComparable<T>
        {
            public int Compare(T x, T y) => 0 < x.CompareTo(y) ? 1 : -1;
        }

        // https://trsing.hatenablog.com/entry/2019/08/27/211038
        public static int GetGreaterEqualIndex<T>(this ReadOnlySpan<T> span, T inclusiveMin) where T : IComparable<T> => ~span.BinarySearch(inclusiveMin, new UpperBoundComparer<T>());
        public static int GetGreaterThanIndex<T>(this ReadOnlySpan<T> span, T exclusiveMin) where T : IComparable<T> => ~span.BinarySearch(exclusiveMin, new LowerBoundComparer<T>());
        public static int GetLessEqualIndex<T>(this ReadOnlySpan<T> span, T inclusiveMax) where T : IComparable<T> => ~span.BinarySearch(inclusiveMax, new LowerBoundComparer<T>()) - 1;
        public static int GetLessThanIndex<T>(this ReadOnlySpan<T> span, T exclusiveMax) where T : IComparable<T> => ~span.BinarySearch(exclusiveMax, new UpperBoundComparer<T>()) - 1;
        public static int GetGreaterEqualIndex<T>(this Span<T> span, T inclusiveMin) where T : IComparable<T> => ((ReadOnlySpan<T>)span).GetGreaterEqualIndex(inclusiveMin);
        public static int GetGreaterThanIndex<T>(this Span<T> span, T exclusiveMin) where T : IComparable<T> => ((ReadOnlySpan<T>)span).GetGreaterThanIndex(exclusiveMin);
        public static int GetLessEqualIndex<T>(this Span<T> span, T inclusiveMax) where T : IComparable<T> => ((ReadOnlySpan<T>)span).GetLessEqualIndex(inclusiveMax);
        public static int GetLessThanIndex<T>(this Span<T> span, T exclusiveMax) where T : IComparable<T> => ((ReadOnlySpan<T>)span).GetLessThanIndex(exclusiveMax);

        public static int BoundaryBinarySearch(Predicate<int> predicate, int ok, int ng)
        {
            while (Math.Abs(ok - ng) > 1)
            {
                int mid = (ok + ng) / 2;
                if (predicate(mid))
                {
                    ok = mid;
                }
                else
                {
                    ng = mid;
                }
            }
            return ok;
        }

        public static long BoundaryBinarySearch(Predicate<long> predicate, long ok, long ng)
        {
            while (Math.Abs(ok - ng) > 1)
            {
                long mid = (ok + ng) / 2;
                if (predicate(mid))
                {
                    ok = mid;
                }
                else
                {
                    ng = mid;
                }
            }
            return ok;
        }

        public static double Bisection(Func<double, double> f, double a, double b, double eps = 1e-9)
        {
            if (f(a) * f(b) >= 0)
            {
                throw new ArgumentException("f(a)とf(b)は異符号である必要があります。");
            }

            const int maxLoop = 100;
            double mid = (a + b) / 2;

            for (int i = 0; i < maxLoop; i++)
            {
                if (f(a) * f(mid) < 0)
                {
                    b = mid;
                }
                else
                {
                    a = mid;
                }
                mid = (a + b) / 2;
                if (Math.Abs(b - a) < eps)
                {
                    break;
                }
            }
            return mid;
        }
    }
}

#endregion

namespace CodeforcesRound581Div2.Graphs
{
    public interface IEdge
    {
        int To { get; }
    }

    public interface IWeightedEdge : IEdge
    {
        long Weight { get; }
    }

    public interface IGraph<TEdge> where TEdge : IEdge
    {
        ReadOnlySpan<TEdge> this[int node] { get; }
        int NodeCount { get; }
    }

    public interface IWeightedGraph<TEdge> : IGraph<TEdge> where TEdge : IWeightedEdge { }

    public readonly struct BasicEdge : IEdge
    {
        public int To { get; }

        public BasicEdge(int to)
        {
            To = to;
        }

        public override string ToString() => To.ToString();
        public static implicit operator BasicEdge(int edge) => new BasicEdge(edge);
        public static implicit operator int(BasicEdge edge) => edge.To;
    }

    [StructLayout(LayoutKind.Auto)]
    public readonly struct WeightedEdge : IWeightedEdge
    {
        public int To { get; }
        public long Weight { get; }

        public WeightedEdge(int to) : this(to, 1) { }

        public WeightedEdge(int to, long weight)
        {
            To = to;
            Weight = weight;
        }

        public override string ToString() => $"[{Weight}]-->{To}";
        public void Deconstruct(out int to, out long weight) => (to, weight) = (To, Weight);
    }

    public class BasicGraph : IGraph<BasicEdge>
    {
        private readonly List<List<BasicEdge>> _edges;
        public ReadOnlySpan<BasicEdge> this[int node] => _edges[node].AsSpan();
        public int NodeCount => _edges.Count;

        public BasicGraph(int nodeCount)
        {
            _edges = new List<List<BasicEdge>>(nodeCount);
            for (int i = 0; i < nodeCount; i++)
            {
                _edges.Add(new List<BasicEdge>());
            }
        }

        public void AddEdge(int from, int to) => _edges[from].Add(to);
        public void AddNode() => _edges.Add(new List<BasicEdge>());
    }

    public class WeightedGraph : IGraph<WeightedEdge>
    {
        private readonly List<List<WeightedEdge>> _edges;
        public ReadOnlySpan<WeightedEdge> this[int node] => _edges[node].AsSpan();
        public int NodeCount => _edges.Count;

        public WeightedGraph(int nodeCount)
        {
            _edges = new List<List<WeightedEdge>>(nodeCount);
            for (int i = 0; i < nodeCount; i++)
            {
                _edges.Add(new List<WeightedEdge>());
            }
        }

        public void AddEdge(int from, int to, long weight) => _edges[from].Add(new WeightedEdge(to, weight));
        public void AddNode() => _edges.Add(new List<WeightedEdge>());
    }
}


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using Number = System.Int32;
namespace Program {
	public class Solver {
		Random rnd = new Random(1);
		public void Solve() {
			//"10" は絶対 "10" にする必要がある
			var s = rs;
			var n = s.Length;
			var ans = new char[n];
			var a = new List<int>();
			for (int i = 0; i < n; i++) {
				if (a.Count == 0) { a.Add(i); continue; }
				var u = s[a.Last()] - '0';
				var v = s[i] - '0';
				Debug.WriteLine($"{i} {u} {v}");
				Debug.WriteLine(a.AsJoinedString());
				if (u == 1 && v == 0) { ans[a.Last()] = '1'; ans[i] = '0'; a.RemoveAt(a.Count - 1); }
				else a.Add(i);
			}
			foreach (var x in a)
				ans[x] = '0';
			Console.WriteLine(ans.AsString());

		}
		const long INF = 1L << 60;
		static int[] dx = { -1, 0, 1, 0 };
		static int[] dy = { 0, 1, 0, -1 };
		int ri { get { return sc.Integer(); } }
		long rl { get { return sc.Long(); } }
		double rd { get { return sc.Double(); } }
		string rs { get { return sc.Scan(); } }
		public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

		static T[] Enumerate<T>(int n, Func<int, T> f) {
			var a = new T[n];
			for (int i = 0; i < a.Length; ++i) a[i] = f(i);
			return a;
		}
		static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
	}
}

#region main
static class Ex {
	static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
	static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
		return string.Join(st, ie);
	}
	static public void Main() {
		Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
		var solver = new Program.Solver();
		//var t = new System.Threading.Thread(solver.Solve, 50000000);
		//t.Start();
		//t.Join();
		solver.Solve();
		Console.Out.Flush();
	}
}
#endregion
#region Ex
namespace Program.IO {
	using System.IO;
	using System.Text;
	using System.Globalization;

	public class Printer : StreamWriter {
		public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
		public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	}

	public class StreamScanner {
		public StreamScanner(Stream stream) { str = stream; }

		public readonly Stream str;
		private readonly byte[] buf = new byte[1024];
		private int len, ptr;
		public bool isEof = false;
		public bool IsEndOfStream { get { return isEof; } }

		private byte read() {
			if (isEof) return 0;
			if (ptr >= len) {
				ptr = 0;
				if ((len = str.Read(buf, 0, 1024)) <= 0) {
					isEof = true;
					return 0;
				}
			}
			return buf[ptr++];
		}

		public char Char() {
			byte b = 0;
			do b = read(); while ((b < 33 || 126 < b) && !isEof);
			return (char)b;
		}
		public string Scan() {
			var sb = new StringBuilder();
			for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
			return sb.ToString();
		}
		public string ScanLine() {
			var sb = new StringBuilder();
			for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
			return sb.ToString();
		}
		public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
		public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
		public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
	}
}

#endregion


using System;
using CompLib.Collections.Generic;
using CompLib.Util;

public class Program
{
    private string S;
    private int N;

    public void Solve()
    {
        var sc = new Scanner();
        S = sc.Next();
        N = S.Length;

        // S+Tの長さ
        // max(Sの長さ+Tの1, Sの0+Tの長さ)

        // S_iを1から0にする
        var st = new SegmentTree<(int w, int b, int l)>(N,
            (l, r) => (l.w + r.w, l.b + r.b, Math.Max(l.l + r.b, l.w + r.l)), (0, 0, 0));

        for (int i = 0; i < N; i++)
        {
            st[i] = S[i] == '0' ? (1, 0, 1) : (0, 1, 1);
        }

        char[] ans = new char[N];
        for (int i = 0; i < N; i++)
        {
            if (S[i] == '0')
            {
                ans[i] = '0';
            }
            else
            {
                var root = st._array[1];
                st[i] = (1, 0, 1);
                var root2 = st._array[1];
                if ((root.l == root2.l))
                {
                    ans[i] = '0';
                }
                else
                {
                    ans[i] = '1';
                    st[i] = (0, 1, 1);
                }
            }
        }

        Console.WriteLine(new string(ans));
    }

    public static void Main(string[] args) => new Program().Solve();
}

namespace CompLib.Collections.Generic
{
    using System;

    public class SegmentTree<T>
    {
        private readonly int N;
        public T[] _array;

        private T _identity;
        private Func<T, T, T> _operation;

        public SegmentTree(int size, Func<T, T, T> operation, T identity)
        {
            N = 1;
            while (N < size) N *= 2;
            _identity = identity;
            _operation = operation;
            _array = new T[N * 2];
            for (int i = 1; i < N * 2; i++)
            {
                _array[i] = _identity;
            }
        }

        /// <summary>
        /// A[i]をnに更新 O(log N)
        /// </summary>
        /// <param name="i"></param>
        /// <param name="n"></param>
        public void Update(int i, T n)
        {
            i += N;
            _array[i] = n;
            while (i > 1)
            {
                i /= 2;
                _array[i] = _operation(_array[i * 2], _array[i * 2 + 1]);
            }
        }

        private T Query(int left, int right, int k, int l, int r)
        {
            if (r <= left || right <= l)
            {
                return _identity;
            }

            if (left <= l && r <= right)
            {
                return _array[k];
            }

            return _operation(Query(left, right, k * 2, l, (l + r) / 2),
                Query(left, right, k * 2 + 1, (l + r) / 2, r));
        }

        /// <summary>
        /// A[left] op A[left+1] ... op A[right-1]を求める
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public T Query(int left, int right)
        {
            return Query(left, right, 1, 0, N);
        }

        public T this[int i]
        {
            set { Update(i, value); }
            get { return _array[i + N]; }
        }
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s;
                do
                {
                    s = Console.ReadLine();
                } while (s.Length == 0);

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		string s = Console.ReadLine();
		int N = s.Length;
		int[]A = new int[N];
		int[]B = new int[N];
		for(var i=0;i<N;i++){
			A[i] = int.Parse(s.Substring(i,1));
		}
		for(var i=0;i<N;i++){
			if(A[i]==0){
				B[i]=0;
			} else if(A[i]==1 && i<N-1 && A[i+1]==0){
				B[i]=1;
			} else {
				B[i]=-1;
			}
		}
		int cta=0;
		int ctb=0;
		int[]C = new int[N];
		for(var i=0;i<N;i++){
			C[i] = -1;
		}
		for(var i=N-1;i>=0;i--){
			if(B[i]==-1){
				if(cta<ctb){
					C[i] = 1;
					cta++;
				} else {
					C[i] = 0;
				}
			}
			if(B[i]==0){
				ctb++;
			} else if(B[i]==1){
				cta++;
			}
		}
		for(var i=0;i<N;i++){
			if(B[i]==-1){
				Console.Write(C[i]);
			} else {
				Console.Write(B[i]);
			}
		}
	}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Numerics;
using static Template;
using static System.Console;
using static System.Convert;
using static System.Math;
using Pi = Pair<int, int>;

class Solver
{
    public void Solve(Scanner sc)
    {
        var S = sc.Str.ToCharArray();
        var dp = Create(S.Length + 1, () => new int[2]);//Sの最長subseq
        var newdp = Create(S.Length + 1, () => new int[2]);//Tの最長subseq
        for(int i = S.Length - 1; i >= 0; i--)
        {
            if (S[i] == '1')
            {
                dp[i][0] = Max(dp[i + 1][0], dp[i + 1][1]);
                dp[i][1] = dp[i + 1][1] + 1;
            }
            else
            {
                dp[i][0] = 1 + Max(dp[i + 1][0], dp[i + 1][1]);
                dp[i][1] = dp[i + 1][1];
            }
            if (S[i] == '1')
            {
                if (1 + Max(newdp[i + 1][0], newdp[i + 1][1]) == Max(dp[i + 1][1] + 1, dp[i + 1][0]))
                    S[i] = '0';
            }
            if (S[i] == '1')
            {
                newdp[i][0] = Max(newdp[i + 1][0], newdp[i + 1][1]);
                newdp[i][1] = newdp[i + 1][1] + 1;
            }
            else
            {
                newdp[i][0] = Max(newdp[i + 1][0], newdp[i + 1][1]) + 1;
                newdp[i][1] = newdp[i + 1][1];
            }
        }
        WriteLine(new string(S));
    }
}

#region Template
public static class Template
{
    static void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver().Solve(new Scanner());
        Console.Out.Flush();
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) == 1) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) == -1) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(ref T a, ref T b) { var t = b; b = a; a = t; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static T[] Create<T>(int n, Func<T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(); return rt; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static T[] Create<T>(int n, Func<int, T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(i); return rt; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static T Unify<T>(this T[] A, Func<T, T, T> f, T init = default(T)) { for (var i = 0; i < A.Length; i++) init = f(init, A[i]); return init; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static U Unify<T, U>(this T[] A, Func<U, T, U> f, U init = default(U)) { for (int i = 0; i < A.Length; i++) init = f(init, A[i]);return init; }
    public static void Fail<T>(T s) { Console.WriteLine(s); Console.Out.Close(); Environment.Exit(0); }
}

public class Scanner
{
    public string Str => Console.ReadLine().Trim();
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public int[] ArrInt => Str.Split(' ').Select(int.Parse).ToArray();
    public long[] ArrLong => Str.Split(' ').Select(long.Parse).ToArray();
    public char[][] Grid(int n) => Create(n, () => Str.ToCharArray());
    public int[] ArrInt1D(int n) => Create(n, () => Int);
    public long[] ArrLong1D(int n) => Create(n, () => Long);
    public int[][] ArrInt2D(int n) => Create(n, () => ArrInt);
    public long[][] ArrLong2D(int n) => Create(n, () => ArrLong);
    private Queue<string> q = new Queue<string>();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public T Next<T>() { if (q.Count == 0) foreach (var item in Str.Split(' ')) q.Enqueue(item); return (T)Convert.ChangeType(q.Dequeue(), typeof(T)); }
    public void Make<T1>(out T1 v1) => v1 = Next<T1>();
    public void Make<T1, T2>(out T1 v1, out T2 v2) { v1 = Next<T1>(); v2 = Next<T2>(); }
    public void Make<T1, T2, T3>(out T1 v1, out T2 v2, out T3 v3) { Make(out v1, out v2); v3 = Next<T3>(); }
    public void Make<T1, T2, T3, T4>(out T1 v1, out T2 v2, out T3 v3, out T4 v4) { Make(out v1, out v2, out v3); v4 = Next<T4>(); }
    public void Make<T1, T2, T3, T4, T5>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5) { Make(out v1, out v2, out v3, out v4); v5 = Next<T5>(); }
    public void Make<T1, T2, T3, T4, T5, T6>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6) { Make(out v1, out v2, out v3, out v4, out v5); v6 = Next<T6>(); }
    //public (T1, T2) Make<T1, T2>() { Make(out T1 v1, out T2 v2); return (v1, v2); }
    //public (T1, T2, T3) Make<T1, T2, T3>() { Make(out T1 v1, out T2 v2, out T3 v3); return (v1, v2, v3); }
    //public (T1, T2, T3, T4) Make<T1, T2, T3, T4>() { Make(out T1 v1, out T2 v2, out T3 v3, out T4 v4); return (v1, v2, v3, v4); }
}
public class Pair<T1, T2> : IComparable<Pair<T1, T2>>
{
    public T1 v1;
    public T2 v2;
    public Pair() { }
    public Pair(T1 v1, T2 v2)
    { this.v1 = v1; this.v2 = v2; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2> p)
    {
        var c = Comparer<T1>.Default.Compare(v1, p.v1);
        if (c == 0)
            c = Comparer<T2>.Default.Compare(v2, p.v2);
        return c;
    }
    public override string ToString() => $"{v1.ToString()} {v2.ToString()}";
    public void Deconstruct(out T1 a, out T2 b) { a = v1; b = v2; }
}

public class Pair<T1, T2, T3> : Pair<T1, T2>, IComparable<Pair<T1, T2, T3>>
{
    public T3 v3;
    public Pair() : base() { }
    public Pair(T1 v1, T2 v2, T3 v3) : base(v1, v2)
    { this.v3 = v3; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2, T3> p)
    {
        var c = base.CompareTo(p);
        if (c == 0)
            c = Comparer<T3>.Default.Compare(v3, p.v3);
        return c;
    }
    public override string ToString() => $"{base.ToString()} {v3.ToString()}";
    public void Deconstruct(out T1 a, out T2 b, out T3 c) { Deconstruct(out a, out b); c = v3; }
}
#endregion


/*
csc -debug D.cs && mono --debug D.exe <<< "0111001100111011101000"

S=0111001100111011101000
T=0011001100001011101000
*/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Reflection;

public class HelloWorld {
    public static void SolveCodeForces() {
        var S = Console.ReadLine();
        var n = S.Length;

        var F = new int[n + 1];
        var O = new int[n + 1];

        F[n - 1] = 1;
        O[n - 1] = S[n - 1] == '1' ? 1 : 0;

        for (var i = n - 2; i >= 0; i--) {
            if (S[i] == '1') {
                O[i] = O[i + 1] + 1;
                F[i] = Math.Max(O[i], F[i + 1]);
            }
            else {
                O[i] = O[i + 1];
                F[i] = F[i + 1] + 1;
            }
        }

        var T = S.ToCharArray();

        foreach (var ij in GroupByDigit(S)) {
            var start = ij[0];
            var end = ij[1];
            if (S[start] == '1') {
                for (var i = start; i <= end; i++) {
                    var c = end - i;
                    var a = end - start + 1;
                    var b = end + 1;
                    if (Math.Max(a + O[b], F[b]) >= Math.Max(a + O[b], a - c + F[b])) {
                        T[i] = '0';
                    }
                    else {
                        T[i] = '1';
                    }
                }
            }
        }

// System.Console.WriteLine("F    = " + F.Join());
// System.Console.WriteLine("Ones = " + Ones.Join());
// System.Console.WriteLine("A    = " + A.Join());

        // System.Console.WriteLine(S);
        System.Console.WriteLine(new string(T));
        // System.Console.WriteLine("0011001100001011101000");
    }

    static IEnumerable<int[]> GroupByDigit(string S) {
        var n = S.Length;
        var start = 0;
        for (var i = 1; i <= n; i++) {
            if (i == n || S[i] != S[start]) {
                yield return new[] { start, i - 1 };
                start = i;
            }
        }
    }

    static Scanner cin = new Scanner();
    static StringBuilder cout = new StringBuilder();

    static public void Main () {
        // Test();
        SolveCodeForces();
        // IncreaseStack(SolveCodeForces);
        // System.Console.Write(cout.ToString());
    }

    public static void IncreaseStack(ThreadStart action, int stackSize = 128000000)
    {
        var thread = new Thread(action, stackSize);
        thread.Start();
        thread.Join();
    }
}

public static class Helpers {
    public static string Join<T>(this IEnumerable<T> arr, string sep = " ") {
        return string.Join(sep, arr);
    }

    public static void Swap<T>(ref T a, ref T b) {
        var tmp = a;
        a = b;
        b = tmp;
    }

    public static T[] CreateArray<T>(int length, Func<int, T> itemCreate) {
        var result = new T[length];
        for (var i = 0; i < result.Length; i++)
            result[i] = itemCreate(i);
        return result;
    }
}

public class Scanner
{
    private string[] line = new string[0];
    private int index = 0;

    public string Next() {
        if (line.Length <= index) {
            line = Console.ReadLine().Split(' ');
            index = 0;
        }
        var res = line[index];
        index++;
        return res;
    }

    public int NI() {
        return int.Parse(Next());
    }

    public long NL() {
        return long.Parse(Next());
    }

    public ulong NUL() {
        return ulong.Parse(Next());
    }

    public string[] Array() {
        line = Console.ReadLine().Split(' ');
        index = line.Length;
        return line;
    }

    public int[] NIA(int emptyPrefixLen = 0) {
        var array = Array();
        var result = new int[emptyPrefixLen + array.Length];
        for (int i = 0; i < array.Length; i++)
            result[emptyPrefixLen + i] = int.Parse(array[i]);
        return result;
    }

    public long[] NLA() {
        var array = Array();
        var result = new long[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = long.Parse(array[i]);
        return result;
    }

    public ulong[] NULA() {
        var array = Array();
        var result = new ulong[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = ulong.Parse(array[i]);
        return result;
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using SB = System.Text.StringBuilder;
//using System.Threading.Tasks;
//using System.Text.RegularExpressions;
//using System.Globalization;
//using System.Diagnostics;
using static System.Console;
using System.Numerics;
using static System.Math;
using pair = Pair<int, int>;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    readonly Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;
    readonly int dom = 998244353;
    bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (b.CompareTo(a) < 0) { a = b; return true; } return false; }

    void solve()
    {
        var S = ReadLine();
        var T = new SB();

        int szero = 0;
        int sone = 0;
        int tzero = 0;
        int tone = 0;
        for (int i = S.Length - 1; i >= 0; i--)
        {
            if (S[i] == '0')
            {
                T.Append('0');
                szero = Max(szero, sone) + 1;
                tzero = Max(tzero, tone) + 1;

                continue;
            }

            sone++;

            var kari = Max(tzero, tone) + 1;
            if (kari > Max(sone, szero))
            {
                tone++;
                T.Append('1');
            }
            else
            {
                tzero = Max(tzero, tone) + 1;
                T.Append('0');
            }

        }
        var ret = T.ToString().reverse();
        WriteLine(ret);

    }
    /// <summary>
    /// 狭義単調 A[i] < A[j] を満たす最長部分列です
    /// </summary>
    /// <param name="A">クエリ配列</param>
    /// <returns>最長増加部分列の長さ</returns>
    int lis(int[] A)
    {
        var dp = new int[A.Length];
        for (int i = 0; i < A.Length; i++)
        {
            dp[i] = int.MaxValue;
        }
        foreach (var i in A)
        {
            dp[dp.lower_bound(i)] = i;
        }

        return dp.lower_bound(int.MaxValue);
    }
}

static class Ex
{
    public static void join<T>(this IEnumerable<T> values, string sep = " ") => WriteLine(string.Join(sep, values));
    public static string concat<T>(this IEnumerable<T> values) => string.Concat(values);
    public static string reverse(this string s) { var t = s.ToCharArray(); Array.Reverse(t); return t.concat(); }

    public static int lower_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) < 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
    public static int upper_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) <= 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
}

class Pair<T, U> : IComparable<Pair<T, U>> where T : IComparable<T> where U : IComparable<U>
{
    public T f; public U s;
    public Pair(T f, U s) { this.f = f; this.s = s; }
    public int CompareTo(Pair<T, U> a) => f.CompareTo(a.f) != 0 ? f.CompareTo(a.f) : s.CompareTo(a.s);
    public override string ToString() => $"{f} {s}";
}

class Scanner
{
    string[] s; int i;
    readonly char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan => ReadLine().Split();
    public int[] scanint => Array.ConvertAll(scan, int.Parse);
    public long[] scanlong => Array.ConvertAll(scan, long.Parse);
    public double[] scandouble => Array.ConvertAll(scan, double.Parse);
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint => int.Parse(next);
    public long nextlong => long.Parse(next);
    public double nextdouble => double.Parse(next);
}


using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Text;
using System;
using System.Numerics;

static class SolutionTemplate
{
    public static List<T> GetOrAddNew<K, T>(this Dictionary<K, List<T>> dic, K key)
    {
        if (dic == null) throw new ArgumentNullException();

        return (dic[key] = dic.ContainsKey(key) ? dic[key] : new List<T>());
    }

    public static V GetValueOrDefault<K, V>(this Dictionary<K, V> dic, K key)
    {
        if (dic == null) throw new ArgumentNullException();

        if (dic.ContainsKey(key)) return dic[key];
        return default(V);
    }
    public static void AddOrSet<K>(this Dictionary<K, long> dic, K key, long add)
    {
        if (dic == null) throw new ArgumentNullException();

        dic[key] = dic.GetValueOrDefault(key) + add;
    }

    public static void AddOrSet<K>(this Dictionary<K, int> dic, K key, int add)
    {
        if (dic == null) throw new ArgumentNullException();

        dic[key] = dic.GetValueOrDefault(key) + add;
    }

    public static int AddExt<T>(this HashSet<T> hs, T val)
    {
        if (hs == null) throw new ArgumentNullException();

        if (!hs.Contains(val)) hs.Add(val);
        return hs.Count();
    }

    static long readLong()
    {
        return long.Parse(Console.ReadLine().Trim());
    }

    static int readInt()
    {
        return int.Parse(Console.ReadLine().Trim());
    }

    static long[] readLongs()
    {
        return Array.ConvertAll(Console.ReadLine().Trim().Split(), long.Parse);
    }

    static int[] readInts()
    {
        return Array.ConvertAll(Console.ReadLine().Trim().Split(), int.Parse);
    }

    static string[] readStrings()
    {
        return Console.ReadLine().Trim().Split();
    }

    static string readString()
    {
        return Console.ReadLine().Trim();
    }

    public static int readInt(this StreamReader str)
    {
        if (str == null) throw new ArgumentNullException();
        return int.Parse(str.ReadLine().Trim());
    }

    public static int[] readInts(this StreamReader str)
    {
        if (str == null) throw new ArgumentNullException();
        return Array.ConvertAll(str.ReadLine().Trim().Split(), int.Parse);
    }

    static StringBuilder WriteArray(StringBuilder sb, IEnumerable lst, string delimeter)
    {
        if (lst == null)
            throw new ArgumentNullException(nameof(lst));
        if (sb == null)
            throw new ArgumentNullException(nameof(sb));

        foreach (var el in lst)
        {
            sb.Append(el);
            if (delimeter != null)
                sb.Append(delimeter);
        }
        return sb;
    }

    static StringBuilder WriteObject(StringBuilder sb, object obj, string delimeter)
    {
        if (obj == null)
            throw new ArgumentNullException(nameof(obj));
        if (sb == null)
            throw new ArgumentNullException(nameof(sb));

        sb.Append(obj);
        if (delimeter != null)
            sb.Append(delimeter);
        return sb;
    }

    static void Write(this object obj, string delimeter = " ")
    {
        if (obj == null)
            throw new ArgumentNullException(nameof(obj));

        var enm = obj as IEnumerable;
        StringBuilder sb = new StringBuilder();
        if (enm != null)
            WriteArray(sb, enm, delimeter);
        else
        {
            WriteObject(sb, obj, delimeter);
        }
        Console.Write(sb.ToString());
    }
    static void WriteLine(this object obj, string delimeter = " ")
    {
        obj.Write(delimeter);
        Console.WriteLine();
    }
    static void WriteS(params object[] obj)
    {
        obj.Write(" ");
    }
    static void WriteLineS(params object[] obj)
    {
        obj.WriteLine(" ");
    }

    static List<Tuple<int, int>> readEdges(int n)
    {
        List<Tuple<int, int>> res = new List<Tuple<int, int>>(n);
        for (int i = 0; i < n; i++)
        {
            var arr = readInts();
            res.Add(Tuple.Create(arr[0], arr[1]));
        }
        return res;
    }

    static Dictionary<int, List<Tuple<int, int>>> readWDicEdges(int n)
    {
        Dictionary<int, List<Tuple<int, int>>> dic =
            new Dictionary<int, List<Tuple<int, int>>>(n);
        for (int i = 0; i < n - 1; i++)
        {
            var arr = readInts();
            var tpl = Tuple.Create(arr[0], arr[1], arr[2]);
            dic[tpl.Item1] = dic.ContainsKey(tpl.Item1) ? dic[tpl.Item1] : new List<Tuple<int, int>>();
            dic[tpl.Item2] = dic.ContainsKey(tpl.Item2) ? dic[tpl.Item2] : new List<Tuple<int, int>>();

            dic[tpl.Item1].Add(Tuple.Create(tpl.Item2, tpl.Item3));
            dic[tpl.Item2].Add(Tuple.Create(tpl.Item1, tpl.Item3));

        }
        return dic;
    }

    static List<Tuple<int, int>> readWEdges(int n)
    {
        List<Tuple<int, int>> res = new List<Tuple<int, int>>(n);
        for (int i = 0; i < n; i++)
        {
            var arr = readInts();
            res.Add(Tuple.Create(arr[0], arr[1]));
        }
        return res;
    }

    static Dictionary<int, List<int>> readDicEdges(int n)
    {
        Dictionary<int, List<int>> dic =
            new Dictionary<int, List<int>>(n);

        for (int i = 0; i < n - 1; i++)
        {
            var arr = readInts();
            var tpl = Tuple.Create(arr[0], arr[1]);
            dic[tpl.Item1] = dic.ContainsKey(tpl.Item1) ? dic[tpl.Item1] : new List<int>();
            dic[tpl.Item2] = dic.ContainsKey(tpl.Item2) ? dic[tpl.Item2] : new List<int>();

            dic[tpl.Item1].Add(tpl.Item2);
            dic[tpl.Item2].Add(tpl.Item1);
        }
        return dic;
    }

    static int getLength(int s, int to, Dictionary<int, List<int>> gr)
    {
        Queue<int> q = new Queue<int>();
        Queue<int> lengths = new Queue<int>();
        HashSet<int> visited = new HashSet<int>();
        q.Enqueue(s);
        lengths.Enqueue(0);
        while (q.Count > 0)
        {
            var cur = q.Dequeue();
            var l = lengths.Dequeue();
            foreach (var item in gr[cur])
            {
                if (s == cur && to == item)
                    continue;

                if (item == to)
                    return l + 1;

                if (visited.Contains(item))
                    continue;
                q.Enqueue(item);
                lengths.Enqueue(l + 1);
                visited.Add(item);
            }

        }
        return int.MaxValue;
    }

    private static void Main(string[] args)
    {
        var str = readString();
        if (str.Length == 1)
        {
            '0'.Write();
            return;
        }
        var res = str.ToArray();

        int minDifl = 0;
        int minDifr = 0;
        int[] right = new int[str.Length + 1];

        for (int i = str.Length - 1; i >= 0; i--)
        {
            minDifr += (str[i] == '1' ? 1 : -1);
            minDifr = Math.Min(minDifr, 0);
            right[i] = minDifr;
        }

        for (int i = 0; i < res.Length; i++)
        {

            if (res[i] == '1')
            {
                if (minDifl >= 0 && right[i + 1] >= 0)
                {
                    res[i] = '0';
                }
            }

            minDifl += ((res[i] == '0' ? 1 : -1));
            minDifl = Math.Min(minDifl, 0);
        }

        res.Write("");

    }

}


using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Text;
using System;
using System.Numerics;

static class SolutionTemplate
{
    public static List<T> GetOrAddNew<K, T>(this Dictionary<K, List<T>> dic, K key)
    {
        if (dic == null) throw new ArgumentNullException();

        return (dic[key] = dic.ContainsKey(key) ? dic[key] : new List<T>());
    }

    public static V GetValueOrDefault<K, V>(this Dictionary<K, V> dic, K key)
    {
        if (dic == null) throw new ArgumentNullException();

        if (dic.ContainsKey(key)) return dic[key];
        return default(V);
    }
    public static void AddOrSet<K>(this Dictionary<K, long> dic, K key, long add)
    {
        if (dic == null) throw new ArgumentNullException();

        dic[key] = dic.GetValueOrDefault(key) + add;
    }

    public static void AddOrSet<K>(this Dictionary<K, int> dic, K key, int add)
    {
        if (dic == null) throw new ArgumentNullException();

        dic[key] = dic.GetValueOrDefault(key) + add;
    }

    public static int AddExt<T>(this HashSet<T> hs, T val)
    {
        if (hs == null) throw new ArgumentNullException();

        if (!hs.Contains(val)) hs.Add(val);
        return hs.Count();
    }

    static long readLong()
    {
        return long.Parse(Console.ReadLine().Trim());
    }

    static int readInt()
    {
        return int.Parse(Console.ReadLine().Trim());
    }

    static long[] readLongs()
    {
        return Array.ConvertAll(Console.ReadLine().Trim().Split(), long.Parse);
    }

    static int[] readInts()
    {
        return Array.ConvertAll(Console.ReadLine().Trim().Split(), int.Parse);
    }

    static string[] readStrings()
    {
        return Console.ReadLine().Trim().Split();
    }

    static string readString()
    {
        return Console.ReadLine().Trim();
    }

    public static int readInt(this StreamReader str)
    {
        if (str == null) throw new ArgumentNullException();
        return int.Parse(str.ReadLine().Trim());
    }

    public static int[] readInts(this StreamReader str)
    {
        if (str == null) throw new ArgumentNullException();
        return Array.ConvertAll(str.ReadLine().Trim().Split(), int.Parse);
    }

    static StringBuilder WriteArray(StringBuilder sb, IEnumerable lst, string delimeter)
    {
        if (lst == null)
            throw new ArgumentNullException(nameof(lst));
        if (sb == null)
            throw new ArgumentNullException(nameof(sb));

        foreach (var el in lst)
        {
            sb.Append(el);
            if (delimeter != null)
                sb.Append(delimeter);
        }
        return sb;
    }

    static StringBuilder WriteObject(StringBuilder sb, object obj, string delimeter)
    {
        if (obj == null)
            throw new ArgumentNullException(nameof(obj));
        if (sb == null)
            throw new ArgumentNullException(nameof(sb));

        sb.Append(obj);
        if (delimeter != null)
            sb.Append(delimeter);
        return sb;
    }

    static void Write(this object obj, string delimeter = " ")
    {
        if (obj == null)
            throw new ArgumentNullException(nameof(obj));

        var enm = obj as IEnumerable;
        StringBuilder sb = new StringBuilder();
        if (enm != null)
            WriteArray(sb, enm, delimeter);
        else
        {
            WriteObject(sb, obj, delimeter);
        }
        Console.Write(sb.ToString());
    }
    static void WriteLine(this object obj, string delimeter = " ")
    {
        obj.Write(delimeter);
        Console.WriteLine();
    }
    static void WriteS(params object[] obj)
    {
        obj.Write(" ");
    }
    static void WriteLineS(params object[] obj)
    {
        obj.WriteLine(" ");
    }

    static List<Tuple<int, int>> readEdges(int n)
    {
        List<Tuple<int, int>> res = new List<Tuple<int, int>>(n);
        for (int i = 0; i < n; i++)
        {
            var arr = readInts();
            res.Add(Tuple.Create(arr[0], arr[1]));
        }
        return res;
    }

    static Dictionary<int, List<Tuple<int, int>>> readWDicEdges(int n)
    {
        Dictionary<int, List<Tuple<int, int>>> dic =
            new Dictionary<int, List<Tuple<int, int>>>(n);
        for (int i = 0; i < n - 1; i++)
        {
            var arr = readInts();
            var tpl = Tuple.Create(arr[0], arr[1], arr[2]);
            dic[tpl.Item1] = dic.ContainsKey(tpl.Item1) ? dic[tpl.Item1] : new List<Tuple<int, int>>();
            dic[tpl.Item2] = dic.ContainsKey(tpl.Item2) ? dic[tpl.Item2] : new List<Tuple<int, int>>();

            dic[tpl.Item1].Add(Tuple.Create(tpl.Item2, tpl.Item3));
            dic[tpl.Item2].Add(Tuple.Create(tpl.Item1, tpl.Item3));

        }
        return dic;
    }

    static List<Tuple<int, int>> readWEdges(int n)
    {
        List<Tuple<int, int>> res = new List<Tuple<int, int>>(n);
        for (int i = 0; i < n; i++)
        {
            var arr = readInts();
            res.Add(Tuple.Create(arr[0], arr[1]));
        }
        return res;
    }

    static Dictionary<int, List<int>> readDicEdges(int n)
    {
        Dictionary<int, List<int>> dic =
            new Dictionary<int, List<int>>(n);

        for (int i = 0; i < n - 1; i++)
        {
            var arr = readInts();
            var tpl = Tuple.Create(arr[0], arr[1]);
            dic[tpl.Item1] = dic.ContainsKey(tpl.Item1) ? dic[tpl.Item1] : new List<int>();
            dic[tpl.Item2] = dic.ContainsKey(tpl.Item2) ? dic[tpl.Item2] : new List<int>();

            dic[tpl.Item1].Add(tpl.Item2);
            dic[tpl.Item2].Add(tpl.Item1);
        }
        return dic;
    }

    static int getLength(int s, int to, Dictionary<int, List<int>> gr)
    {
        Queue<int> q = new Queue<int>();
        Queue<int> lengths = new Queue<int>();
        HashSet<int> visited = new HashSet<int>();
        q.Enqueue(s);
        lengths.Enqueue(0);
        while (q.Count > 0)
        {
            var cur = q.Dequeue();
            var l = lengths.Dequeue();
            foreach (var item in gr[cur])
            {
                if (s == cur && to == item)
                    continue;

                if (item == to)
                    return l + 1;

                if (visited.Contains(item))
                    continue;
                q.Enqueue(item);
                lengths.Enqueue(l + 1);
                visited.Add(item);
            }

        }
        return int.MaxValue;
    }

    private static void Main(string[] args)
    {
        var str = readString();
        if (str.Length == 1)
        {
            '0'.Write();
            return;
        }
        StringBuilder res = new StringBuilder();

        for (int i = 1; i < str.Length; i++)
        {
            if (str[i] == '1' || str[i - 1] == '0')
            {
                res.Append('0');
            }
            else
            {
                res.Append('1');
            }
        }

        res.Append('0');
        res.Write();
    }

}


//spnauti-rusT {{{
use std::io::*; use std::str::{self,*}; use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::{self,*};
#[allow(unused_imports)] use std::iter::{self,*};
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_imports)] use std::cell::*;
#[allow(unused_macros)] macro_rules! min {
	($x:expr,$y:expr) => {{ let b=$y; let a=&mut$x; if b < *a {*a=b; true} else {false} }};
}
#[allow(unused_macros)] macro_rules! max {
	($x:expr,$y:expr) => {{ let b=$y; let a=&mut$x; if b > *a {*a=b; true} else {false} }};
}
#[allow(unused_macros)] macro_rules! l {
	($($v:ident),+ =$e:expr) => {$(let$v=$e;)+};
	($($v:ident),+:$t:ty=$e:expr) => {$(let$v:$t=$e;)+};
	(mut $($v:ident),+ =$e:expr) => {$(let mut$v=$e;)+};
	(mut $($v:ident),+:$t:ty=$e:expr) => {$(let mut$v:$t=$e;)+};
}
#[allow(unused_macros)] macro_rules! v {
	([$d:expr]$($s:tt)+) => {vec![v!($($s)+);$d]};
	([]) => {Vec::new()}; ([$e:expr]) => {Vec::with_capacity($e)}; (=$e:expr) => {$e};
}
#[allow(unused_macros)] macro_rules! rep { {[$c:expr]$($s:tt)+} => {for _ in 0..$c {$($s)+}} }
#[allow(dead_code)] fn reader() -> WordReaderC { WordReaderC::new() }
#[allow(dead_code)] fn writer() -> BufWriter<Stdout> { BufWriter::new(stdout()) }
struct WordReaderC {buf: Vec<u8>, pos: usize, q: std::io::StdinLock<'static>}//'
#[allow(dead_code)] impl WordReaderC {
	fn new() -> Self {
		let r = unsafe {&*Box::into_raw(Box::new(stdin()))};
		Self { q: r.lock(), buf: v!([]), pos: 0 }
	}
	fn next_line(&mut self) -> bool {
		self.buf.clear(); self.pos = 0;
		self.q.read_until(b'\n', &mut self.buf).unwrap_or(0) > 0
	}
	fn is_ws(c: u8) -> bool {
		c == b' ' || c == b'\r' || c == b'\n' || c == b'\t'
	}
	fn byte(&mut self) -> Option<u8> {
		if self.pos == self.buf.len() { if !self.next_line() { return None; } }
		self.pos += 1; Some(self.buf[self.pos - 1])
	}
	fn vb(&mut self) -> Vec<u8> {
		let mut s = v!([8]);
		let mut f = false;
		loop {
			if let Some(c) = self.byte() {
				if !Self::is_ws(c) {
					s.push(c);
					f = true;
				} else if f { break; }
			} else { break; }
		}
		s
	}
	fn board(&mut self, r: usize, c: Option<usize>) -> Vec<Vec<u8>> {
		let mut res = v!([r]);
		let c = c.unwrap_or(0);
		rep!{[r]
			let t = self.vb();
			assert!(c == 0 || t.len() == c);
			res.push(t);
		}
		res
	}
	fn framed_board(&mut self, r: usize, c: usize, f: u8) -> Vec<Vec<u8>> {
		let mut res = v!([r+2]);
		res.push( v!([c+2] = f) );
		rep!{[r]
			let mut t = self.vb();
			assert!(t.len() == c);
			t.reserve(2);
			t.insert(0,f);
			t.push(f);
			res.push(t);
		}
		res.push( v!([c+2] = f) );
		res
	}
	fn s(&mut self) -> String { String::from_utf8(self.vb()).expect("invalid utf8") }
	fn i(&mut self) ->    i32 { self.p() }
	fn l(&mut self) ->    i64 { self.p() }
	fn u(&mut self) ->  usize { self.p() }
	fn f(&mut self) ->    f64 { self.p() }
	fn vi(&mut self, n: usize) -> Vec<i32> { self.vp(n) }
	fn vl(&mut self, n: usize) -> Vec<i64> { self.vp(n) }
	fn vu(&mut self, n: usize) -> Vec<usize> { self.vp(n) }
	fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> { self.ip(n).into_iter() }
	fn iu(&mut self, n: usize) -> impl Iterator<Item=usize> { self.ip(n).into_iter() }
	fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
		let w = self.vb(); str::from_utf8(w.as_ref()).unwrap().parse::<T>().unwrap()
	}
	fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
		(0..n).map(|_|self.p()).collect()
	}
	fn ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
		self.vp(n).into_iter()
	}
	fn graph(&mut self, n: usize, m: usize) -> Vec<Vec<usize>> {
		let mut e = v!([n][]); rep!{[m] l!(a,b = self.u()-1); e[a].push(b); e[b].push(a); } e
	}
	fn graph_w<T: Copy+FromStr>(&mut self, n: usize, m: usize) -> Vec<Vec<(usize,T)>> where T::Err: Debug {
		let mut e = v!([n][]); rep!{[m] l!(a,b = self.u()-1); let c: T = self.p(); e[a].push((b,c)); e[b].push((a,c)); } e
	}
}
//------------------- End rusT }}}

fn main() {
	let mut rin = reader();
	let mut rout = writer();

	let s = rin.vb();
	let n = s.len();
	let mut st = v!([]);
	for i in 0..n {
		let mut used = false;
		if s[i] == b'0' {
			if let Some( (p,c) ) = st.pop() {
				if c == b'1' {
					used = true;
				} else {
					st.push( (p,c) );
				}
			}
		}
		if !used {
			st.push( (i,s[i]) );
		}
	}
	let mut t = s.clone();
	for (p,_) in st {
		t[p] = b'0';
	}
	writeln!(rout, "{}", str::from_utf8(&t).unwrap()).ok();
}


fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let s: Vec<char> = s.trim().chars().collect();
    let n = s.len();
    let mut ans: Vec<char> = vec!['0'; n];
    let mut stack = std::collections::VecDeque::<(usize, char)>::new();
    for (i, &c) in s.iter().enumerate() {
        if c == '0' && stack.len() > 0 && stack.back().unwrap().1 == '1' {
            let (k, _) = stack.pop_back().unwrap();
            ans[k] = '1';
        } else {
            stack.push_back((i, c));
        }
    }
    let ans: String = ans.into_iter().collect();
    println!("{}", ans);
}

fn main() {
    run();
}


#![allow(warnings)]

use std::io::{self, *};
use std::str::{self, *};

fn main() {
    let mut stdin = stdin();
    let mut s = String::new();
    let _ = stdin.read_to_string(&mut s);
    let mut x = 0;

    println!("{}",
             s
             .trim()
             .chars()
             .rev()
             .map(|c|
                  match c {
                      '0' => {
                          x += 1;
                          '0'
                      },
                      '1' if x == 0 => {
                          '0'
                      },
                      '1' => {
                          x -= 1;
                          '1'
                      },
                      _ => unimplemented!(),
                  }
             )
             .collect::<Vec<_>>()
             .iter()
             .rev()
             .collect::<String>()
    );
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

const (
	mod = 998244353
)

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	s := ""
	fmt.Fscanf(in, "%s\n", &s)
	ans := []byte{}
	zero := 0
	for i := len(s) - 1; i >= 0; i-- {
		if s[i] == '0' {
			zero++
			ans = append(ans, '0')
		} else if zero == 0 {
			ans = append(ans, '0')
		} else {
			zero--
			ans = append(ans, '1')
		}
	}
	ans = reverse(ans)
	fmt.Fprintf(out, "%s\n", string(ans))
}

func reverse(a []byte) []byte {
	ans := []byte{}
	for i := len(a) - 1; i >= 0; i-- {
		ans = append(ans, a[i])
	}
	return ans
}

func first(a int) int64 {
	ans := int64(0)
	base := int64(10)
	for a > 0 {
		tail := int64(a % 10)
		a /= 10
		ans += base * tail
		base *= 100
		ans %= mod
		base %= mod
	}
	return ans
}

func second(a int) int64 {
	ans := int64(0)
	base := int64(1)
	for a > 0 {
		tail := int64(a % 10)
		a /= 10
		ans += base * tail
		base *= 100
		ans %= mod
		base %= mod
	}
	return ans
}


from __future__ import division, print_function

def main():
    s = list(map(int, input()))
    n = len(s)
    t = [0] * n

    st = []
    for i in range(n):
        if s[i] == 1:
            st.append(i)
        else:
            if st:
                v = st.pop()
                t[v] = 1

    print(*t, sep='')

INF = float('inf')
MOD = 10**9 + 7

import os, sys
from atexit import register
from io import BytesIO
import itertools

if sys.version_info[0] < 3:
    input = raw_input
    range = xrange

    filter = itertools.ifilter
    map = itertools.imap
    zip = itertools.izip

if "LOCAL_" in os.environ:
    debug_print = print
else:
    sys.stdin = BytesIO(os.read(0, os.fstat(0).st_size))
    sys.stdout = BytesIO()
    register(lambda: os.write(1, sys.stdout.getvalue()))

    input = lambda: sys.stdin.readline().rstrip('\r\n')
    debug_print = lambda *x, **y: None

def input_as_list():
    return list(map(int, input().split()))

def array_of(f, *dim):
    return [array_of(f, *dim[1:]) for _ in range(dim[0])] if dim else f()

main()


import sys
range = xrange
input = raw_input

B = [int(x) for x in input()]
n = len(B)

sumB = sum(B)
if sumB == n or sumB == 0:
    print '0'*n
    sys.exit()

cur = 0
D = []
for i in reversed(range(n)):
    D.append(cur)
    if B[i] == 0:
        cur += 1
    else:
        cur -= 1
        if cur < 0:
            cur = 0

D = D[::-1]

for i in range(n):
    if B[i] == 1 and D[i] == 0:
        B[i] = 0
print ''.join(str(x) for x in B)


s = list(raw_input())
ones = []
for i in xrange(len(s)):
  if s[i] == '0':
    if ones:
      ones.pop()
  else:
    ones.append(i)
for i in ones:
  s[i] = '0'
print(''.join(s))


s = list(map(int, input()))
ans = []
cnt = 0
if s[0] == 1:
    cnt += 1
else:
    ans.append('0')
for i in range(1, len(s)):
    if s[i] == 0 and s[i - 1] == 0:
        ans.append('0')
    elif s[i] == 1:
        cnt += 1
    else:
        maba = 0
        b = 0
        for x in range(i, len(s)):
            if s[x] == 1:
                b -= 1
            else:
                b += 1
            maba = max(maba, b)
        maba = min(maba, cnt)
        for _ in range(cnt - maba):
            ans.append('0')
        for _ in range(maba):
            ans.append('1')
        cnt = 0
        ans.append('0')
for _ in range(len(s) - len(ans)):
    ans.append('0')
print(''.join(ans))


a=input()
a=list(a)
l=[]
for i in range(0,len(a)):
    l.append([a[i],i])
i=1
while(i<len(l)):
    if l[i][0]=='0' and l[i-1][0]=='1':
        l.pop(i)
        l.pop(i-1)
        i-=2
    i+=1
for i in range(0,len(l)):
    a[l[i][1]]=0
print (*a,sep="")


a=input()
a=list(a)
l=[]
for i in range(0,len(a)):
    l.append([a[i],i])
i=1
while(i<len(l)):
    if l[i][0]=='0' and l[i-1][0]=='1':
        l.pop(i)
        l.pop(i-1)
        i-=2
    if i==-1:
        i=0
    i+=1
for i in range(0,len(l)):
    a[l[i][1]]=0
print (*a,sep="")


s=list(map(int,input()))
stack=[]
for i in range(len(s)):
    if s[i]==1:
        stack.append(i)
    elif len(stack)!=0:
        stack=stack[:-1]
for i in stack:
    s[i]=0
s=list(map(str,s))
print(''.join(s))


l = list(input())
s = e = 0
m = 0
S = E = 0
n = len(l)
for i in range(n-1):
	if(l[i+1] < l[i]):
		e = i
		if(m <= e-s+1):
			S = s
			E = e
			m = e-s+1
		s = i+1
if(s == e):
	e = n-1
	if(m < e-s+1):
		S = s
		E = e
		m = e-s+1
#print(S,E)
if(E == n-1):
	for i in range(S,E+1):
		l[i] = '0'
else:
	for i in range(S,E):
		l[i] = '0'
print(''.join(l))


l = list(input())
ct = 0
n = len(l)
for i in range(n-1,-1,-1):
	if(l[i] == '0'):
		ct += 1
	else:
		if(ct != 0):
			ct -= 1
		else:
			l[i] = '0'
print(''.join(l))


from sys import stdin
s=stdin.readline().strip()
dp=[0 for i in range(len(s)+2)]
ons=[0 for i in range(len(s)+2)]
zs=[0 for i in range(len(s)+2)]
for i in range(len(s)-1,-1,-1):
    if s[i]=="1":
        ons[i]+=1
    if(i!=len(s)-1):
        ons[i]+=ons[i+1]
z=0
for i in range(len(s)-1,-1,-1):
    if(s[i]=="1"):
        dp[i]=max(1+ons[i+1],z)
    else:
        dp[i]=max(dp[i+1]+1,1+ons[i+1])
        z=dp[i]
    zs[i]=z

ans=""
for i in range(len(s)):
    if s[i]=="1":
        x=dp[i]
        y=1+dp[i+1]
        if x==y:
            ans+="0"
        else:
            ans+="1"
    else:
        ans+="0"
print(ans)


'''
    Author : thekushalghosh
'''
a = list(map(int, input()))
w = [0] * len(a)
q = []
for i in range(len(a)):
    if a[i] == 1:
        q.append(i)
    elif len(q) > 0:
        qw = q.pop()
        w[qw] = 1
print(*w,sep='')


s=input()
ans=list(s)
n=len(s)
dp=[0]*n
i=0
j=1
while j<n:
    if s[i]=="1" and s[j]=="0":
        dp[i]=1
        dp[j]=1
        if i>0 and j<n:
            while dp[i]==1 and i>0:
                i-=1
            j+=1
    else:
        j+=1
        i=j-1
#print(dp)
for i in range(n):
    if dp[i]==0:
        ans[i]="0"
print("".join(ans))


s=input()
ans=list(s)
n=len(s)
dp=[0]*n
i=0
j=1
while j<n:
    if s[i]=="1" and s[j]=="0":
        dp[i]=1
        dp[j]=1
       # print(i,j)
        if i>0:
            while dp[i]==1 and i>0:
                i-=1
        j+=1
    else:
        j+=1
        i=j-1
#print(dp)
for i in range(n):
    if dp[i]==0:
        ans[i]="0"
print("".join(ans))


s = input()

s = [*s]
c = m = 0

for i in range(len(s) - 1, -1, -1):
	c += -1 if s[i] == '0' else 1
	if c > m:
		s[i] = '0'
		m = c

print(''.join(s))


s = input()

import re
itr = [*re.finditer(r"((10)*10(10)*)|(1(10)*10(10)*0)", s)]

ind = set()

for i in itr:
	for j in range(i.span()[0], i.span()[1]):
		ind.add(j)

for i in range(len(s)):
	if i in ind:
		print(s[i], end='')
	else:
		print('0', end='')


s = input()

import re
itr = [*re.finditer(r"((10)*10(10)*)|(1(10)*10(10)*0)", s)]

d = []

for i in itr:
	d.append([*i.span()])

ind = set()

for i in range(len(d)):
	j = 0
	while d[i][0] - j >= max(0, 0 if i == 0 else d[i - 1][1]) and d[i][1] + j <= min(len(s) - 1, len(s) - 1 if i == len(d) - 1 else d[-1][0]):
		if s[d[i][0] - j] == '1' and s[d[i][1] + j] == '0':
			j += 1
		else:
			break
	d[i][0] -= j
	d[i][1] += j
	for j in range(d[i][0], d[i][1]):
		ind.add(j)

ind = set(range(len(s))) - ind
ans = [*s]
for i in ind:
	ans[i] = '0'

print(''.join(ans))


s = input()

import re
itr = [*re.finditer(r"((10)*10(10)*)*|(1(10)*10(10)*0)*", s)]

d = []

for i in itr:
	d.append([*i.span()])

ind = set()

for i in range(len(d)):
	j = 0
	while d[i][0] - j >= max(0, 0 if i == 0 else d[i - 1][1]) and d[i][1] + j <= min(len(s) - 1, len(s) - 1 if i == len(d) - 1 else d[-1][0]):
		if s[d[i][0] - j] == '1' and s[d[i][1] + j] == '0':
			j += 1
		else:
			break
	d[i][0] -= j
	d[i][1] += j
	for j in range(d[i][0], d[i][1]):
		ind.add(j)

ind = set(range(len(s))) - ind
ans = [*s]
for i in ind:
	ans[i] = '0'

print(''.join(ans))


s = input()

import re
itr = [*re.finditer(r"10", s)]

d = []

for i in itr:
	d.append([*i.span()])

ind = set()

for i in range(len(d)):
	for j in range(d[i][0], d[i][1]):
		ind.add(j)

ind = set(range(len(s))) - ind
ans = [*s]
for i in ind:
	ans[i] = '0'

print(''.join(ans))


S = list(map(int,input().strip()))
N = len(S)

stack = []
for i in range(N):
    s = S[i]
    if s == 0 and stack and stack[-1][0] == 1:
        stack.pop()
    else:
        stack.append((s, i))
T = S[:]
for i in tuple(map(list, zip(*stack)))[1]:
    T[i] = 0

print(''.join(map(str, T)))


''' CODED WITH LOVE BY SATYAM KUMAR '''

from sys import stdin, stdout
import heapq
import cProfile, math
from collections import Counter, defaultdict, deque
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
import sys

sys.setrecursionlimit(10 ** 6)  # max depth of recursion
threading.stack_size(2 ** 27)  # new thread will get stack of such size
fac_warm_up = False
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7

class MergeFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n
        self.lista = [[_] for _ in range(n)]

    def find(self, a):
        to_update = []
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
        for b in to_update:
            self.parent[b] = a
        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a == b:
            return
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]
        self.lista[a] += self.lista[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def prime_factors(n):  # n**0.5 complex
    factors = dict()
    for i in range(2, math.ceil(math.sqrt(n)) + 1):
        while n % i == 0:
            if i in factors:
                factors[i] += 1
            else:
                factors[i] = 1
            n = n // i
    if n > 2:
        factors[n] = 1
    return (factors)

def all_factors(n):
    return set(reduce(list.__add__,
                      ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def fibonacci_modP(n, MOD):
    if n < 2: return 1
    return (cached_fn(fibonacci_modP, (n + 1) // 2, MOD) * cached_fn(fibonacci_modP, n // 2, MOD) + cached_fn(
        fibonacci_modP, (n - 1) // 2, MOD) * cached_fn(fibonacci_modP, (n - 2) // 2, MOD)) % MOD

def factorial_modP_Wilson(n, p):
    if (p <= n):
        return 0
    res = (p - 1)
    for i in range(n + 1, p):
        res = (res * cached_fn(InverseEuler, i, p)) % p
    return res

def binary(n, digits=20):
    b = bin(n)[2:]
    b = '0' * (digits - len(b)) + b
    return b

def is_prime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True

def generate_primes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while p * p <= n:
        if prime[p]:
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    return prime

factorial_modP = []

def warm_up_fac(MOD):
    global factorial_modP, fac_warm_up
    if fac_warm_up: return
    factorial_modP = [1 for _ in range(fac_warm_up_size + 1)]
    for i in range(2, fac_warm_up_size):
        factorial_modP[i] = (factorial_modP[i - 1] * i) % MOD
    fac_warm_up = True

def InverseEuler(n, MOD):
    return pow(n, MOD - 2, MOD)

def nCr(n, r, MOD):
    global fac_warm_up, factorial_modP
    if not fac_warm_up:
        warm_up_fac(MOD)
        fac_warm_up = True
    return (factorial_modP[n] * (
                (pow(factorial_modP[r], MOD - 2, MOD) * pow(factorial_modP[n - r], MOD - 2, MOD)) % MOD)) % MOD

def test_print(*args):
    if testingMode:
        print(args)

def display_list(list1, sep=" "):
    stdout.write(sep.join(map(str, list1)) + "\n")

def display_2D_list(li):
    for i in li:
        print(i)

def prefix_sum(li):
    sm = 0
    res = []
    for i in li:
        sm += i
        res.append(sm)
    return res

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))

memory = dict()

def clear_cache():
    global memory
    memory = dict()

def cached_fn(fn, *args):
    global memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result

def ncr(n, r):
    return math.factorial(n) / (math.factorial(n - r) * math.factorial(r))

def binary_search(i, li):
    fn = lambda x: li[x] - x // i
    x = -1
    b = len(li)
    while b >= 1:
        while b + x < len(li) and fn(b + x) > 0:  # Change this condition 2 to whatever you like
            x += b
        b = b // 2
    return x

# -------------------------------------------------------------- MAIN PROGRAM

TestCases = False
fac_warm_up_size = 10 ** 5 + 100
optimise_for_recursion = False  # Can not be used clubbed with TestCases WHen using recursive functions, use Python 3

def main():
    st = list(stdin.readline().strip())
    res = []
    i=0
    while i < (len(st)):
        if st[i]=='1' and i+1<len(st) and st[i+1]=='0':
            res.append(1)
            res.append(0)
            i+=2
        else:
            res.append(0)
            i+=1
    display_list(res,'')

# --------------------------------------------------------------------- END=

if TestCases:
    for i in range(get_int()):
        main()
else:
    main() if not optimise_for_recursion else threading.Thread(target=main).start()


''' Hey stalker :) '''
INF = 10**10
def main():
    #print = out.append
    ''' Cook your dish here! '''
    st = list(input())
    stk = []
    for index, i in enumerate(st):
        if i=='0' and len(stk)>0 and stk[-1][0]=='1':
            stk.pop()
        else: stk.append([i, index])
    for li in stk:
        st[li[1]] = '0'
    print("".join(st))

''' Pythonista fLite 1.1 '''
import sys
#from collections import defaultdict, Counter
#from bisect import bisect_left, bisect_right
#from functools import reduce
#import math
#input = iter(sys.stdin.buffer.read().decode().splitlines()).__next__
out = []
get_int = lambda: int(input())
get_list = lambda: list(map(int, input().split()))
main()
#[main() for _ in range(int(input()))]
print(*out, sep='\n')


S = input()
N = len(S)
p = q = 0

prv = S[0]
c = 0
C = []
if S[0] == '1':
    C.append(0)
for ch in S:
    if ch != prv:
        C.append(c)
        c = 1
        prv = ch
    else:
        c += 1
C.append(c)

ans = []
r = 0
L = len(C)
for i in range(L-1, -1, -1):
    c = C[i]
    if i % 2:
        r += c
        if i != L-1:
            m = max(min(c-1, r), 0)
        else:
            m = max(min(c, r), 0)
        if m:
            r -= m
            ans.append("0"*m + "1"*(c-m))
        else:
            ans.append("1"*c)
    else:
        r -= c
        ans.append("0"*c)
ans.reverse()
print(*ans, sep='')


def main():
    import sys
    input = sys.stdin.readline

    s = [int(i) for i in input()[:-1]][::-1]
    n = len(s)
    dp = [[0] * n for _ in range(n)]
    for j in range(n):
        tmp = [0, 0]
        for i in range(j, n):
            if s[i] == 0:
                tmp[0] = max(tmp) + 1
                dp[j][i] = tmp[0]
            else:
                tmp[1] += 1
                dp[j][i] = tmp[1]

    t = ""
    dp2 = [[0] * n for _ in range(n)]
    tmp = [[0, 0] for _ in range(n)]
    for j in range(n):
        okay = 1
        prev = [0] * (j + 1)
        for i in range(j + 1):
            prev[i] = tmp[i][0]
            tmp[i][0] = max(tmp[i]) + 1
            dp2[i][j] = tmp[i][0]
            if dp2[i][j] != dp[i][j]:
                okay = 0

        if not okay:
            for i in range(j + 1):
                tmp[i][0] = prev[i]
                tmp[i][1] += 1
                dp2[i][j] = tmp[i][1]
            t += '1'
        else:
            t += '0'

    print(t[::-1])

    return 0

main()


s=input()
a,b,c=[],[],[]
count=0
for i in range(len(s)-1,-1,-1):
    a.append(s[i])
for i in range(len(a)):
    if(a[i]=='0'):
        count+=1
        b.append('0')
    elif(a[i]=='1' and count>0):
        count-=1
        b.append('1')
    elif(a[i]=='1' and count==0):
        b.append('0')

for i in range(len(b)-1,-1,-1):
    c.append(b[i])
ans=''.join(c)
print(ans)


s=[*input()]
c = m = 0
for i in range(len(s) - 1, -1, -1):
	c += -1 if s[i] == '0' else 1
	if c > m:
		s[i] = '0'
		m = c
print(''.join(s))


from sys import stdin
input = stdin.readline

s = input()

res = ""
min_dif = 0

for i in range(len(s)):
    if s[len(s)-i-1] == "0":
        res = "0"+res
        min_dif = min([-1, min_dif-1])
    else:
        if min_dif >= 0: res = "0"+res
        else: res = "1"+res
        min_dif = min([1, min_dif+1])
print(res)


s = input()

res = ""
min_dif = 0

for i in range(len(s)):
    if s[len(s)-i-1] == "0":
        res = "0"+res
        min_dif = min([-1, min_dif-1])
    else:
        if min_dif >= 0: res = "0"+res
        else: res = "1"+res
        min_dif = min([1, min_dif+1])
print(res)


s = list(map(int, input()))
ans = [0] * len(s)
back = []

for i, c in enumerate(s):
    if c == 0:
        if back:
            ans[back.pop()] = 1
    else:
        back.append(i)

print(*ans, sep='')


def main():
    s = input()
    n = len(s)

    st = []
    flags = [False for i in range(n)]

    for i in range(n):
        if s[i] == '1':
            st.append(i)
        elif len(st) != 0:
            st.pop()

    for i in range(len(st)):
        flags[st[i]] = True

    for i in range(n):
        if flags[i] == True:
            print("0", end = '')
        else:
            print(s[i], end = '')
    print()

main()


s = input()
n = len(s)
if n == 1:
	print(0)
elif n == 2:
	if s == "10":
		print("10")
	else:
		print("00")
else:
	s_lis = 0
	s_max = 0
	s_zero = 0
	t_zero = 0
	stack_01 = []
	t = []
	for i in range(n):
		t.append("0")
		t_zero += 1
		if s[i] == "0":
			s_zero += 1
		if i > 0 and s[i-1:i+1] == "10":
			t[i-1] = "1"
			t_zero -= 1
			stack_01.append(i-2)
		if s_max <= int(s[i]):
			s_lis += 1
			s_max = max(s_max, int(s[i]))
		if s_lis < s_zero:
			s_lis = s_zero
			s_max = 0
		if s_lis < t_zero:
			#print(t_01)
			while t[stack_01[-1]] == "1" or t[stack_01[-1]-1] == "1":
				stack_01.pop()
			t[stack_01[-1]] = "1"
			t_zero -= 1
			stack_01[-1] -= 1
	print(*t, sep="")


s = input()
n = len(s)
if n == 1:
	print(0)
elif n == 2:
	if s == "10":
		print("10")
	else:
		print("00")
else:
	s_lis = 0
	s_max = 0
	t_zero = 0
	stack_01 = []
	t = []
	for i in range(n):
		t.append("0")
		t_zero += 1
		if i > 0 and s[i-1:i+1] == "10":
			t[i-1] = "1"
			t_zero -= 1
			stack_01.append(i-2)
		if s_max <= int(s[i]):
			s_lis += 1
			s_max = max(s_max, int(s[i]))
		if s_lis < t_zero:
			#print(t_01)
			while t[stack_01[-1]] == "1" or t[stack_01[-1]-1] == "1":
				stack_01.pop()
			t[stack_01[-1]] = "1"
			t_zero -= 1
			stack_01[-1] -= 1
	print(*t, sep="")


s = input()
n = len(s)
if n == 1:
	print(0)
elif n == 2:
	if s == "10":
		print("10")
	else:
		print("00")
else:
	s_lis = 0
	s_max = 0
	s_zero = 0
	t_zero = 0
	stack_01 = []
	t = []
	for i in range(n):
		t.append("0")
		t_zero += 1
		if s[i] == "0":
			s_zero += 1
		if i > 0 and s[i-1:i+1] == "10":
			t[i-1] = "1"
			t_zero -= 1
			stack_01.append(i-2)
		if s_max <= int(s[i]):
			s_lis += 1
			s_max = max(s_max, int(s[i]))
		if s_lis <= s_zero:
			s_lis = s_zero
			s_max = 0
		if s_lis < t_zero:
			#print(t_01)
			while t[stack_01[-1]] == "1" or t[stack_01[-1]-1] == "1":
				stack_01.pop()
			t[stack_01[-1]] = "1"
			t_zero -= 1
			stack_01[-1] -= 1
	print(*t, sep="")


s = input()
n = len(s)
if n == 1:
	print(0)
elif n == 2:
	if s == "10":
		print("10")
	else:
		print("00")
else:
	s_lis = 0
	s_max = 0
	t_zero = 0
	t_01 = 0
	t = []
	for i in range(n):
		t.append("0")
		t_zero += 1
		if i > 0 and s[i-1:i+1] == "10":
			t[i-1] = "1"
			t_zero -= 1
			#print(i)
			if t[i-3] == "0":
				t_01 = i-2
		if s_max <= int(s[i]):
			s_lis += 1
			s_max = max(s_max, int(s[i]))
		if s_lis < t_zero:
			#print(t_01)
			t[t_01] = "1"
			t_zero -= 1
			t_01 -= 1
	print(*t, sep="")


s = input()
n = len(s)
if n == 1:
	print(0)
elif n == 2:
	if s == "10":
		print("10")
	else:
		print("00")
else:
	s_lis = 0
	s_max = 0
	s_zero = 0
	t_zero = 0
	stack_01 = []
	t = []
	for i in range(n):
		t.append("0")
		t_zero += 1
		if s[i] == "0":
			s_zero += 1
		if i > 0 and s[i-1:i+1] == "10":
			t[i-1] = "1"
			t_zero -= 1
			stack_01.append(i-2)
		if s_max <= int(s[i]):
			s_lis += 1
			s_max = max(s_max, int(s[i]))
		if s_lis <= s_zero:
			s_lis = s_zero
			s_max = 0
		if s_lis < t_zero:
			#print(t_01)
			while t[stack_01[-1]] == "1" or s[stack_01[-1]] == "0" or t[stack_01[-1]-1] == "1":
				stack_01.pop()
			t[stack_01[-1]] = "1"
			t_zero -= 1
			stack_01[-1] -= 1
	print(*t, sep="")


import os
import sys
from io import BytesIO, IOBase
# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# ------------------------------

from math import factorial
from collections import Counter, defaultdict, deque
from heapq import heapify, heappop, heappush

def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
def comb(n, m): return factorial(n) / (factorial(m) * factorial(n - m)) if n >= m else 0
def perm(n, m): return factorial(n) // (factorial(n - m)) if n >= m else 0
def mdis(x1, y1, x2, y2): return abs(x1 - x2) + abs(y1 - y2)
mod = 998244353
INF = float('inf')

# ------------------------------

def main():
    s = list(input())
    le = len(s)
    rec = []

    for i in range(le):
        if rec and s[i]=='0' and s[rec[-1]]=='1':
            rec.pop()
        else:
            rec.append(i)

    for i in rec: s[i] = '0'
    print(''.join(s))

if __name__ == "__main__":
    main()


s=input()
ans=[]
for i in range(0,len(s)):
    ans.append(s[i])
for i in range(0,len(s)-1):
    if(s[i]=='1' and s[i+1]=='1'):
        ans[i]='0'
ptr=len(ans)-1
for i in range(len(ans)-1,-1,-1):
    if(ans[i]=='0'):
        ptr=i
        break

for i in range(ptr+1,len(ans)):
    ans[i]='0'

ans=''.join(ans)
print(ans)


s=input()
ans=[]
for i in range(0,len(s)):
    ans.append(s[i])
c0=0
c1=0
for i in range(len(ans)-1,-1,-1):
    if(ans[i]=='0'):
        c0+=1
    elif(ans[i]=='1' and c1>=c0):
        ans[i]='0'
    else:
        c1+=1

ans=''.join(ans)
print(ans)


pp = input()
z = 1 if pp[0]=='0' else 0
zc = [z]
l = 1
lndl = [l]
for p in pp[1:]:
    l = max(z + 1, l + (1 if p == '1' else 0))
    z += 1 if p == '0' else 0
    lndl.append(l)
    zc.append(z)
lnda = lndl[-1]
o = 1 if pp[-1]=='1' else 0
oc = [o]
l = 1
lndr = [l]
for p in reversed(pp[:-1]):
    l = max(o + 1, l + (1 if p == '0' else 0))
    o += 1 if p == '1' else 0
    lndr.append(l)
    oc.append(o)
oc.reverse()
lndr.reverse()
qq = []
ez = 0
if pp[0] == '1':
    if max(oc[1], lndr[1] + 1) != lnda :
        qq.append('1')
    else:
        qq.append('0')
        ez += 1
else:
    qq.append('0')
for p, l, o, z, r in zip(pp[1:-1],lndl, oc[2:], zc, lndr[2:]):
    if p == '1':
        if max(l + o, z + ez + 1 + r) != lnda:
            qq.append('1')
        else:
            qq.append('0')
            ez += 1
    else:
        qq.append('0')

if len(pp) > 1:
    qq.append('0')
print(''.join(qq))


pp = input()
if len(pp) == 1:
    print('0')
    exit(0)
z = 1 if pp[0]=='0' else 0
zc = [z]
l = 1
lndl = [l]
for p in pp[1:]:
    l = max(z + 1, l + (1 if p == '1' else 0))
    z += 1 if p == '0' else 0
    lndl.append(l)
    zc.append(z)
lnda = lndl[-1]
o = 1 if pp[-1]=='1' else 0
oc = [o]
l = 1
lndr = [l]
for p in reversed(pp[:-1]):
    l = max(o + 1, l + (1 if p == '0' else 0))
    o += 1 if p == '1' else 0
    lndr.append(l)
    oc.append(o)
oc.reverse()
lndr.reverse()
qq = []
ez = 0
if pp[0] == '1':
    if max(oc[1], lndr[1] + 1) != lnda :
        qq.append('1')
    else:
        qq.append('0')
        ez += 1
else:
    qq.append('0')
for p, l, o, z, r in zip(pp[1:-1],lndl, oc[2:], zc, lndr[2:]):
    if p == '1':
        if max(l + o, z + ez + 1 + r) != lnda:
            qq.append('1')
        else:
            qq.append('0')
            ez += 1
    else:
        qq.append('0')

print(''.join(qq))


pp = input()
z = 1 if pp[0]=='0' else 0
zc = [z]
l = 1
lndl = [l]
for p in pp[1:]:
    l = max(z + 1, l + (1 if p == '1' else 0))
    z += 1 if p == '0' else 0
    lndl.append(l)
    zc.append(z)
lnda = lndl[-1]
o = 1 if pp[-1]=='1' else 0
oc = [o]
l = 1
lndr = [l]
for p in reversed(pp[:-1]):
    l = max(o + 1, l + (1 if p == '0' else 0))
    o += 1 if p == '1' else 0
    lndr.append(l)
    oc.append(o)
oc.reverse()
lndr.reverse()
jj = []
ez = 0
if pp[0] == '1':
    if max(oc[1], lndr[1] + 1) != lnda :
        jj.append('1')
    else:
        jj.append('0')
        ez += 1
else:
    jj.append('0')
for p, l, o, z, r in zip(pp[1:-1],lndl, oc[2:], zc, lndr[2:]):
    if p == '1':
        if max(l + o, z + ez + 1 + r) != lnda:
            jj.append('1')
        else:
            jj.append('0')
            ez += 1
    else:
        jj.append('0')

jj.append('0')
print(''.join(jj))


pp = input()
if len(pp) == 1:
    print('0')
    exit(0)
z = 1 if pp[0]=='0' else 0
zc = [z]
l = 1
lndl = [l]
for p in pp[1:]:
    l = max(z + 1, l + (1 if p == '1' else 0))
    z += 1 if p == '0' else 0
    lndl.append(l)
    zc.append(z)
lnda = lndl[-1]
o = 1 if pp[-1]=='1' else 0
oc = [o]
l = 1
lndr = [l]
for p in reversed(pp[:-1]):
    l = max(o + 1, l + (1 if p == '0' else 0))
    o += 1 if p == '1' else 0
    lndr.append(l)
    oc.append(o)
oc.reverse()
lndr.reverse()
qq = []
ez = 0
if pp[0] == '1':
    if max(oc[1], lndr[1] + 1) != lnda :
        qq.append('1')
    else:
        qq.append('0')
        ez += 1
else:
    qq.append('0')
for p, l, o, z, r in zip(pp[1:-1],lndl, oc[2:], zc, lndr[2:]):
    if p == '1':
        if max(l + o, z + ez + 1 + r) != lnda:
            qq.append('1')
        else:
            qq.append('0')
            ez += 1
    else:
        qq.append('0')

qq.append('0')
print(''.join(qq))


fun main() {
    val s = readLn()
    val n = s.length

    val t = IntArray(n) { s[it] - '0' }

    val ls = IntArray(n+1)
    val os = IntArray(n+1)

    for (i in n-1 downTo 0) {
        os[i] = os[i + 1]
        ls[i] = ls[i + 1]

        when(t[i]) {
            0 -> {
                ls[i]++
            }
            1 -> {
                os[i]++
                ls.checkMax(i, os[i])
            }
        }
    }

    val L = ls[0]
    var lp = 0
    var zp = 0
    for(i in 0 until n) {
        when(t[i]) {
            0 -> {
                zp++
                if(lp < zp) lp = zp
            }
            1 -> {
                if(maxOf(lp + os[i+1], zp + 1 + ls[i+1]) == L) {
                    t[i] = 0
                    zp++
                }
                lp++
            }
        }
    }

    println(t.joinToString(""))
}

fun IntArray.checkMax(i: Int, v: Int) { if(v > this[i]) this[i] = v }

fun readLn() = readLine()!!
fun readInt() = readLn().toInt()
fun readDouble() = readLn().toDouble()
fun readLong() = readLn().toLong()
fun readStrings() = readLn().split(' ')
fun readStringSeq() = readLn().splitToSequence(' ')
fun readInts() = readStrings().map { it.toInt() }
fun readIntSeq() = readStringSeq().map { it.toInt() }
fun readDoubles() = readStrings().map { it.toDouble() }
fun readDoubleSeq() = readStringSeq().map { it.toDouble() }
fun readLongs() = readStrings().map { it.toLong() }
fun readLongSeq() = readStringSeq().map { it.toLong() }

class Output {
    val outputSb = StringBuilder()
    fun print(o: Any?) { outputSb.append(o) }
    fun println() { outputSb.append('\n') }
    fun println(o: Any?) { outputSb.append(o).append('\n') }
    @JvmName("_print") fun Any?.print() = print(this)
    @JvmName("_println") fun Any?.println() = println(this)
    fun nowPrint() { kotlin.io.print(outputSb) }
}
inline fun output(block: Output.()->Unit) { Output().apply(block).nowPrint() }


fun main() {
    val s = readLn()
    val n = s.length

    val t = IntArray(n) { s[it] - '0' }

    val lp = IntArray(n+1)
    val zp = IntArray(n+1)

    for (i in 1..n) {
        zp[i] = zp[i - 1]
        lp[i] = lp[i - 1]

        when(t[i-1]) {
            0 -> {
                zp[i]++
                lp.checkMax(i, zp[i])
            }
            1 -> {
                lp[i]++
            }
        }
    }

    val ls = IntArray(n+1)
    val os = IntArray(n+1)

    for (i in n-1 downTo 0) {
        os[i] = os[i + 1]
        ls[i] = ls[i + 1]

        when(t[i]) {
            0 -> {
                ls[i]++
            }
            1 -> {
                os[i]++
                ls.checkMax(i, os[i])
            }
        }
    }

    val L = ls[0]
    var z = 1
    for(i in 0 until n) {
        if(t[i] == 0) continue
        if(maxOf(lp[i] + os[i+1], zp[i] + z + ls[i+1]) == L) {
            t[i] = 0
            z++
        }
    }

    println(t.joinToString(""))
}

fun IntArray.checkMax(i: Int, v: Int) { if(v > this[i]) this[i] = v }

fun readLn() = readLine()!!
fun readInt() = readLn().toInt()
fun readDouble() = readLn().toDouble()
fun readLong() = readLn().toLong()
fun readStrings() = readLn().split(' ')
fun readStringSeq() = readLn().splitToSequence(' ')
fun readInts() = readStrings().map { it.toInt() }
fun readIntSeq() = readStringSeq().map { it.toInt() }
fun readDoubles() = readStrings().map { it.toDouble() }
fun readDoubleSeq() = readStringSeq().map { it.toDouble() }
fun readLongs() = readStrings().map { it.toLong() }
fun readLongSeq() = readStringSeq().map { it.toLong() }

class Output {
    val outputSb = StringBuilder()
    fun print(o: Any?) { outputSb.append(o) }
    fun println() { outputSb.append('\n') }
    fun println(o: Any?) { outputSb.append(o).append('\n') }
    @JvmName("_print") fun Any?.print() = print(this)
    @JvmName("_println") fun Any?.println() = println(this)
    fun nowPrint() { kotlin.io.print(outputSb) }
}
inline fun output(block: Output.()->Unit) { Output().apply(block).nowPrint() }


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.StringTokenizer;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Andy Phan
 */
public class d {
    public static void main(String[] args) {
        FS in = new FS(System.in);
        PrintWriter out = new PrintWriter(System.out);

        String s = in.next();
        ArrayDeque<Integer> q = new ArrayDeque<>();
        boolean[] isFixed = new boolean[s.length()];
        for(int i = 0; i < s.length(); i++) {
            if(s.charAt(i) == '1') q.addLast(i);
            else if(!q.isEmpty()) {
                isFixed[i] = true;
                isFixed[q.pollLast()] = true;
            }
        }
        StringBuilder str = new StringBuilder();
        for(int i = 0; i < s.length(); i++) if(isFixed[i]) str.append(s.charAt(i)); else str.append(0);
        out.println(str);
        out.close();
    }

    static class FS {

        BufferedReader in;
        StringTokenizer token;

        public FS(InputStream str) {
            in = new BufferedReader(new InputStreamReader(str));
        }

        public String next() {
            if (token == null || !token.hasMoreElements()) {
                try {
                    token = new StringTokenizer(in.readLine());
                } catch (IOException ex) {
                }
                return next();
            }
            return token.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}


import java.util.*;
import java.io.*;

public class D {
    public static void main(String[] args) {
        FastScanner scanner = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        char[] ss = scanner.next().toCharArray();
        int n = ss.length;
        int[] s = new int[n];
        for(int i = 0; i < n; i++) s[i] = ss[i]-'0';
        ArrayDeque<Pair> stack = new ArrayDeque<>();
        for(int i = 0; i < n; i++) {
            //matching fixed string
            if (s[i] == 0 && stack.size() > 0 && stack.peek().a == 1) stack.pop();
            else stack.push(new Pair(s[i], i));
        }
        while(!stack.isEmpty()) {
            if (stack.peek().a == 1) s[stack.peek().b] = 0;
            stack.pop();
        }
        for(int i = 0; i < n; i++) out.print(s[i]);
        out.println();
        out.flush();
    }
    static class Pair {
        int a,b;
        public Pair(int aa, int bb) {
            a = aa; b = bb;
        }
    }
    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;
        public FastScanner(Reader in) {
            br = new BufferedReader(in);
        }
        public FastScanner() {
            this(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 readNextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}