## 1. Abridged Problem Statement

Given a decimal number `N` with up to 1000 digits and an integer `K`, remove exactly `K` digits from `N` while preserving the order of the remaining digits. Output the maximum possible resulting number.

`N` has no leading zeroes, and `0 ≤ K < number of digits in N`.

---

## 2. Detailed Editorial

We need choose a subsequence of digits of `N` of length:

```text
len(N) - K
```

such that the resulting number is as large as possible.

Since all possible answers have the same length, maximizing the number is equivalent to maximizing it lexicographically digit by digit.

### Greedy Idea

At each step, we want the next digit of the answer to be as large as possible.

Suppose the answer must have length `L = len(N) - K`.

For the first digit, we may delete at most `K` digits before it. Therefore, the first chosen digit must be among:

```text
N[0], N[1], ..., N[K]
```

To maximize the answer, we choose the largest digit in this range.

After choosing a digit, we continue similarly for the remaining suffix.

### Layered greedy used by the C++ solution

The C++ solution builds the answer one position at a time, keeping a set of
candidate source indices (`valid_states`) that could end the current optimal
prefix.

- For the first answer digit, any index in `[0, K]` is reachable (at most `K`
  digits may be deleted before it). The largest digit in that window is taken,
  and every index attaining it becomes a candidate.
- For a later answer position `l`, a candidate index `i` has already used
  `i - l + 1` deletions to reach there, so from it the next digit can land on
  any index up to `i + (K - (i - l + 1)) + 1`. We mark the union of these
  reachable indices in `can_visit`, scan it for the maximal digit, and keep the
  indices matching it as candidates for the next position.

Iterating the candidate list in reversed (descending index) order lets the
inner loop stop as soon as it hits an already-marked index, so each next-layer
position is marked only once.

The greedy invariant is the same as the classic monotonic-stack version: every
prefix produced is lexicographically maximal among all feasible prefixes.

---

### Monotonic Stack view (used by the Python solution)

The same greedy can be implemented with a monotonic stack.

We scan the digits from left to right and maintain a stack of digits forming
the current best prefix.

When we see a new digit `d`, if the last digit in the stack is smaller than `d`
and deletions remain, removing that smaller digit makes the number larger. So
while:

```text
stack is not empty
and deletions remain
and stack[-1] < current digit
```

we pop from the stack. Then we push the current digit.

At the end, if we still have deletions left, we remove digits from the end of
the stack, because the number is already non-increasing and deleting from the
end hurts the least.

---

### Example

Input:

```text
1992 2
```

Process:

- Read `1`, stack = `1`
- Read `9`, pop `1`, stack = `9`
- Read second `9`, stack = `99`
- Read `2`, stack = `992`

We have deleted one digit so far, but must delete `2`, so delete one digit from the end:

```text
99
```

Answer:

```text
99
```

---

### Correctness Argument

Consider the leftmost position where a solution differs from the greedy result.

The greedy algorithm always removes smaller previous digits when a larger digit appears and deletions are available. Therefore, whenever it keeps a digit before a larger digit, it must be because deleting it would either be impossible or would exceed the allowed number of deletions.

If another solution had a larger digit at the first differing position, then the greedy algorithm would also have been able to remove the smaller previous digits and place that larger digit earlier. Since it did not, such a solution cannot exist.

Thus, every prefix produced by the greedy algorithm is lexicographically maximal among all feasible prefixes. Therefore, the final number is maximal.

---

### Complexity

Let `D = len(N)`.

The monotonic-stack version pushes and pops each digit at most once, giving
`O(D)`. The layered C++ version processes at most `D` answer positions and, per
position, marks each next index once thanks to the reversed iteration, so it is
`O(D^2)` in the worst case — easily fast enough for `D ≤ 1000`.

```text
Memory complexity: O(D)
```

---

## 3. C++ Solution

```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

int k;
string n;

void read() { cin >> n >> k; }

void solve() {
    // We delete exactly K digits and keep the remaining len = |N| - K digits
    // in order, choosing them so the resulting number is maximal. Build the
    // answer greedily one digit at a time: for each output position take the
    // largest digit reachable, and keep every source index that attains it as
    // a candidate start for the next digit.
    //
    // The first digit may come from any index in [0, K], since len - 1 digits
    // must remain after it. For a later position l, a candidate index i has
    // already used i - l + 1 deletions to get there, so from it the next digit
    // can reach any index up to i + (K - (i - l + 1)) + 1 = K + l. We mark the
    // union of these reaches in can_visit, scan it for the best digit, and keep
    // the indices that match it as the candidate set for the following
    // position.

    string ans;
    vector<int> valid_states;

    char best = 0;
    for(int i = 0; i <= k; i++) {
        best = max(best, n[i]);
    }

    for(int i = 0; i <= k; i++) {
        if(n[i] == best) {
            valid_states.push_back(i);
        }
    }

    ans.push_back(best);

    int len = n.size() - k;
    for(int l = 1; l < len; l++) {
        vector<bool> can_visit(n.size(), false);
        reverse(valid_states.begin(), valid_states.end());
        for(int i: valid_states) {
            int ck = i - l + 1;
            for(int j = 0; j <= k - ck; j++) {
                int nxt = i + j + 1;
                if(nxt >= (int)n.size() || can_visit[nxt]) {
                    break;
                }
                can_visit[nxt] = true;
            }
        }

        char best = 0;
        for(int i = 0; i < (int)n.size(); i++) {
            if(can_visit[i]) {
                best = max(best, n[i]);
            }
        }

        vector<int> new_valid_states;
        for(int i = 0; i < (int)n.size(); i++) {
            if(n[i] == best && can_visit[i]) {
                new_valid_states.push_back(i);
            }
        }

        ans.push_back(best);
        valid_states = new_valid_states;
    }

    cout << ans << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

---

## 4. Python Solution with Detailed Comments

This Python solution uses the simpler monotonic stack greedy method.

```python
import sys  # Import sys for fast input and output.


def main():
    # Read all whitespace-separated input tokens.
    data = sys.stdin.read().split()

    # If input is empty, do nothing.
    if not data:
        return

    # N may have up to 1000 digits, so read it as a string.
    n = data[0]

    # K is the exact number of digits to remove.
    k = int(data[1])

    # The final answer must contain this many digits.
    keep = len(n) - k

    # This stack stores the digits of the best number built so far.
    stack = []

    # Number of digits removed so far.
    removed = 0

    # Process digits from left to right.
    for digit in n:
        # While the last chosen digit is smaller than the current digit,
        # removing it will make the resulting number larger.
        #
        # We may do this only if:
        # - the stack is not empty,
        # - we still have deletions available,
        # - the previous digit is smaller than the current one.
        while removed < k and stack and stack[-1] < digit:
            stack.pop()       # Delete the smaller previous digit.
            removed += 1      # Count this deletion.

        # Keep the current digit.
        stack.append(digit)

    # If we did not use all deletions, remove remaining digits from the end.
    #
    # This happens when the digits are in non-increasing order, for example:
    # N = 98765, K = 2.
    extra = k - removed

    if extra > 0:
        # Removing from the end damages the number least.
        stack = stack[:-extra]

    # The stack now contains exactly len(n) - k digits.
    # As a safety measure, slice to keep digits in case of any edge condition.
    answer = ''.join(stack[:keep])

    # Output the maximum possible number.
    sys.stdout.write(answer)


if __name__ == "__main__":
    main()
```

---

## 5. Compressed Editorial

We need the maximum subsequence of `N` of length `len(N) - K`.

Greedily pick, for each output position, the largest digit reachable given the
remaining deletion budget. The Python solution realizes this with a monotonic
decreasing stack: scan digits left to right, and while the stack is nonempty,
deletions remain, and the stack top is smaller than the current digit, pop the
stack; then push the current digit; if deletions remain after the scan, remove
digits from the end. The C++ solution does the equivalent by tracking the set
of candidate source indices per answer position.

This greedily ensures that larger digits are moved as far left as possible.
Since all answers have the same length, lexicographic maximum equals numeric
maximum.
