#include <bits/stdc++.h>

using namespace std;

template <typename T>
T F_HSC_max(T a, T b) {
    return max(a, b);
}

template <typename T>
T G_HSC_max(T a, T b, int i, int j) {
    return a + b;
}

template <typename T>
T F_HSC_sum(T a, T b) {
    return a + b;
}

template <typename T>
T G_HSC_sum(T a, T b, int i, int j) {
    return a + b * (j-i);
}

template <typename T>
struct HeapSegmentCounter {
    // Holds a set of numbers x_0, x_1, ..., x_{n-1}
    // In the following X_{i, j} refers to the set of numbers x_i, x_{i+1}, .., x_{j-1}
    // Supports the following operations:
    // (1) Add c to each of X_{i, j}
    // (2) Find the max/sum of X_{i, j}
    // (3) Find the smallest i such that max/sum of X_{0, i} is \ge c
    // (4) Find the smallest i such that max/sum of X_{0, i} is > c
    // (5) Find the biggest i such that max/sum of X_{i, n} is \ge c
    // (6) Find the biggest i such that max/sum of X_{i, n} is > c
    int n;
    // We consider a tree of size 2n-1 where:
    // i has two children, 2i+1 and 2i+2, if i < n-1, and otherwise i is a leaf.
    // Hence for i > 0, i has the parent floor((i-1)/2)
    // The leaf n-1+i for i = 0,..,n-1 represents x_i.
    vector<T> ys;
    // ys is a vector of size 2n-1 - one value of each node in the tree.
    // Let the path from n-1+i to the root, 0, consist of the nodes n-i+1 = u_0, ..., u_{r-1} = 0.
    // Then it holds that x_i = y_{u_0} + .. + y_{u_{r-1}}
    vector<T> zs;
    // zs is a vector of size 2n-1 and represents the nodes of the tree
    // Let i be a node and:
    // (1) Let the leafs in its subtree be n-1+j, .., n-1+k-1 (i.e. corresponding to X_{j, k})
    // (2) Let the path from i to the root be i = u_0, ..., u_{r-1} = 0.
    // Then z_i + u_1 + ... + u_{r-1} = max X_{j, k}.
    // Another way of seeing this statement is the following:
    //   The subtree rooted in i corresponds to a heap, where the values in the leafs are the
    //   sum of the values on the path to the root. z_i is the max value in this subtree.
    function<T (T, T)> F;
    function<T (T, T, int, int)> G;
    vector<int> left_leaf, right_leaf;
    T neutral;
    HeapSegmentCounter(const vector<T>& xs, function<T (T, T)> F, function<T (T, T, int, int)> G, T neutral):
        F(F), G(G), neutral(neutral) {
        int m = 1;
        while (m < (int) xs.size()) {
            m *= 2;
        }
        n = m;
        ys = vector<T>(2*n-1);
        zs = vector<T>(2*n-1);
        left_leaf = vector<int>(2*n-1);
        right_leaf = vector<int>(2*n-1);
        for (int i = 0; i < n; ++i) {
            ys[n-1+i] = xs[i];
            zs[n-1+i] = xs[i];
            left_leaf[n-1+i] = i;
            right_leaf[n-1+i] = i;
        }
        for (int i = n-2; i >= 0; --i) {
            zs[i] = F(zs[2*i+1], zs[2*i+2]);
            left_leaf[i] = left_leaf[2*i+1];
            right_leaf[i] = right_leaf[2*i+2];
        }
    }
    T _get_aggregate(int p, int i, int j) {
        // assert(i <= left_leaf[p] && right_leaf[p] < j);
        if (i <= left_leaf[p] && right_leaf[p]+1 <= j) {
            return zs[p];
        }
        i = max(i, left_leaf[p]);
        j = min(j, right_leaf[p]+1);
        if (i >= j) return neutral;
        T left = _get_aggregate(2*p+1, i, j);
        T right = _get_aggregate(2*p+2, i, j);
        return G(F(left, right), ys[p], i, j);
        
    }
    T get_aggregate(int i, int j) {
        // Returns F(x_i, x_{i+1}, ..., x_{j-1})
        assert (i <= j);
        return _get_aggregate(0, i, j);
    }
    void _add(int p, int i, int j, T c) {
        if (i <= left_leaf[p] && right_leaf[p]+1 <= j) {
            ys[p] += c;
            zs[p] = G(zs[p], c, left_leaf[p], right_leaf[p]+1);
            return;
        }
        i = max(i, left_leaf[p]);
        j = min(j, right_leaf[p]+1);
        if (i >= j) return;
        _add(2*p+1, i, j, c);
        _add(2*p+2, i, j, c);
        zs[p] = G(F(zs[2*p+1], zs[2*p+2]), ys[p], left_leaf[p], right_leaf[p]+1);
    }
    void add(int i, int j, T c) {
        assert (i <= j);
        _add(0, i, j, c);
    }
    int _lower_bound(int p, T left, T upper, T threshold) {
        if (p >= n-1) {
            return p - (n-1);
        }
        T new_upper = upper + ys[p];
        T left_child = F(left, G(zs[2*p+1], new_upper, left_leaf[2*p+1], right_leaf[2*p+1]+1));
        if (left_child >= threshold) {
            return _lower_bound(2*p+1, left, new_upper, threshold);
        }
        return _lower_bound(2*p+2, left_child, new_upper, threshold);
        
    }
    int lower_bound(T threshold) {
        // finds smallest i such that F(x_0, x_1, .., x_i) >= t
        if (zs[0] < threshold) {
            return n;
        }
        return _lower_bound(0, neutral, 0, threshold);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> xs(n), ones(n);
    for (int i = 0; i < n; ++i) {
        cin >> xs[i];
        --xs[i];
        xs[i] -= i;
        ones[i] = 1;
    }
    reverse(xs.begin(), xs.end());
    HeapSegmentCounter<int> heap(xs, F_HSC_max<int>, G_HSC_max<int>, -100000000);
    HeapSegmentCounter<int> sum_heap(ones, F_HSC_sum<int>, G_HSC_sum<int>, 0);
    if (heap.get_aggregate(0, n) > 0) {
        cout << -1 << endl;
        return 0;
    }
    deque<int> solution;
    for (int i = 0; i < n; ++i) {
        int j = heap.lower_bound(0);
        solution.push_front(sum_heap.get_aggregate(j, n));
        sum_heap.add(j, j+1, -1);
        heap.add(j, j+1, -2*n);
        heap.add(0, j, 1);
    }
    for (int s : solution) {
        cout << s << "\n";
    }
    return 0;
}

Measured memory_bytes: 256