#include <stdio.h>
#include <stdlib.h>

/* Add a neighbor into adjacency list (resize if needed) */
void add_edge(int **adj, int *adjSz, int *adjCap, int u, int v) {
    if (adjSz[u] >= adjCap[u]) {
        adjCap[u] *= 2;
        int *tmp = realloc(adj[u], adjCap[u] * sizeof(int));
        if (!tmp) exit(1);
        adj[u] = tmp;
    }
    adj[u][adjSz[u]++] = v;
}

/* BFS that returns the farthest node from start and sets outDist to its distance */
int bfs_farthest(int start, int m, int **adj, int *adjSz, int *outDist) {
    int *dist = malloc(m * sizeof(int));
    for (int i = 0; i < m; ++i) dist[i] = -1;

    int *q = malloc(m * sizeof(int));
    int head = 0, tail = 0;
    q[tail++] = start;
    dist[start] = 0;

    int farNode = start;
    int maxd = 0;

    while (head < tail) {
        int u = q[head++];
        for (int i = 0; i < adjSz[u]; ++i) {
            int v = adj[u][i];
            if (dist[v] == -1) {
                dist[v] = dist[u] + 1;
                q[tail++] = v;
                if (dist[v] > maxd) { maxd = dist[v]; farNode = v; }
            }
        }
    }

    free(q);
    free(dist);
    *outDist = maxd;
    return farNode;
}

int main() {
    int n;
    if (scanf("%d", &n) != 1) return 0;   // if input malformed, exit quietly

    if (n <= 0) {
        printf("0");
        return 0;
    }

    int *arr = malloc(n * sizeof(int));
    for (int i = 0; i < n; ++i) {
        if (scanf("%d", &arr[i]) != 1) arr[i] = -1;
    }

    /* map level-order indices -> compact node ids [0..m-1] for non -1 entries */
    int *idxToId = malloc(n * sizeof(int));
    for (int i = 0; i < n; ++i) idxToId[i] = -1;

    int m = 0;
    for (int i = 0; i < n; ++i) if (arr[i] != -1) idxToId[i] = m++;

    if (m == 0) {                     // all -1 -> empty tree -> diameter edges = 0
        printf("0");
        free(arr); free(idxToId);
        return 0;
    }

    /* adjacency lists for compact nodes */
    int *adj = malloc(m * sizeof(int));
    int *adjSz = calloc(m, sizeof(int));
    int *adjCap = malloc(m * sizeof(int));
    for (int i = 0; i < m; ++i) {
        adjCap[i] = 2;
        adj[i] = malloc(adjCap[i] * sizeof(int));
        adjSz[i] = 0;
    }

    /* build undirected edges between parent and children where present */
    for (int i = 0; i < n; ++i) {
        if (idxToId[i] == -1) continue;
        int u = idxToId[i];
        int l = 2 * i + 1;
        if (l < n && idxToId[l] != -1) {
            add_edge(adj, adjSz, adjCap, u, idxToId[l]);
            add_edge(adj, adjSz, adjCap, idxToId[l], u);
        }
        int r = 2 * i + 2;
        if (r < n && idxToId[r] != -1) {
            add_edge(adj, adjSz, adjCap, u, idxToId[r]);
            add_edge(adj, adjSz, adjCap, idxToId[r], u);
        }
    }

    /* double BFS (tree diameter): BFS from any node -> farthest A, BFS from A -> distance = diameter in edges */
    int dummy;
    int startNode = 0;             // valid since m > 0
    int far = bfs_farthest(startNode, m, adj, adjSz, &dummy);
    int diameterEdges = 0;
    bfs_farthest(far, m, adj, adjSz, &diameterEdges);

    printf("%d", diameterEdges);

    /* free memory (optional) */
    for (int i = 0; i < m; ++i) free(adj[i]);
    free(adj); free(adjSz); free(adjCap);
    free(arr); free(idxToId);

    return 0;
}