A company has n employees numbered from 1 to n. Each employee either has no immediate manager or exactly one immediate manager, who is another employee with a different number. An employee A is said to be the superior of another employee B if at least one of the following is true:

  * Employee A is the immediate manager of employee B
  * Employee B has an immediate manager employee C such that employee A is the superior of employee C. 



The company will not have a managerial cycle. That is, there will not exist an employee who is the superior of his/her own immediate manager.

Today the company is going to arrange a party. This involves dividing all n employees into several groups: every employee must belong to exactly one group. Furthermore, within any single group, there must not be two employees A and B such that A is the superior of B.

What is the minimum number of groups that must be formed?

Input

The first line contains integer n (1 ≤ n ≤ 2000) — the number of employees.

The next n lines contain the integers pi (1 ≤ pi ≤ n or pi = -1). Every pi denotes the immediate manager for the i-th employee. If pi is -1, that means that the i-th employee does not have an immediate manager. 

It is guaranteed, that no employee will be the immediate manager of him/herself (pi ≠ i). Also, there will be no managerial cycles.

Output

Print a single integer denoting the minimum number of groups that will be formed in the party.

Examples

Input

5
-1
1
2
1
-1


Output

3

Note

For the first example, three groups are sufficient, for example: 

  * Employee 1 
  * Employees 2 and 4 
  * Employees 3 and 5 
//var input = "2\n2\n-1";
//var index = 0;
//
//function readline(){
//    var data = input.split('\n');
//    if(index < data.length)
//        return data[index++];
//}
//
//function print(output){
//    console.log(output);
//}

var a = [];
var ans = 0;

function Graph(n){
    this.adj = new Array(n);
    for(var i = 0; i < n; i++)
        this.adj[i] = [];
};

function Edge(vertexTo, weightEdge){
    this.vertexTo = vertexTo;
    this.weightEdge = weightEdge;
};

Graph.prototype.addEdge = function(vertexFrom, vertexTo, weightEdge){
    var edge = new Edge(vertexTo, weightEdge);
    this.adj[vertexFrom].push(edge);
}

var Constants  = {
    WHITE_NODE : 0,
    GRAY_NODE : 1,
    BLACK_NODE : 2,
    NULL_PARENT : -1
}

function DepthFirstSearch(graph){
    this.adj = graph.adj;
    this.used = new Array(graph.adj.length);
    this.parent = new Array(graph.adj.length);
    for(var i = 0; i < this.adj.length; i++){
        this.used[i] = Constants.WHITE_NODE;
        this.parent[i] = Constants.NULL_PARENT;
    }
    this.path = [];
};

DepthFirstSearch.prototype.dfs = function(vertex, depth){
    ans = Math.max(ans, depth);
    depth++;
    this.used[vertex] = Constants.GRAY_NODE;
    for(var i = 0; i < this.adj[vertex].length; i++){
        var edge = this.adj[vertex][i];
        var next = edge.vertexTo;
        if(this.used[next] == Constants.WHITE_NODE){
            this.parent[next] = vertex;
            arguments.callee.apply(this, [next, depth]);
        }
    }
    this.used[vertex] = Constants.BLACK_NODE;
}

DepthFirstSearch.prototype.searchPath = function(vertexFrom, vertexTo){
    if(vertexFrom == vertexTo){
        this.path.push(vertexFrom);
    }else{
        if (this.parent[vertexTo] != Constants.NULL_PARENT) {
            arguments.callee.apply(this, [vertexFrom, this.parent[vertexTo]]);
            this.path.push(vertexTo);
        }
    }
}

DepthFirstSearch.prototype.getPath = function(vertexFrom, vertexTo){
    this.searchPath(vertexFrom, vertexTo);
    return this.path;
}

function main() {
    var n  = readline();
    var graph = new Graph(n);
    for(var i = 0; i < n; i++){
        var val = readline();
        if(val == -1) {
            a.push(i);
            continue;
        }
        graph.addEdge(val - 1, i);
    }
    for(var i = 0; i < a.length; i++){
        var alg = new DepthFirstSearch(graph);
        alg.dfs(a[i], 1);
    }
    print(ans);
    return 0;
}

main();


