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 
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;


public class Party {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
Reader r=new Reader();
Graph g=new Graph();
int n=r.nextInt();
List<Integer> graph[]=g.createGraph(n);
int a[]=new int[n];
boolean b=false;
int index=0;

for(int i=0;i<n;i++){
    a[i]=r.nextInt();
    
    if(i>0 && !b){
        if(a[i-1]!=a[i])b=true;
    }
}
if(!b){System.out.println(1);System.exit(0);}
ArrayList<Integer> al=new ArrayList<Integer>();
for(int i=0;i<n;i++){
    if(a[i]==-1){
        al.add(i);
        a[i]=0;}
    else{
        a[i]--;
        g.addEdge(graph, a[i],i);
    }
}
int ans=g.BFS(graph,index,al);
System.out.println(ans+1);
    }
    static class Graph{
        int distances[];
        int colour[];
        int parent[];
        public List<Integer>[] createGraph(int n){
            distances=new int[n];
            colour=new int[n];
            List<Integer> graph[]=new List[n];
            for(int i=0;i<n;i++)graph[i]=new ArrayList<Integer>();
            return graph;
        }
        public void addEdge(List<Integer> graph[],int s,int d){
            graph[s].add(d);
        }
        public int BFS(List<Integer> graph[],int s,ArrayList<Integer> al){
            Arrays.fill(distances, -1);
            
            Arrays.fill(colour, 'W');
            Queue<Integer> q=new LinkedList<Integer>();
            int size1=al.size();
            for(int xy=0;xy<size1;xy++){
                int j=al.get(xy);
                if(colour[j]=='W'){
            q.add(j);
            distances[j]=0;
                }
            while(q.size()>0){
                int x=q.remove();
                colour[x]='G';
                int size=graph[x].size();
                for(int i=0;i<size;i++){
                    int y=graph[x].get(i);
                    distances[y]=distances[x]+1;
                    if(colour[y]=='W')
                    q.add(y);
                }
                colour[x]='B';
            }
            
            }
            int max=Integer.MIN_VALUE;
            for(int i=0;i<distances.length;i++){
                max=Math.max(max, distances[i]);
            }
            return max;
        }
    }
static class Reader {
    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader() {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException {
        byte[] buf = new byte[1000000];
        int cnt = 0, c;
        while ((c = read()) != -1) {
            if (c == '\n')
                break;
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException {
        int ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public long nextLong() throws IOException {
        long ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public double nextDouble() throws IOException {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (c == '.')
            while ((c = read()) >= '0' && c <= '9')
                ret += (c - '0') / (div *= 10);
        if (neg)
            return -ret;
        return ret;
    }

    private void fillBuffer() throws IOException {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1)
            buffer[0] = -1;
    }

    private byte read() throws IOException {
        if (bufferPointer == bytesRead)
            fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException {
        if (din == null)
            return;
        din.close();
    }
}
}
