#include <bits/stdc++.h>

using namespace std;
#define ll long long
#define ld long double
#define mk make_pair
#define pb push_back
#define sz(a) (int)(a).size()
#define rep(i, a, b) for (int i = (a), _b = (b); i < _b; ++i)

typedef complex<ld> cplex;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef pair<ii, int> iii;
typedef vector<ii> vii;
typedef vector<iii> viii;

const int multipleTest = 0;
const int N = 300000 + 7;
const int inf = 1000000007;

int dp[N];
string s;

class SegmentTree {
public:
    const static  int MAXN = 300000 + 7;
    struct node{
        int val;
        int leftChild;
        int rightChild;
        int leftIdx, rightIdx;
        node() {
            val = 0;
            rightChild = leftChild = -1;
        }
        void reset(int u, int v, int _left, int _right) {
            val = 0;
            leftChild = _left;
            rightChild = _right;
            leftIdx = u;
            rightIdx = v;
        }
    };
    
    node tree[MAXN * 4];
    int cnt = 0;
    
    void buildTree(node& root, int l, int r) {
        if (l == r) {
            root.val = l;
            root.reset(l, r, -1, -1);
            return;
        }
        int g = (l + r) >> 1;
        int leftChild = cnt++, rightChild = cnt++;
        buildTree(tree[leftChild], l, g);
        buildTree(tree[rightChild], g + 1, r);
        root.reset(l, r, leftChild, rightChild);
        
        int lhs = tree[leftChild].val;
        int rhs = tree[rightChild].val;
        if (dp[lhs] != dp[rhs]) {
            if (dp[lhs] < dp[rhs]) root.val = lhs;
            else root.val = rhs;
        } else {
            if (s[lhs] < s[rhs]) root.val = lhs;
            else root.val = rhs;
        }
    }
    
    void init(int l, int r) {
        cnt = 1;
        buildTree(tree[0], l, r);
    }
    
    void update(node& root, int i) {
        if (root.leftIdx == i && root.rightIdx == i) {
//            assert(u == i);
            root.val = i;
            return;
        }
        int g = (root.leftIdx + root.rightIdx) >> 1;
        if (i <= g)
            update(tree[root.leftChild], i);
        else
            update(tree[root.rightChild],  i);
        int lhs = tree[root.leftChild].val;
        int rhs = tree[root.rightChild].val;
        if (dp[lhs] != dp[rhs]) {
            if (dp[lhs] < dp[rhs]) root.val = lhs;
            else root.val = rhs;
        } else {
            if (s[lhs] < s[rhs]) root.val = lhs;
            else root.val = rhs;
        }
        return;
    }
    
    void update(int u, int v, int val) {
        assert(u <= v);
        update(tree[0], val);
    }
    
    int get(node& root, int u, int v) {
        if (u <= root.leftIdx && root.rightIdx <= v) return root.val;
        if (u > root.rightIdx || v < root.leftIdx) return -1;
        int lhs = get(tree[root.leftChild], u, v);
        int rhs = get(tree[root.rightChild], u, v);
        if (lhs == -1) return rhs;
        if (rhs == -1) return lhs;
        if (dp[lhs] != dp[rhs]) {
            if (dp[lhs] < dp[rhs]) return lhs; else return rhs;
        } else {
            if (s[lhs] < s[rhs]) return lhs; else return rhs;
        }
    }
    
    int get(int u, int v) {
        assert(u <= v);
        return get(tree[0], u, v);
    }
} segmentTree;

int nxt[N];
int last[N];
int trace[N];

void solve() {
    cin >> s;
    s = s + char('z' + 1);
    int n = s.size() - 1;
    
    rep(j, 0, 26) last[j] = n;
    
    for (int i = 0; i <= n; ++i) dp[i] = inf;
    
    dp[n] = 0;
    
    segmentTree.init(0, n);
    
    segmentTree.update(0, n, n);
    
    for (int i = n - 1; i >= 0; --i) {
        nxt[i] = last[s[i] - 'a'];
        last[s[i] - 'a'] = i;
        int idx = segmentTree.get(i + 1, nxt[i]);
        dp[i] = dp[idx] + 1;
        trace[i] = idx;
//        cout << i << ' ' << idx << ' ' << dp[i] << '\n';
        segmentTree.update(0, n, i);
    }

    rep(j, 0, 26) last[j] = -1;
    
    int minLen = 1 + dp[0];
    
    for (int i = 0; i < n; ++i) {
        last[s[i] - 'a'] = i;
        int found = -1;
        rep(j, 0, 26) if (last[j] == -1) found = j;
        if (found == -1) break;
        minLen = min(minLen, 1 + dp[i + 1]);
    }
    
    set<iii> st;
    if (dp[0] + 1 == minLen) {
//        cout << 'a';
//        int i = 0;
//        while (i < n) {
//            cout << s[i];
//            i = trace[i];
//        }
        st.insert(mk(mk(0, s[0]), 0));
//        return;
    }
    
    rep(j, 0, 26) last[j] = -1;
    for (int i = 0; i < n; ++i) {
        last[s[i] - 'a'] = i;
        int found = -1;
        rep(j, 0, 26) if (last[j] == -1) {
            found = j;
            break;
        }
        if (found == -1) break;
        if (minLen == dp[i + 1] + 1) {
//            cout << char(found + 'a');
//            ++i;
//            while (i < n) {
//                cout << s[i];
//                i = trace[i];
//            }
//            return;
            st.insert(mk(mk(found, s[i + 1]), i + 1));
        }
        
    }
    cout << char(st.begin()->first.first + 'a');
                      int i = st.begin()->second;
    while (i < n) {
                        cout << s[i];
                        i = trace[i];
                    }
    

}

int main() {
#ifdef _LOCAL_
    freopen("in.txt", "r", stdin);
    //    freopen("out.txt", "w", stdout);
#endif
    
    int Test = 1;
    if (multipleTest) {
        cin >> Test;
    }
    for(int i = 0; i < Test; ++i) {
        solve();
    }
    
#ifdef _LOCAL_
    cout<<"\n" << 1.0 * clock() / CLOCKS_PER_SEC <<endl;
#endif
}


Measured memory_bytes: 27072