#include <alloca.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

const int mod = (int)1e9 + 7;

int main() {
  int i, j, n, *a, *next, *rank, *c, ans = 1;
  struct edge {
    int to;
    struct edge *next;
  } **g;
  assert(freopen("binary.in", "r", stdin));
  assert(freopen("binary.out", "w", stdout));

  assert(scanf("%d", &n) == 1);
  a = alloca(sizeof(a[0]) * n);
  for (i = 0; i < n; i++)
    assert(scanf("%d", &a[i]) == 1);

  next = alloca(sizeof(next[0]) * n);
  rank = alloca(sizeof(rank[0]) * n);
  g = alloca(sizeof(g[0]) * n);
  c = alloca(sizeof(c[0]) * n);
  for (i = 0; i < n; i++)
    next[i] = i, rank[i] = 0, g[i] = 0, c[i] = 0;

  /* nested functions are gcc extension for C */
  int get( int u ) {
    return next[u] == u ? u : (next[u] = get(next[u]));
  }
  void merge( int a, int b ) {
    a = get(a);
    b = get(b);
    if (rank[a] <= rank[b])
      next[a] = b;
    else
      next[b] = a;
  }

  for (i = 1; i < n; i++) {
    if (a[i] == -1)
      continue;
    if (a[i] > n - i) {
      ans = 0;
      continue;
    }
    for (j = 0; j < a[i]; j++)
      merge(j, i + j);
  }

  void edge( int a, int b ) {
    struct edge *e = (struct edge *)malloc(sizeof(struct edge));
    e->to = b;
    e->next = g[a];
    g[a] = e;
  }

  for (i = 1; i < n; i++)
    if (a[i] != -1 && a[i] < n - i)
      edge(get(a[i]), get(i + a[i]));

  void dfs( int u, int cc ) {
    struct edge *x;
    c[u] = cc;
    for (x = g[u]; x != 0; x = x->next)
      if (c[x->to] == 0)
        dfs(x->to, 3 - cc);
      else if (c[x->to] != 3 - cc)
        ans = 0;
  }

  for (i = 0; i < n; i++) {
    if (c[get(i)])
      continue;
    ans = (ans * 2) % mod;
    dfs(get(i), 1);
  }

  printf("%d\n", ans);

  return 0;
}

