Vasya has written some permutation p_1, p_2, …, p_n of integers from 1 to n, so for all 1 ≤ i ≤ n it is true that 1 ≤ p_i ≤ n and all p_1, p_2, …, p_n are different. After that he wrote n numbers next_1, next_2, …, next_n. The number next_i is equal to the minimal index i < j ≤ n, such that p_j > p_i. If there is no such j let's let's define as next_i = n + 1.

In the evening Vasya went home from school and due to rain, his notebook got wet. Now it is impossible to read some written numbers. Permutation and some values next_i are completely lost! If for some i the value next_i is lost, let's say that next_i = -1.

You are given numbers next_1, next_2, …, next_n (maybe some of them are equal to -1). Help Vasya to find such permutation p_1, p_2, …, p_n of integers from 1 to n, that he can write it to the notebook and all numbers next_i, which are not equal to -1, will be correct. 

Input

The first line contains one integer t — the number of test cases (1 ≤ t ≤ 100 000).

Next 2 ⋅ t lines contains the description of test cases,two lines for each. The first line contains one integer n — the length of the permutation, written by Vasya (1 ≤ n ≤ 500 000). The second line contains n integers next_1, next_2, …, next_n, separated by spaces (next_i = -1 or i < next_i ≤ n + 1).

It is guaranteed, that the sum of n in all test cases doesn't exceed 500 000.

In hacks you can only use one test case, so T = 1.

Output

Print T lines, in i-th of them answer to the i-th test case.

If there is no such permutations p_1, p_2, …, p_n of integers from 1 to n, that Vasya could write, print the only number -1.

In the other case print n different integers p_1, p_2, …, p_n, separated by spaces (1 ≤ p_i ≤ n). All defined values of next_i which are not equal to -1 should be computed correctly p_1, p_2, …, p_n using defenition given in the statement of the problem. If there exists more than one solution you can find any of them.

Example

Input


6
3
2 3 4
2
3 3
3
-1 -1 -1
3
3 4 -1
1
2
4
4 -1 4 5


Output


1 2 3
2 1
2 1 3
-1
1
3 2 1 4

Note

In the first test case for permutation p = [1, 2, 3] Vasya should write next = [2, 3, 4], because each number in permutation is less than next. It's easy to see, that it is the only satisfying permutation.

In the third test case, any permutation can be the answer because all numbers next_i are lost.

In the fourth test case, there is no satisfying permutation, so the answer is -1.
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Stack;
import java.util.Vector;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author cplayer
 */
public class Main {
    public static void main (String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        EPermutationRecovery solver = new EPermutationRecovery();
        int testCount = Integer.parseInt(in.next());
        for (int i = 1; i <= testCount; i++)
            solver.solve(i, in, out);
        out.close();
    }

    static class EPermutationRecovery {
        private int times;

        public void solve (int testNumber, InputReader in, OutputWriter out) {
            int n = in.readInt();
            int[] next = in.readIntArray(n);
            for (int i = 0; i < n; ++i) {
                if (next[i] == -1) {
                    next[i] = i + 2;
                }
            }
            int[] from = new int[n], to = new int[n];
            for (int i = n - 1, pt = 0; i >= 0; --i, ++pt) {
                from[pt] = next[i];
                to[pt] = i + 1;
            }
            Tree tree = Tree.createTree(n + 2, from, to);
            int[] res = new int[n + 2];
            times = n + 1;
            Arrays.fill(res, -1);
            dfs(tree, res, n + 1);
            if (check(res, next) == 0) {
                for (int i = 1; i <= n; ++i) {
                    out.print(res[i]);
                    out.print(i == n ? '\n' : ' ');
                }
            } else {
                out.println(-1);
            }
        }

        private int check (int[] res, int[] next) {
            int[] curNext = new int[res.length];
            Stack<Integer> stk = new Stack<>();
            int n = res.length - 2;
            for (int i = 1; i <= n; ++i) {
                while (!stk.isEmpty() && res[stk.peek()] < res[i]) {
                    curNext[stk.pop()] = i;
                }
                stk.push(i);
            }
            while (!stk.isEmpty()) {
                curNext[stk.pop()] = n + 1;
            }
            int compareRes = 0;
            for (int i = 1; i <= n; ++i) {
                if (next[i - 1] != -1) {
                    if (curNext[i] != next[i - 1]) {
                        compareRes = 1;
                    }
                }
            }
            return compareRes;
        }

        private void dfs (Tree tree, int[] res, int root) {
            res[root] = times;
            --times;
            for (int j = tree.firstOutBound(root); j != -1; j = tree.nextOutBound(j)) {
                dfs(tree, res, tree.destination(j));
            }
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter (OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter (Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print (char i) {
            writer.print(i);
        }

        public void close () {
            writer.close();
        }

        public void print (int i) {
            writer.print(i);
        }

        public void println (int i) {
            writer.println(i);
        }

    }

    static abstract class Edge {
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader (InputStream stream) {
            this.stream = stream;
        }

        public int[] readIntArray (int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = readInt();
            }
            return array;
        }

        public int read () {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt () {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public String readString () {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                if (Character.isValidCodePoint(c)) {
                    res.appendCodePoint(c);
                }
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public boolean isSpaceChar (int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace (int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next () {
            return readString();
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar (int ch);

        }

    }

    static class Tree {
        private int vertexCount;
        private int edgeCount;
        private int[] firstOutBound;
        private int[] nextOutBound;
        private int[] from;
        private int[] to;
        private long[] weight;
        private Edge[] edges;

        public Tree (int vertexCount, int maxEdgeCount) {
            this.vertexCount = vertexCount;
            this.edgeCount = 0;
            firstOutBound = new int[vertexCount];
            from = new int[maxEdgeCount];
            to = new int[maxEdgeCount];
            nextOutBound = new int[maxEdgeCount];
            Arrays.fill(firstOutBound, -1);
        }

        public static Tree createTree (int vertexCount, int[] from, int[] to) {
            Tree res = new Tree(vertexCount, from.length * 2);
            for (int i = 0; i < from.length; ++i) {
                res.addSimpleEdge(from[i], to[i]);
            }
            return res;
        }

        public int destination (int id) {
            return to[id];
        }

        public final int firstOutBound (int vertex) {
            return firstOutBound[vertex];
        }

        public final int nextOutBound (int vertex) {
            return nextOutBound[vertex];
        }

        protected TreeEdge createEdge (int id) {
            return new TreeEdge(id);
        }

        protected void ensureEdgeCapacity (int edgeSize) {
            if (from.length < edgeSize) {
                int newSize = Math.max(edgeSize, 2 * from.length);
                if (edges != null) {
                    edges = resize(edges, newSize);
                }
                from = resize(from, newSize);
                to = resize(to, newSize);
                nextOutBound = resize(nextOutBound, newSize);
                if (weight != null) {
                    weight = resize(weight, newSize);
                }
            }
        }

        public int addEdge (int fromId, int toId, long weight) {
            ensureEdgeCapacity(edgeCount + 1);
            if (firstOutBound[fromId] != -1) {
                nextOutBound[edgeCount] = firstOutBound[fromId];
            } else {
                nextOutBound[edgeCount] = -1;
            }
            firstOutBound[fromId] = edgeCount;
            this.from[edgeCount] = fromId;
            this.to[edgeCount] = toId;
            if (weight != 0) {
                if (this.weight == null) {
                    this.weight = new long[from.length];
                }
                this.weight[edgeCount] = weight;
            }
            if (edges != null) {
                edges[edgeCount] = createEdge(edgeCount);
            }
            return edgeCount++;
        }

        public int addWeightedEdge (int from, int to, long weight) {
            return addEdge(from, to, weight);
        }

        public int addSimpleEdge (int from, int to) {
            return addWeightedEdge(from, to, 0);
        }

        private Edge[] resize (Edge[] oriEdges, int newSize) {
            Edge[] newEdges = new Edge[newSize];
            System.arraycopy(oriEdges, 0, newEdges, 0, oriEdges.length);
            return newEdges;
        }

        private long[] resize (long[] oriArr, int newSize) {
            long[] newArr = new long[newSize];
            System.arraycopy(oriArr, 0, newArr, 0, oriArr.length);
            return newArr;
        }

        private int[] resize (int[] oriArr, int newSize) {
            int[] newArr = new int[newSize];
            System.arraycopy(oriArr, 0, newArr, 0, oriArr.length);
            return newArr;
        }

        protected class TreeEdge extends Edge {
            protected int id;

            protected TreeEdge (int id) {
                this.id = id;
            }

        }

    }
}

