// Original C++ solution (slower):
#include<cstdio>

#include<iostream>

#include<vector>

#include<string>

#include<algorithm>

#include<queue>

#include<map>

#include<set>



using namespace std;



#define reps(i,f,n) for(int i=f;i<int(n);i++)

#define rep(i,n) reps(i,0,n)

#define pb push_back





int n;

vector<int> dat;



bool input(){

	cin>>n;

	

	rep(i,n){

		int a;

		cin>>a;

		dat.pb(a);

	}

	

	return true;

}



const int N = 111111;





class P{

	public:

	int pos,val;

	P(int pos, int val):pos(pos), val(val){}

	bool operator < (const P& a) const{

		if(val==a.val)return pos>a.pos;;

		return val>a.val;

	}

};



typedef pair<int,int> pii;



vector<pii> edge[N];

int visit[N];

void solve(){

	

	rep(i,n){

		if(dat[i]!=0){

			edge[i].pb(pii(i+dat[i], 0));

		}

	}

	

	rep(i,n){

		rep(j,6){

			if(dat[i]==0){

				if(i+j+1<=n-1){

					edge[i].pb(pii(i+j+1, 1));

				}

			}

		}

	}

	

	priority_queue<P> que;

	que.push(P(0,0));

	

	rep(i,N)visit[i]=0;

	

	while(!que.empty()){

		P u = que.top();

		que.pop();

		

		if(visit[u.pos]==1)continue;

		visit[u.pos] = 1;

		

		//printf("pos = %d  val=%d\n",u.pos, u.val);

		

		if(u.pos==n-1){

			cout<<u.val<<endl;

			break;

		}

		

		rep(i,edge[u.pos].size()){

			que.push(P(edge[u.pos][i].first, u.val+edge[u.pos][i].second));

		}

	}

}



int main(){

	input();

	solve();

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <vector>

#include <queue>

using namespace std;



int N;

vector<int> p;

//bool visited[10010];

//bool is_loop[10010];

bool dijkstra_visited[100100];

//int v[10010];



struct edge {

	int to;

	int cost;

	edge(int t_, int c_) {

		to = t_;

		cost = c_;

	}

};



struct status {

	int amt;

	int v;

	status(int a_, int v_) {

		amt = a_;

		v = v_;

	}

	bool operator<(const status &obj) const {

		return this->amt > obj.amt;

	}

};



vector<vector<edge> > e;



/*

bool loop(int n) {

	if(visited[n])

		return is_loop[n];

	visited[n] = true;

	is_loop[n] = true;

	if(p[n] == 0)

		return is_loop[n] = false;

	return is_loop[n] = loop(n + p[n]);

}

// */



int main() {

	cin >> N;

	p.resize(N);

	for(int i = 0; i < N; i++) {

		cin >> p[i];

	}

	/*

	for(int i = 0; i < N; i++) {

		loop(i);

	}

	// */

	e.resize(N);

	for(int i = 0; i < N; i++) {

		if(p[i] == 0) {

			for(int j = 0; j < 6; j++) {

		//		if(!is_loop[i+j+1]) {

				if(i+j+1 < N) {

					e[i].push_back(edge(i+j+1, 1));

				}

		//		}

			}

		}

		else {

	//		if(!is_loop[i]) {

				e[i].push_back(edge(i+p[i], 0));

	//		}

		}

	}



	priority_queue<status> q;

	q.push(status(0,0));

	int res = 1e9;

	while(!q.empty()) {

		status cur = q.top();

		q.pop();

		if(dijkstra_visited[cur.v])

			continue;

		dijkstra_visited[cur.v] = true;

//		v[cur.v] = cur.amt;

		if(cur.v == N-1) {

			res = cur.amt;

			break;

		}

		for(int i = 0; i < e[cur.v].size(); i++) {

			if(!dijkstra_visited[e[cur.v][i].to]) {

				q.push(status(cur.amt + e[cur.v][i].cost, e[cur.v][i].to));

			}

		}

	}

//	for(int i = 0; i < N; i++)

//		cout << "i:" << i << " " << v[i] << endl;

	cout << res << endl;

}

// Fastest known solution for this problem: