#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const int LOG = 17;
const int N = 100100;
int a[N];
pii sparse[LOG + 1][N];
int n;

void getTL()
{
	int x = 0;
	while(true)
	{
		x++;
	}
	printf("%d\n", x);
}

struct Node
{
	int l, r;
	ll val;
	bool pushOne;
	int add;

	Node () : l(-1), r(-1), val(), pushOne(), add() {}
	Node(int _l, int _r) : l(_l), r(_r), val(0), pushOne(false), add(0) {}
};
const int SZ = 4 * LOG * N;
Node tree[SZ];
int m = 0;
ll ans;
int p[N];
int roots[N];

pii getSparse(int l, int r)
{
	int k = p[r - l];
	return max(sparse[k][l], sparse[k][r - (1 << k)]);
}

void push(int v, int l, int r)
{
	if (v == -1) throw;
	int mid = (l + r) / 2;

	int u = tree[v].l;
	if (u == -1) throw;
	int w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = mid - l;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (mid - l);
	tree[v].l = w;

	u = tree[v].r;
	if (u == -1) throw;
	w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = r - mid;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (r - mid);
	tree[v].r = w;

	tree[v].pushOne = 0;
	tree[v].add = 0;

	return;
}

int update(int v)
{
	if (v == -1 || tree[v].l == -1 || tree[v].r == -1) throw;
//	int u = m++;
	int u = v;
	tree[u] = tree[v];
	tree[u].val = tree[tree[u].l].val + tree[tree[u].r].val;
	return u;
}

int buildTree(int l, int r)
{
	if (l + 1 == r)
	{
		tree[m] = Node();
		if (m + 1 == SZ)
			getTL();
		return m++;
	}
	int mid = (l + r) / 2;
	int v = m++;
	if (m == SZ)
		getTL();
	tree[v] = Node(buildTree(l, mid), buildTree(mid, r));
	return v;
}

int addSegm(int v, int l, int r, int a, int b, ll d)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add += d;
		tree[u].val += d * (r - l);
		return u;
	}
	if (b <= l || r <= a) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = addSegm(tree[u].l, l, mid, a, b, d);
	tree[u].r = addSegm(tree[u].r, mid, r, a, b, d);
	return update(u);
}

int colorOne(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add = 0;
		tree[u].pushOne = 1;
		tree[u].val = (r - l);
		return u;
	}
	if (r <= a || b <= l) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = colorOne(tree[u].l, l, mid, a, b);
	tree[u].r = colorOne(tree[u].r, mid, r, a, b);
	return update(u);
}

ll getSum(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b) return tree[v].val;
	if (b <= l || r <= a) return 0;
	push(v, l, r);
	int mid = (l + r) / 2;
	return getSum(tree[v].l, l, mid, a, b) + getSum(tree[v].r, mid, r, a, b);
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	for (int i = 0; i < n - 1; i++)
	{
		scanf("%d", &a[i]);
		a[i]--;
	}
	a[n - 1] = n;
	for (int i = 0; i < n; i++)
		sparse[0][i] = mp(a[i], i);
	for (int k = 1; k < LOG; k++)
		for (int i = 0; i + (1 << k) <= n; i++)
			sparse[k][i] = max(sparse[k - 1][i], sparse[k - 1][i + (1 << (k - 1))]);
	for (int i = 2; i < N; i++)
		p[i] = p[i / 2] + 1;

	roots[n - 1] = buildTree(0, n);
	for (int i = n - 2; i >= 0; i--)
	{
		int x = getSparse(i + 1, a[i] + 1).second;
		roots[i] = colorOne(addSegm(roots[x], 0, n, x, n, 1), 0, n, i + 1, a[i] + 1);
		ans += getSum(roots[i], 0, n, i + 1, n);
	}
	printf("%lld\n", ans);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const int LOG = 17;
const int N = 1 << LOG;
int a[N];
pii sparse[LOG + 1][N];
int n;

struct Node
{
	int l, r;
	ll val;
	bool pushOne;
	ll add;

	Node () : l(-1), r(-1), val(), pushOne(), add() {}
	Node(int _l, int _r) : l(_l), r(_r), val(0), pushOne(false), add(0) {}
};
const int SZ = 3 * LOG * N;
Node tree[SZ];
int m = 0;
ll ans;
int p[N];
int roots[N];

pii getSparse(int l, int r)
{
	int k = p[r - l];
	return max(sparse[k][l], sparse[k][r - (1 << k)]);
}

void push(int v, int l, int r)
{
	if (v == -1) throw;
	int mid = (l + r) / 2;

	int u = tree[v].l;
	if (u == -1) throw;
	int w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = mid - l;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (mid - l);
	tree[v].l = w;

	u = tree[v].r;
	if (u == -1) throw;
	w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = r - mid;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (r - mid);
	tree[v].r = w;

	tree[v].pushOne = 0;
	tree[v].add = 0;

	return;
}

int update(int v)
{
	if (v == -1 || tree[v].l == -1 || tree[v].r == -1) throw;
//	int u = m++;
	int u = v;
	tree[u] = tree[v];
	tree[u].val = tree[tree[u].l].val + tree[tree[u].r].val;
	return u;
}

int buildTree(int l, int r)
{
	if (l + 1 == r)
	{
		tree[m] = Node();
		if (m + 1 == SZ)
			getTL();
		return m++;
	}
	int mid = (l + r) / 2;
	int v = m++;
	if (m == SZ)
		getTL();
	tree[v] = Node(buildTree(l, mid), buildTree(mid, r));
	return v;
}

int addSegm(int v, int l, int r, int a, int b, ll d)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add += d;
		tree[u].val += d * (r - l);
		return u;
	}
	if (b <= l || r <= a) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = addSegm(tree[u].l, l, mid, a, b, d);
	tree[u].r = addSegm(tree[u].r, mid, r, a, b, d);
	return update(u);
}

int colorOne(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add = 0;
		tree[u].pushOne = 1;
		tree[u].val = (r - l);
		return u;
	}
	if (r <= a || b <= l) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = colorOne(tree[u].l, l, mid, a, b);
	tree[u].r = colorOne(tree[u].r, mid, r, a, b);
	return update(u);
}

ll getSum(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b) return tree[v].val;
	if (b <= l || r <= a) return 0;
	push(v, l, r);
	int mid = (l + r) / 2;
	return getSum(tree[v].l, l, mid, a, b) + getSum(tree[v].r, mid, r, a, b);
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	for (int i = 0; i < n - 1; i++)
	{
		scanf("%d", &a[i]);
		a[i]--;
	}
	a[n - 1] = n;
	for (int i = 0; i < n; i++)
		sparse[0][i] = mp(a[i], i);
	for (int k = 1; k < LOG; k++)
		for (int i = 0; i + (1 << k) <= n; i++)
			sparse[k][i] = max(sparse[k - 1][i], sparse[k - 1][i + (1 << (k - 1))]);
	for (int i = 2; i < N; i++)
		p[i] = p[i / 2] + 1;

	roots[n - 1] = buildTree(0, n);
	for (int i = n - 2; i >= 0; i--)
	{
		int x = getSparse(i + 1, a[i] + 1).second;
		roots[i] = colorOne(addSegm(roots[x], 0, n, x, n, 1), 0, n, i + 1, a[i] + 1);
		ans += getSum(roots[i], 0, n, i + 1, n);
	}
	printf("%lld\n", ans);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const int LOG = 17;
const int N = 1 << LOG;
int a[N];
pii sparse[LOG + 1][N];
int n;

struct Node
{
	int l, r;
	ll val;
	bool pushOne;
	ll add;

	Node () : l(-1), r(-1), val(), pushOne(), add() {}
	Node(int _l, int _r) : l(_l), r(_r), val(0), pushOne(false), add(0) {}
};
Node tree[2 * LOG * N];
int m = 0;
ll ans;
int p[N];
int roots[N];

pii getSparse(int l, int r)
{
	int k = p[r - l];
	return max(sparse[k][l], sparse[k][r - (1 << k)]);
}

void push(int v, int l, int r)
{
	if (v == -1) throw;
	int mid = (l + r) / 2;

	int u = tree[v].l;
	if (u == -1) throw;
	if (tree[v].pushOne)
	{
		tree[u].pushOne = 1;
		tree[u].add = 0;
		tree[u].val = mid - l;
	}
	tree[u].add += tree[v].add;
	tree[u].val += tree[v].add * (mid - l);

	u = tree[v].r;
	if (u == -1) throw;
	if (tree[v].pushOne)
	{
		tree[u].pushOne = 1;
		tree[u].add = 0;
		tree[u].val = r - mid;
	}
	tree[u].add += tree[v].add;
	tree[u].val += tree[v].add * (r - mid);

	tree[v].pushOne = 0;
	tree[v].add = 0;

	return;
}

void update(int v)
{
	if (v == -1 || tree[v].l == -1 || tree[v].r == -1) throw;
	tree[v].val = tree[tree[v].l].val + tree[tree[v].r].val;
	return;
}

int buildTree(int l, int r)
{
	if (l + 1 == r)
	{
		tree[m] = Node();
		return m++;
	}
	int mid = (l + r) / 2;
	int v = m++;
	tree[v] = Node(buildTree(l, mid), buildTree(mid, r));
	return v;
}

int addSegm(int v, int l, int r, int a, int b, ll d)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		tree[u] = tree[v];
		tree[u].add += d;
		tree[u].val += d * (r - l);
		return u;
	}
	if (b <= l || r <= a) return v;
	push(v, l, r);
	int u = m++;
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = addSegm(tree[u].l, l, mid, a, b, d);
	tree[u].r = addSegm(tree[u].r, mid, r, a, b, d);
	update(u);
	return u;
}

int colorOne(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		tree[u] = tree[v];
		tree[u].add = 0;
		tree[u].pushOne = 1;
		tree[u].val = (r - l);
		return u;
	}
	if (r <= a || b <= l) return v;
	push(v, l, r);
	int u = m++;
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = colorOne(tree[u].l, l, mid, a, b);
	tree[u].r = colorOne(tree[u].r, mid, r, a, b);
	update(u);
	return u;
}

ll getSum(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b) return tree[v].val;
	if (b <= l || r <= a) return 0;
	push(v, l, r);
	int mid = (l + r) / 2;
	return getSum(tree[v].l, l, mid, a, b) + getSum(tree[v].r, mid, r, a, b);
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	for (int i = 0; i < n - 1; i++)
	{
		scanf("%d", &a[i]);
		a[i]--;
	}
	a[n - 1] = n;
	for (int i = 0; i < n; i++)
		sparse[0][i] = mp(a[i], i);
	for (int k = 1; k < LOG; k++)
		for (int i = 0; i + (1 << k) <= n; i++)
			sparse[k][i] = max(sparse[k - 1][i], sparse[k - 1][i + (1 << (k - 1))]);
	for (int i = 2; i < N; i++)
		p[i] = p[i / 2] + 1;

	roots[n - 1] = buildTree(0, n);
	for (int i = n - 2; i >= 0; i--)
	{
		int x = getSparse(i + 1, a[i] + 1).second;
		roots[i] = colorOne(addSegm(roots[x], 0, n, x, n, 1), 0, n, i + 1, a[i] + 1);
		ans += getSum(roots[i], 0, n, i + 1, n);
	}
	printf("%lld\n", ans);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const int LOG = 17;
const int N = 100100;
int a[N];
pii sparse[LOG + 1][N];
int n;

void getTL()
{
	int x = 0;
	while(true)
	{
		x++;
	}
	printf("%d\n", x);
}

struct Node
{
	int l, r;
	ll val;
	bool pushOne;
	int add;

	Node () : l(-1), r(-1), val(), pushOne(), add() {}
	Node(int _l, int _r) : l(_l), r(_r), val(0), pushOne(false), add(0) {}
};
const int SZ = 6 * LOG * N;
Node tree[SZ];
int m = 0;
ll ans;
int p[N];
int roots[N];

pii getSparse(int l, int r)
{
	int k = p[r - l];
	return max(sparse[k][l], sparse[k][r - (1 << k)]);
}

void push(int v, int l, int r)
{
	if (v == -1) throw;
	int mid = (l + r) / 2;

	int u = tree[v].l;
	if (u == -1) throw;
	int w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = mid - l;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (mid - l);
	tree[v].l = w;

	u = tree[v].r;
	if (u == -1) throw;
	w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = r - mid;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (r - mid);
	tree[v].r = w;

	tree[v].pushOne = 0;
	tree[v].add = 0;

	return;
}

int update(int v)
{
	if (v == -1 || tree[v].l == -1 || tree[v].r == -1) throw;
//	int u = m++;
	int u = v;
	tree[u] = tree[v];
	tree[u].val = tree[tree[u].l].val + tree[tree[u].r].val;
	return u;
}

int buildTree(int l, int r)
{
	if (l + 1 == r)
	{
		tree[m] = Node();
		if (m + 1 == SZ)
			getTL();
		return m++;
	}
	int mid = (l + r) / 2;
	int v = m++;
	if (m == SZ)
		getTL();
	tree[v] = Node(buildTree(l, mid), buildTree(mid, r));
	return v;
}

int addSegm(int v, int l, int r, int a, int b, ll d)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add += d;
		tree[u].val += d * (r - l);
		return u;
	}
	if (b <= l || r <= a) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = addSegm(tree[u].l, l, mid, a, b, d);
	tree[u].r = addSegm(tree[u].r, mid, r, a, b, d);
	return update(u);
}

int colorOne(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add = 0;
		tree[u].pushOne = 1;
		tree[u].val = (r - l);
		return u;
	}
	if (r <= a || b <= l) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = colorOne(tree[u].l, l, mid, a, b);
	tree[u].r = colorOne(tree[u].r, mid, r, a, b);
	return update(u);
}

ll getSum(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b) return tree[v].val;
	if (b <= l || r <= a) return 0;
	push(v, l, r);
	int mid = (l + r) / 2;
	return getSum(tree[v].l, l, mid, a, b) + getSum(tree[v].r, mid, r, a, b);
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	for (int i = 0; i < n - 1; i++)
	{
		scanf("%d", &a[i]);
		a[i]--;
	}
	a[n - 1] = n;
	for (int i = 0; i < n; i++)
		sparse[0][i] = mp(a[i], i);
	for (int k = 1; k < LOG; k++)
		for (int i = 0; i + (1 << k) <= n; i++)
			sparse[k][i] = max(sparse[k - 1][i], sparse[k - 1][i + (1 << (k - 1))]);
	for (int i = 2; i < N; i++)
		p[i] = p[i / 2] + 1;

	roots[n - 1] = buildTree(0, n);
	for (int i = n - 2; i >= 0; i--)
	{
		int x = getSparse(i + 1, a[i] + 1).second;
		roots[i] = colorOne(addSegm(roots[x], 0, n, 0, n, 1), 0, n, 0, a[i] + 1);
		ans += getSum(roots[i], 0, n, i + 1, n);
	}
	printf("%lld\n", ans);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const int LOG = 17;
const int N = 1 << LOG;
int a[N];
pii sparse[LOG + 1][N];
int n;

struct Node
{
	int l, r;
	ll val;
	bool pushOne;
	ll add;

	Node () : l(-1), r(-1), val(), pushOne(), add() {}
	Node(int _l, int _r) : l(_l), r(_r), val(0), pushOne(false), add(0) {}
};
Node tree[2 * LOG * N];
int m = 0;
ll ans;
int p[N];
int roots[N];

pii getSparse(int l, int r)
{
	int k = p[r - l];
	return max(sparse[k][l], sparse[k][r - (1 << k)]);
}

void push(int v, int l, int r)
{
	if (v == -1) throw;
	int mid = (l + r) / 2;

	int u = tree[v].l;
	if (u == -1) throw;
	int w = m++;
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = mid - l;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (mid - l);
	tree[v].l = w;

	u = tree[v].r;
	if (u == -1) throw;
	w = m++;
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = r - mid;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (r - mid);
	tree[v].r = w;

	tree[v].pushOne = 0;
	tree[v].add = 0;

	return;
}

int update(int v)
{
	if (v == -1 || tree[v].l == -1 || tree[v].r == -1) throw;
//	int u = m++;
	int u = v;
	tree[u] = tree[v];
	tree[u].val = tree[tree[u].l].val + tree[tree[u].r].val;
	return u;
}

int buildTree(int l, int r)
{
	if (l + 1 == r)
	{
		tree[m] = Node();
		return m++;
	}
	int mid = (l + r) / 2;
	int v = m++;
	tree[v] = Node(buildTree(l, mid), buildTree(mid, r));
	return v;
}

int addSegm(int v, int l, int r, int a, int b, ll d)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		tree[u] = tree[v];
		tree[u].add += d;
		tree[u].val += d * (r - l);
		return u;
	}
	if (b <= l || r <= a) return v;
	push(v, l, r);
	int u = m++;
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = addSegm(tree[u].l, l, mid, a, b, d);
	tree[u].r = addSegm(tree[u].r, mid, r, a, b, d);
	return update(u);
}

int colorOne(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		tree[u] = tree[v];
		tree[u].add = 0;
		tree[u].pushOne = 1;
		tree[u].val = (r - l);
		return u;
	}
	if (r <= a || b <= l) return v;
	push(v, l, r);
	int u = m++;
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = colorOne(tree[u].l, l, mid, a, b);
	tree[u].r = colorOne(tree[u].r, mid, r, a, b);
	return update(u);
}

ll getSum(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b) return tree[v].val;
	if (b <= l || r <= a) return 0;
	push(v, l, r);
	int mid = (l + r) / 2;
	return getSum(tree[v].l, l, mid, a, b) + getSum(tree[v].r, mid, r, a, b);
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	for (int i = 0; i < n - 1; i++)
	{
		scanf("%d", &a[i]);
		a[i]--;
	}
	a[n - 1] = n;
	for (int i = 0; i < n; i++)
		sparse[0][i] = mp(a[i], i);
	for (int k = 1; k < LOG; k++)
		for (int i = 0; i + (1 << k) <= n; i++)
			sparse[k][i] = max(sparse[k - 1][i], sparse[k - 1][i + (1 << (k - 1))]);
	for (int i = 2; i < N; i++)
		p[i] = p[i / 2] + 1;

	roots[n - 1] = buildTree(0, n);
	for (int i = n - 2; i >= 0; i--)
	{
		int x = getSparse(i + 1, a[i] + 1).second;
		roots[i] = colorOne(addSegm(roots[x], 0, n, x, n, 1), 0, n, i + 1, a[i] + 1);
		ans += getSum(roots[i], 0, n, i + 1, n);
	}
	printf("%lld\n", ans);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const int LOG = 17;
const int N = 1 << LOG;
int a[N];
pii sparse[LOG + 1][N];
int n;

void getTL()
{
	int x = 0;
	while(true)
	{
		x++;
	}
	printf("%d\n", x);
}

struct Node
{
	int l, r;
	ll val;
	bool pushOne;
	ll add;

	Node () : l(-1), r(-1), val(), pushOne(), add() {}
	Node(int _l, int _r) : l(_l), r(_r), val(0), pushOne(false), add(0) {}
};
const int SZ = 3 * LOG * N;
Node tree[SZ];
int m = 0;
ll ans;
int p[N];
int roots[N];

pii getSparse(int l, int r)
{
	int k = p[r - l];
	return max(sparse[k][l], sparse[k][r - (1 << k)]);
}

void push(int v, int l, int r)
{
	if (v == -1) throw;
	int mid = (l + r) / 2;

	int u = tree[v].l;
	if (u == -1) throw;
	int w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = mid - l;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (mid - l);
	tree[v].l = w;

	u = tree[v].r;
	if (u == -1) throw;
	w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = r - mid;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (r - mid);
	tree[v].r = w;

	tree[v].pushOne = 0;
	tree[v].add = 0;

	return;
}

int update(int v)
{
	if (v == -1 || tree[v].l == -1 || tree[v].r == -1) throw;
//	int u = m++;
	int u = v;
	tree[u] = tree[v];
	tree[u].val = tree[tree[u].l].val + tree[tree[u].r].val;
	return u;
}

int buildTree(int l, int r)
{
	if (l + 1 == r)
	{
		tree[m] = Node();
		if (m + 1 == SZ)
			getTL();
		return m++;
	}
	int mid = (l + r) / 2;
	int v = m++;
	if (m == SZ)
		getTL();
	tree[v] = Node(buildTree(l, mid), buildTree(mid, r));
	return v;
}

int addSegm(int v, int l, int r, int a, int b, ll d)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add += d;
		tree[u].val += d * (r - l);
		return u;
	}
	if (b <= l || r <= a) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = addSegm(tree[u].l, l, mid, a, b, d);
	tree[u].r = addSegm(tree[u].r, mid, r, a, b, d);
	return update(u);
}

int colorOne(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add = 0;
		tree[u].pushOne = 1;
		tree[u].val = (r - l);
		return u;
	}
	if (r <= a || b <= l) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = colorOne(tree[u].l, l, mid, a, b);
	tree[u].r = colorOne(tree[u].r, mid, r, a, b);
	return update(u);
}

ll getSum(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b) return tree[v].val;
	if (b <= l || r <= a) return 0;
	push(v, l, r);
	int mid = (l + r) / 2;
	return getSum(tree[v].l, l, mid, a, b) + getSum(tree[v].r, mid, r, a, b);
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	for (int i = 0; i < n - 1; i++)
	{
		scanf("%d", &a[i]);
		a[i]--;
	}
	a[n - 1] = n;
	for (int i = 0; i < n; i++)
		sparse[0][i] = mp(a[i], i);
	for (int k = 1; k < LOG; k++)
		for (int i = 0; i + (1 << k) <= n; i++)
			sparse[k][i] = max(sparse[k - 1][i], sparse[k - 1][i + (1 << (k - 1))]);
	for (int i = 2; i < N; i++)
		p[i] = p[i / 2] + 1;

	roots[n - 1] = buildTree(0, n);
	for (int i = n - 2; i >= 0; i--)
	{
		int x = getSparse(i + 1, a[i] + 1).second;
		roots[i] = colorOne(addSegm(roots[x], 0, n, x, n, 1), 0, n, i + 1, a[i] + 1);
		ans += getSum(roots[i], 0, n, i + 1, n);
	}
	printf("%lld\n", ans);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const int LOG = 17;
const int N = 100100;
int a[N];
pii sparse[LOG + 1][N];
int n;

void getTL()
{
	int x = 0;
	while(true)
	{
		x++;
	}
	printf("%d\n", x);
}

struct Node
{
	int l, r;
	ll val;
	bool pushOne;
	int add;

	Node () : l(-1), r(-1), val(), pushOne(), add() {}
	Node(int _l, int _r) : l(_l), r(_r), val(0), pushOne(false), add(0) {}
};
const int SZ = 6 * LOG * N;
Node tree[SZ];
int m = 0;
ll ans;
int p[N];
int roots[N];

pii getSparse(int l, int r)
{
	int k = p[r - l];
	return max(sparse[k][l], sparse[k][r - (1 << k)]);
}

void push(int v, int l, int r)
{
	if (v == -1) throw;
	int mid = (l + r) / 2;

	int u = tree[v].l;
	if (u == -1) throw;
	int w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = mid - l;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (mid - l);
	tree[v].l = w;

	u = tree[v].r;
	if (u == -1) throw;
	w = m++;
	if (m == SZ)
		getTL();
	tree[w] = tree[u];
	if (tree[v].pushOne)
	{
		tree[w].pushOne = 1;
		tree[w].add = 0;
		tree[w].val = r - mid;
	}
	tree[w].add += tree[v].add;
	tree[w].val += tree[v].add * (r - mid);
	tree[v].r = w;

	tree[v].pushOne = 0;
	tree[v].add = 0;

	return;
}

int update(int v)
{
	if (v == -1 || tree[v].l == -1 || tree[v].r == -1) throw;
//	int u = m++;
	int u = v;
	tree[u] = tree[v];
	tree[u].val = tree[tree[u].l].val + tree[tree[u].r].val;
	return u;
}

int buildTree(int l, int r)
{
	if (l + 1 == r)
	{
		tree[m] = Node();
		if (m + 1 == SZ)
			getTL();
		return m++;
	}
	int mid = (l + r) / 2;
	int v = m++;
	if (m == SZ)
		getTL();
	tree[v] = Node(buildTree(l, mid), buildTree(mid, r));
	return v;
}

int addSegm(int v, int l, int r, int a, int b, ll d)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add += d;
		tree[u].val += d * (r - l);
		return u;
	}
	if (b <= l || r <= a) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = addSegm(tree[u].l, l, mid, a, b, d);
	tree[u].r = addSegm(tree[u].r, mid, r, a, b, d);
	return update(u);
}

int colorOne(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b)
	{
		int u = m++;
		if (m == SZ)
			getTL();
		tree[u] = tree[v];
		tree[u].add = 0;
		tree[u].pushOne = 1;
		tree[u].val = (r - l);
		return u;
	}
	if (r <= a || b <= l) return v;
	push(v, l, r);
	int u = m++;
	if (m == SZ)
		getTL();
	tree[u] = tree[v];
	int mid = (l + r) / 2;
	tree[u].l = colorOne(tree[u].l, l, mid, a, b);
	tree[u].r = colorOne(tree[u].r, mid, r, a, b);
	return update(u);
}

ll getSum(int v, int l, int r, int a, int b)
{
	if (a <= l && r <= b) return tree[v].val;
	if (b <= l || r <= a) return 0;
	push(v, l, r);
	int mid = (l + r) / 2;
	return getSum(tree[v].l, l, mid, a, b) + getSum(tree[v].r, mid, r, a, b);
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	for (int i = 0; i < n - 1; i++)
	{
		scanf("%d", &a[i]);
		a[i]--;
	}
	a[n - 1] = n;
	for (int i = 0; i < n; i++)
		sparse[0][i] = mp(a[i], i);
	for (int k = 1; k < LOG; k++)
		for (int i = 0; i + (1 << k) <= n; i++)
			sparse[k][i] = max(sparse[k - 1][i], sparse[k - 1][i + (1 << (k - 1))]);
	for (int i = 2; i < N; i++)
		p[i] = p[i / 2] + 1;

	roots[n - 1] = buildTree(0, n);
	for (int i = n - 2; i >= 0; i--)
	{
		int x = getSparse(i + 1, a[i] + 1).second;
		roots[i] = colorOne(addSegm(roots[x], 0, n, x, n, 1), 0, n, i + 1, a[i] + 1);
		ans += getSum(roots[i], 0, n, i + 1, n);
	}
	printf("%lld\n", ans);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
#define sz(c) (int)(c).size()
#define ALL(c) (c).begin(), (c).end()

const int inf = (int)1e9;

struct tree
{
    typedef pair<int, int> T;
    vector<T> val;
    int tsz;

    tree (const vector<T> &start)
    {
        tsz = 1;
        while (tsz <= sz(start))
            tsz *= 2;

        val.resize(2 * tsz);
        for (int i = tsz; i < tsz + sz(start); i++)
            val[i] = start[i - tsz];
        for (int i = tsz - 1; i > 0; i--)
            val[i] = max(val[2 * i], val[2 * i + 1]);
    }

    T getmax (int l, int r)
    {
        T ans(0, 0);
        for (l += tsz, r += tsz; l < r; l >>= 1, r >>= 1)
        {
            if (l & 1)  ans = max(ans, val[l++]);
            if (r & 1)  ans = max(ans, val[--r]);
        }
        return ans;
    }
};

void solve (int n)
{
    vi a(n + 1);
    for (int i = 1; i < n; i++)
        cin >> a[i];
    a[n] = inf - 1;

    vector<ll> dp(n + 1);
    ll ans = 0;

    vector<pair<int, int>> va;
    for (int i = 0; i < sz(a); i++)
        va.pb(mp(a[i], i));
    tree data(va);

    for (int i = n - 1; i > 0; i--)
    {
        pair<int, int> cur = data.getmax(i + 1, a[i] + 1);
        if (cur.first == a[a[i]])
            dp[i] = n - i + dp[a[i]];
        else
        {
            dp[i] = (a[i] - i) + (a[cur.second] - a[i])*2 + dp[a[cur.second]];
       //    cerr << "here " << i << ' ' << dp[i] << endl;;
        }

        ans += dp[i];
    }

    cout << ans << endl;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("output.txt", "w", stdout);
    freopen("input.txt", "rt", stdin);
    #endif // ONLINE_JUDGE

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    while (cin >> n)
        solve(n);
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
#define sz(c) (int)(c).size()
#define ALL(c) (c).begin(), (c).end()

const int inf = (int)1e9;

struct tree
{
    typedef pair<int, int> T;
    vector<T> val;
    int tsz;

    tree (const vector<T> &start)
    {
        tsz = 1;
        while (tsz <= sz(start))
            tsz *= 2;

        val.resize(2 * tsz);
        for (int i = tsz; i < tsz + sz(start); i++)
            val[i] = start[i - tsz];
        for (int i = tsz - 1; i > 0; i--)
            val[i] = max(val[2 * i], val[2 * i + 1]);
    }

    T getmax (int l, int r)
    {
        T ans(0, 0);
        for (l += tsz, r += tsz; l < r; l >>= 1, r >>= 1)
        {
            if (l & 1)  ans = max(ans, val[l++]);
            if (r & 1)  ans = max(ans, val[--r]);
        }
        return ans;
    }
};

void solve (int n)
{
    vi a(n + 1);
    for (int i = 1; i < n; i++)
        cin >> a[i];
    a[n] = inf - 1;

    ll ans = 0;

    vector<pair<int, int>> va;
    for (int i = 0; i < sz(a); i++)
        va.pb(mp(a[i], i));
    tree data(va);

    map<pair<int, int>, ll> dp;

    function<ll(int, int)> get_dp = [&] (int l, int r) -> ll
    {
        if (r >= n)
            return 0;

        auto it = dp.find(mp(l, r));
        if (it != dp.end())
            return it -> second;

        pair<int, int> cur = data.getmax(l, r + 1);
        if (cur.first == a[n])
            return n - r;

        ll anst = get_dp(r + 1, a[cur.second]) + n - r;
        dp[mp(l, r)] = anst;
        return anst;
    };

    for (int i = n - 1; i > 0; i--)
    {
        ll cur = get_dp(i + 1, a[i]) + n - i;
        ans += cur;
   //     cerr << cur << '\n';
    }
   // cerr << endl;

    cout << ans << endl;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("output.txt", "w", stdout);
    freopen("input.txt", "rt", stdin);
    #endif // ONLINE_JUDGE

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    while (cin >> n)
        solve(n);
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
#define sz(c) (int)(c).size()
#define ALL(c) (c).begin(), (c).end()

const int inf = (int)1e9;

struct tree
{
    typedef pair<int, int> T;
    vector<T> val;
    int tsz;

    tree (const vector<T> &start)
    {
        tsz = 1;
        while (tsz <= sz(start))
            tsz *= 2;

        val.resize(2 * tsz);
        for (int i = tsz; i < tsz + sz(start); i++)
            val[i] = start[i - tsz];
        for (int i = tsz - 1; i > 0; i--)
            val[i] = max(val[2 * i], val[2 * i + 1]);
    }

    T getmax (int l, int r)
    {
        T ans(0, 0);
        for (l += tsz, r += tsz; l < r; l >>= 1, r >>= 1)
        {
            if (l & 1)  ans = max(ans, val[l++]);
            if (r & 1)  ans = max(ans, val[--r]);
        }
        return ans;
    }
};

void solve (int n)
{
    vi a(n + 1);
    for (int i = 1; i < n; i++)
        cin >> a[i];
    a[n] = inf - 1;

    ll ans = 0;

    vector<pair<int, int>> va;
    for (int i = 0; i < sz(a); i++)
        va.pb(mp(a[i], i));
    tree data(va);

    map<pair<int, int>, ll> dp;

    function<ll(int, int)> get_dp = [&] (int l, int r) -> ll
    {
        if (r >= n)
            return 0;

        auto it = dp.find(mp(l, r));
        if (it != dp.end())
            return it -> second;

        pair<int, int> cur = data.getmax(l, r + 1);
        if (cur.first == a[n])
            return n - r;

        return get_dp(l + 1, a[cur.second]) + n - r;
    };

    for (int i = n - 1; i > 0; i--)
    {
        ll cur = get_dp(i + 1, a[i]) + n - i;
        ans += cur;
   //     cerr << cur << '\n';
    }
   // cerr << endl;

    cout << ans << endl;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("output.txt", "w", stdout);
    freopen("input.txt", "rt", stdin);
    #endif // ONLINE_JUDGE

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    while (cin >> n)
        solve(n);
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
#define sz(c) (int)(c).size()
#define ALL(c) (c).begin(), (c).end()

void solve (int n)
{
    vi a(n + 1);
    for (int i = 1; i < n; i++)
        cin >> a[i];

    vector<ll> dp(n + 1);
    ll ans = 0;
    for (int i = n - 1; i > 0; i--)
    {
        dp[i] = n - i + dp[a[i]];
        ans += dp[i];
    }

    cout << ans << endl;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("output.txt", "w", stdout);
    freopen("input.txt", "rt", stdin);
    #endif // ONLINE_JUDGE

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    while (cin >> n)
        solve(n);
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
#define sz(c) (int)(c).size()
#define ALL(c) (c).begin(), (c).end()

const int inf = (int)1e9;

struct tree
{
    typedef pair<int, int> T;
    vector<T> val;
    int tsz;

    tree (const vector<T> &start)
    {
        tsz = 1;
        while (tsz <= sz(start))
            tsz *= 2;

        val.resize(2 * tsz);
        for (int i = tsz; i < tsz + sz(start); i++)
            val[i] = start[i - tsz];
        for (int i = tsz - 1; i > 0; i--)
            val[i] = max(val[2 * i], val[2 * i + 1]);
    }

    T getmax (int l, int r)
    {
        T ans(0, 0);
        for (l += tsz, r += tsz; l < r; l >>= 1, r >>= 1)
        {
            if (l & 1)  ans = max(ans, val[l++]);
            if (r & 1)  ans = max(ans, val[--r]);
        }
        return ans;
    }
};

void solve (int n)
{
    vi a(n + 1);
    for (int i = 1; i < n; i++)
        cin >> a[i];
    a[n] = inf - 1;

    ll ans = 0;

    vector<pair<int, int>> va;
    for (int i = 0; i < sz(a); i++)
        va.pb(mp(a[i], i));
    tree data(va);

    map<pair<int, int>, ll> dp;

    function<ll(int, int)> get_dp = [&] (int l, int r) -> ll
    {
        if (r >= n)
            return 0;

        auto it = dp.find(mp(l, r));
        if (it != dp.end())
            return it -> second;

        pair<int, int> cur = data.getmax(l, r + 1);
        if (cur.first == a[n])
            return n - r;

        return get_dp(r + 1, a[cur.second]) + n - r;
    };

    for (int i = n - 1; i > 0; i--)
    {
        ll cur = get_dp(i + 1, a[i]) + n - i;
        ans += cur;
   //     cerr << cur << '\n';
    }
   // cerr << endl;

    cout << ans << endl;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("output.txt", "w", stdout);
    freopen("input.txt", "rt", stdin);
    #endif // ONLINE_JUDGE

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    while (cin >> n)
        solve(n);
}


#include    <bits/stdc++.h>

#define     M_PI            3.14159265358979323846
#define     mod             1000000007
#define     inf             1000000000000000000
#define     mp              make_pair
#define     pb              push_back
#define     F               first
#define     S               second
#define     ll              long long
#define     pii             pair<int,int>
#define     pli             pair<ll,int>
#define     pil             pair<int,ll>
#define     pll             pair<ll,ll>
#define     si(t)           scanf("%d",&t)
#define     sii(m,n)        scanf("%d %d",&m,&n);
#define     sl(t)           scanf("%lld",&t)
#define     rep(i,n)        for(int i=0;i<n;i++)
#define     REP(i,a,b)      for(int i=a;i<=b;i++)
#define     RREP(i,a,b)     for(int i=a;i>=b;i--)
#define     N               500005

using namespace std;

int arr[N],tree[1<<17],dp[N],n;

void merge(int& c, int a, int b){
    if(dp[a] < dp[b]) c = a;
    else c = b;
}

void update(int c,int a,int b,int x,int v){
    if(a>b || a>x || b<x) return;
    if(a==b&&a==x){tree[c] = v; return ;}
    int cc=2*c,m=(a+b)>>1;
    update(cc,a,m,x,v);
    update(cc+1,m+1,b,x,v);
    merge(tree[c],tree[cc],tree[cc+1]);
}

int query(int c,int a,int b,int x,int y){
    if(a>b || a>y || b < x) return n;
    if(a>=x && b<=y) return tree[c];
    int cc=2*c,m=(a+b)>>1;
    int i = query(cc,a,m,x,y);
    int j = query(cc+1,m+1,b,x,y);
    int ans;
    merge(ans,i,j);
    return ans;
}

int main(){
    ll ans=0;
    si(n);
    dp[n] = mod;
    rep(i,n-1) si(arr[i]),arr[i]--;
    RREP(i,n-2,0){
        if(arr[i] == n-1) dp[i] = n-i-1;
        else{
            int k = query(1,0,n-1,i+1,arr[i]);
            dp[i] = (dp[k] - arr[i] + k + n-i-1);
        }
        update(1,0,n-1,i,i);
    }
    rep(i,n) ans += dp[i];
    printf("%lld\n",ans );
    return 0;
}


#include    <bits/stdc++.h>

#define     M_PI            3.14159265358979323846
#define     mod             1000000007
#define     inf             1000000000000000000
#define     mp              make_pair
#define     pb              push_back
#define     F               first
#define     S               second
#define     ll              long long
#define     pii             pair<int,int>
#define     pli             pair<ll,int>
#define     pil             pair<int,ll>
#define     pll             pair<ll,ll>
#define     si(t)           scanf("%d",&t)
#define     sii(m,n)        scanf("%d %d",&m,&n);
#define     sl(t)           scanf("%lld",&t)
#define     rep(i,n)        for(int i=0;i<n;i++)
#define     REP(i,a,b)      for(int i=a;i<=b;i++)
#define     RREP(i,a,b)     for(int i=a;i>=b;i--)
#define     N               500005

using namespace std;

int arr[N],tree[1<<17],dp[N],n;

void merge(int& c, int a, int b){
    if(arr[a] > arr[b]) c = a;
    else c = b;
}

void build(int c,int a,int b){
    if(a>b) return ;
    if(a == b){
        tree[c] = a;
        return ;
    }
    int cc=2*c,m=(a+b)>>1;
    build(cc,a,m);
    build(cc+1,m+1,b);
    merge(tree[c],tree[cc],tree[cc+1]);
}

int query(int c,int a,int b,int x,int y){
    if(a>b || a>y || b < x) return n;
    if(a>=x && b<=y) return tree[c];
    int cc=2*c,m=(a+b)>>1;
    int i = query(cc,a,m,x,y);
    int j = query(cc+1,m+1,b,x,y);
    int ans;
    merge(ans,i,j);
    return ans;
}

int main(){
    ll ans=0;
    si(n);
    rep(i,n-1) si(arr[i]),arr[i]--;
    arr[n-1] = n-1;
    build(1,0,n-1);
    RREP(i,n-2,0){
            int k = query(1,0,n-1,i+1,arr[i]);
            //cout << k << endl;
            dp[i] = (dp[k] - arr[i] + k + n-i-1);
    }
    rep(i,n) ans += dp[i];
    //rep(i,n) cout << dp[i] << " ";
    printf("%lld\n",ans );
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef pair<ii, int> iii;
typedef vector<ii> vii;
typedef set<int> si;
typedef map<int, int> mii;
typedef map<string, int> msi;
typedef pair<ll, ll> pll;

#define FOR(i, a, b) \
for (int i = int(a); i <= int(b); i++) // a to b, and variable i is local!
#define FORD(i, a, b) \
for (int i = int(a); i >= int(b); i--) // a to b, and variable i is local!
#define TRvi(c, it) \
for (vi::iterator it = (c).begin(); it != (c).end(); it++)
#define TRvii(c, it) \
for (vii::iterator it = (c).begin(); it != (c).end(); it++)
#define TRmsi(c, it) \
for (msi::iterator it = (c).begin(); it != (c).end(); it++)
#define TRmii(c, it) \
for (mii::iterator it = (c).begin(); it != (c).end(); it++)
#define INF 2000000000
#define MEMSET_INF 127
#define MEMSET_HALF_INF 63
#define zero(arr) memset((arr), 0, sizeof (arr))
#define init(arr) memset((arr), -1, sizeof (arr))
#define ff first
#define ss second
#define pb push_back
#define LSOne(S) (S & (-S))

//memset(dist, MEMSET_INF, sizeof dist);
//memset(dp_memo, -1, sizeof dp_memo);
//memset(arr, 0, sizeof arr);

#define SIZE 100005
#define MAX 1<<18

int a[SIZE];
ll dp[SIZE];
ii tree[2*MAX];

void build(ll p, ll l, ll r) {
	if(l==r)
		tree[p] = {a[l], l};
	else {
		build( (p<<1), l, (l+r)/2 );
		build( (p<<1) + 1, (l+r)/2 + 1, r );
		ii p1 = tree[(p<<1)];
		ii p2 = tree[(p<<1)+1];
		tree[p] = max(p1, p2);
	}
}

pll rmq(ll p, ll l, ll r, ll i, ll j) {
	if(i > r || j < l)
		return {-1, -1};
	if(i<=l && r<=j)
		return tree[p];

	pll p1 = rmq( (p<<1) , l, (l+r) / 2, i, j);
    pll p2 = rmq( (p<<1) + 1, (l+r) / 2 + 1, r, i, j);

    if (p1.ff == -1) return p2;
    if (p2.ff == -1) return p1;

	pll p3 = max(p1, p2);

    return p3;
}

int main()
{
	ll n;

	cin>>n;

	FOR(i, 0, n-2) {
		cin>>a[i];
		a[i]--;
	}

	a[n-1] = n-1;

	dp[n-1] = 0;

	build(1, 0, n-1);

	ll ans = 0;

	FORD(i, n-2, 0) {
		pll tmp = rmq(1, 0, n-1, i + 1, a[i]);
		ll m = tmp.ss;
		dp[i] = dp[m] - (a[i] - m) + n - 1 - i;
		ans += dp[i];
	}

	cout<<ans<<endl;
	return 0;
}


#include    <bits/stdc++.h>

#define     M_PI            3.14159265358979323846
#define     mod             1000000007
#define     inf             1000000000000000000
#define     mp              make_pair
#define     pb              push_back
#define     F               first
#define     S               second
#define     ll              long long
#define     pii             pair<int,int>
#define     pli             pair<ll,int>
#define     pil             pair<int,ll>
#define     pll             pair<ll,ll>
#define     si(t)           scanf("%d",&t)
#define     sii(m,n)        scanf("%d %d",&m,&n);
#define     sl(t)           scanf("%lld",&t)
#define     rep(i,n)        for(int i=0;i<n;i++)
#define     REP(i,a,b)      for(int i=a;i<=b;i++)
#define     RREP(i,a,b)     for(int i=a;i>=b;i--)
#define     N               500005

using namespace std;

int arr[N],tree[1<<17],dp[N],n;

void merge(int& c, int a, int b){
    if(dp[a] <= dp[b]) c = a;
    else c = b;
}

void update(int c,int a,int b,int x,int v){
    if(a>b || a>x || b<x) return;
    if(a==b&&a==x){tree[c] = v; return ;}
    int cc=2*c,m=(a+b)>>1;
    update(cc,a,m,x,v);
    update(cc+1,m+1,b,x,v);
    merge(tree[c],tree[cc],tree[cc+1]);
}

int query(int c,int a,int b,int x,int y){
    if(a>b || a>y || b < x) return n;
    if(a>=x && b<=y) return tree[c];
    int cc=2*c,m=(a+b)>>1;
    int i = query(cc,a,m,x,y);
    int j = query(cc+1,m+1,b,x,y);
    int ans;
    merge(ans,i,j);
    return ans;
}

int main(){
    ll ans=0;
    si(n);
    dp[n] = mod;
    rep(i,n-1) si(arr[i]),arr[i]--;
    update(1,0,n-1,n-1,n-1);
    RREP(i,n-2,0){

            int k = query(1,0,n-1,i+1,arr[i]);
            dp[i] = (dp[k] - arr[i] + k + n-i-1);

        update(1,0,n-1,i,i);
    }
    rep(i,n) ans += dp[i];
    printf("%lld\n",ans );
    return 0;
}


#include    <bits/stdc++.h>

#define     M_PI            3.14159265358979323846
#define     mod             1000000007
#define     inf             1000000000000000000
#define     mp              make_pair
#define     pb              push_back
#define     F               first
#define     S               second
#define     ll              long long
#define     pii             pair<int,int>
#define     pli             pair<ll,int>
#define     pil             pair<int,ll>
#define     pll             pair<ll,ll>
#define     si(t)           scanf("%d",&t)
#define     sii(m,n)        scanf("%d %d",&m,&n);
#define     sl(t)           scanf("%lld",&t)
#define     rep(i,n)        for(int i=0;i<n;i++)
#define     REP(i,a,b)      for(int i=a;i<=b;i++)
#define     RREP(i,a,b)     for(int i=a;i>=b;i--)
#define     N               500005

using namespace std;

int arr[N],tree[1<<17],n;
ll dp[N];

void merge(int& c, int a, int b){
    if(arr[a] > arr[b]) c = a;
    else c = b;
}

void build(int c,int a,int b){
    if(a>b) return ;
    if(a == b){
        tree[c] = a;
        return ;
    }
    int cc=2*c,m=(a+b)>>1;
    build(cc,a,m);
    build(cc+1,m+1,b);
    merge(tree[c],tree[cc],tree[cc+1]);
}

int query(int c,int a,int b,int x,int y){
    if(a>b || a>y || b < x) return n;
    if(a>=x && b<=y) return tree[c];
    int cc=2*c,m=(a+b)>>1;
    int i = query(cc,a,m,x,y);
    int j = query(cc+1,m+1,b,x,y);
    int ans;
    merge(ans,i,j);
    return ans;
}

int main(){
    ll ans=0;
    si(n);
    rep(i,n-1) si(arr[i]),arr[i]--;
    arr[n-1] = n-1;
    build(1,0,n-1);
    RREP(i,n-2,0){
            int k = query(1,0,n-1,i+1,arr[i]);
            //cout << k << endl;
            dp[i] = (dp[k] - arr[i] + k + n-i-1);
    }
    rep(i,n) ans += dp[i];
    //rep(i,n) cout << dp[i] << " ";
    printf("%lld\n",ans );
    return 0;
}


#include    <bits/stdc++.h>

#define     M_PI            3.14159265358979323846
#define     mod             1000000007
#define     inf             1000000000000000000
#define     mp              make_pair
#define     pb              push_back
#define     F               first
#define     S               second
#define     ll              long long
#define     pii             pair<int,int>
#define     pli             pair<ll,int>
#define     pil             pair<int,ll>
#define     pll             pair<ll,ll>
#define     si(t)           scanf("%d",&t)
#define     sii(m,n)        scanf("%d %d",&m,&n);
#define     sl(t)           scanf("%lld",&t)
#define     rep(i,n)        for(int i=0;i<n;i++)
#define     REP(i,a,b)      for(int i=a;i<=b;i++)
#define     RREP(i,a,b)     for(int i=a;i>=b;i--)
#define     N               500005

using namespace std;

int arr[N],tree[1<<17],dp[N],n;

void merge(int& c, int a, int b){
    if(dp[a] <= dp[b]) c = a;
    else c = b;
}

void update(int c,int a,int b,int x,int v){
    if(a>b || a>x || b<x) return;
    if(a==b&&a==x){tree[c] = v; return ;}
    int cc=2*c,m=(a+b)>>1;
    update(cc,a,m,x,v);
    update(cc+1,m+1,b,x,v);
    merge(tree[c],tree[cc],tree[cc+1]);
}

int query(int c,int a,int b,int x,int y){
    if(a>b || a>y || b < x) return n;
    if(a>=x && b<=y) return tree[c];
    int cc=2*c,m=(a+b)>>1;
    int i = query(cc,a,m,x,y);
    int j = query(cc+1,m+1,b,x,y);
    int ans;
    merge(ans,i,j);
    return ans;
}

int main(){
    ll ans=0;
    si(n);
    dp[n] = mod;
    rep(i,n-1) si(arr[i]),arr[i]--;
    RREP(i,n-2,0){
        if(arr[i] == n-1) dp[i] = n-i-1;
        else{
            int k = query(1,0,n-1,i+1,arr[i]);
            dp[i] = (dp[k] - arr[i] + k + n-i-1);
        }
        update(1,0,n-1,i,i);
    }
    rep(i,n) ans += dp[i], cout << dp[i] << " ";;
    printf("%lld\n",ans );
    return 0;
}


#include    <bits/stdc++.h>

#define     M_PI            3.14159265358979323846
#define     mod             1000000007
#define     inf             1000000000000000000
#define     mp              make_pair
#define     pb              push_back
#define     F               first
#define     S               second
#define     ll              long long
#define     pii             pair<int,int>
#define     pli             pair<ll,int>
#define     pil             pair<int,ll>
#define     pll             pair<ll,ll>
#define     si(t)           scanf("%d",&t)
#define     sii(m,n)        scanf("%d %d",&m,&n);
#define     sl(t)           scanf("%lld",&t)
#define     rep(i,n)        for(int i=0;i<n;i++)
#define     REP(i,a,b)      for(int i=a;i<=b;i++)
#define     RREP(i,a,b)     for(int i=a;i>=b;i--)
#define     N               500005

using namespace std;

int arr[N],tree[1<<17],dp[N],n;

void merge(int& c, int a, int b){
    if(dp[a] <= dp[b]) c = a;
    else c = b;
}

void update(int c,int a,int b,int x,int v){
    if(a>b || a>x || b<x) return;
    if(a==b&&a==x){tree[c] = v; return ;}
    int cc=2*c,m=(a+b)>>1;
    update(cc,a,m,x,v);
    update(cc+1,m+1,b,x,v);
    merge(tree[c],tree[cc],tree[cc+1]);
}

int query(int c,int a,int b,int x,int y){
    if(a>b || a>y || b < x) return n;
    if(a>=x && b<=y) return tree[c];
    int cc=2*c,m=(a+b)>>1;
    int i = query(cc,a,m,x,y);
    int j = query(cc+1,m+1,b,x,y);
    int ans;
    merge(ans,i,j);
    return ans;
}

int main(){
    ll ans=0;
    si(n);
    dp[n] = mod;
    rep(i,n-1) si(arr[i]),arr[i]--;
    RREP(i,n-2,0){
        if(arr[i] == n-1) dp[i] = n-i-1;
        else{
            int k = query(1,0,n-1,i+1,arr[i]);
            dp[i] = (dp[k] - arr[i] + k + n-i-1);
        }
        update(1,0,n-1,i,i);
    }
    rep(i,n) ans += dp[i];
    printf("%lld\n",ans );
    return 0;
}


#include    <bits/stdc++.h>

#define     M_PI            3.14159265358979323846
#define     mod             1000000007
#define     inf             1000000000000000000
#define     mp              make_pair
#define     pb              push_back
#define     F               first
#define     S               second
#define     ll              long long
#define     pii             pair<int,int>
#define     pli             pair<ll,int>
#define     pil             pair<int,ll>
#define     pll             pair<ll,ll>
#define     si(t)           scanf("%d",&t)
#define     sii(m,n)        scanf("%d %d",&m,&n);
#define     sl(t)           scanf("%lld",&t)
#define     rep(i,n)        for(int i=0;i<n;i++)
#define     REP(i,a,b)      for(int i=a;i<=b;i++)
#define     RREP(i,a,b)     for(int i=a;i>=b;i--)
#define     N               500005

using namespace std;

int arr[N],tree[1<<17],dp[N],n;

void merge(int& c, int a, int b){
    if(dp[a] <= dp[b]) c = a;
    else c = b;
}

void update(int c,int a,int b,int x,int v){
    if(a>b || a>x || b<x) return;
    if(a==b&&a==x){tree[c] = v; return ;}
    int cc=2*c,m=(a+b)>>1;
    update(cc,a,m,x,v);
    update(cc+1,m+1,b,x,v);
    merge(tree[c],tree[cc],tree[cc+1]);
}

int query(int c,int a,int b,int x,int y){
    if(a>b || a>y || b < x) return n;
    if(a>=x && b<=y) return tree[c];
    int cc=2*c,m=(a+b)>>1;
    int i = query(cc,a,m,x,y);
    int j = query(cc+1,m+1,b,x,y);
    int ans;
    merge(ans,i,j);
    return ans;
}

int main(){
    ll ans=0;
    si(n);
    dp[n] = mod;
    rep(i,n-1) si(arr[i]),arr[i]--;
    RREP(i,n-2,0){

            int k = query(1,0,n-1,i+1,arr[i]);
            dp[i] = (dp[k] - arr[i] + k + n-i-1);

        update(1,0,n-1,i,i);
    }
    rep(i,n) ans += dp[i];
    printf("%lld\n",ans );
    return 0;
}


#include    <bits/stdc++.h>

#define     M_PI            3.14159265358979323846
#define     mod             1000000007
#define     inf             1000000000000000000
#define     mp              make_pair
#define     pb              push_back
#define     F               first
#define     S               second
#define     ll              long long
#define     pii             pair<int,int>
#define     pli             pair<ll,int>
#define     pil             pair<int,ll>
#define     pll             pair<ll,ll>
#define     si(t)           scanf("%d",&t)
#define     sii(m,n)        scanf("%d %d",&m,&n);
#define     sl(t)           scanf("%lld",&t)
#define     rep(i,n)        for(int i=0;i<n;i++)
#define     REP(i,a,b)      for(int i=a;i<=b;i++)
#define     RREP(i,a,b)     for(int i=a;i>=b;i--)
#define     N               500005

using namespace std;

int arr[N],tree[1<<17],n;
ll dp[N];

void merge(int& c, int a, int b){
    if(arr[a] >= arr[b]) c = a;
    else c = b;
}

void build(int c,int a,int b){
    if(a>b) return ;
    if(a == b){
        tree[c] = a;
        return ;
    }
    int cc=2*c,m=(a+b)>>1;
    build(cc,a,m);
    build(cc+1,m+1,b);
    merge(tree[c],tree[cc],tree[cc+1]);
}

int query(int c,int a,int b,int x,int y){
    if(a>b || a>y || b < x) return n;
    if(a>=x && b<=y) return tree[c];
    int cc=2*c,m=(a+b)>>1;
    int i = query(cc,a,m,x,y);
    int j = query(cc+1,m+1,b,x,y);
    int ans;
    merge(ans,i,j);
    return ans;
}

int main(){
    ll ans=0;
    si(n);
    rep(i,n-1) si(arr[i]),arr[i]--;
    arr[n-1] = n-1;
    build(1,0,n-1);
    RREP(i,n-2,0){
            int k = query(1,0,n-1,i+1,arr[i]);
            //cout << k << endl;
            dp[i] = (dp[k] - arr[i] + k + n-i-1);
    }
    rep(i,n) ans += dp[i];
    //rep(i,n) cout << dp[i] << " ";
    printf("%lld\n",ans );
    return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> made(n/DEC + 1, 0);
	vector<int64_t> maid(n/DEC + 1, 0);
	for(int i=1; i<n; ++i) {
		if (a[i] > made[i/DEC]) {
			made[i/DEC] = a[i];
			maid[i/DEC] = i;
		}
	}

	vector<int64_t> mi(n+1, 0);

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = i;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		while(ptr + DEC < a[i]) {
			if (a[mii] < made[ptr/DEC]) {
				mii = maid[ptr/DEC];
			}
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		// Insert
		mi[i] = (n - i);
		mi[i] += mi[mii] - (a[i] - mii);
	}

	cout << accumulate(mi.begin(), mi.end(), 0LL);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> mi(n+1, 0);
	vector<int64_t> mide(n/DEC + 1, INF);
	mide[n/DEC] = 0;

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = INF;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			mii = min(mii, mi[ptr++]);
		}

		while(ptr + DEC <= a[i]) {
			mii = min(mii, mide[ptr/DEC]);
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			mii = min(mii, mi[ptr++]);
		}

		// Insert
		mi[i] += (a[i] - i);
		mi[i] += mii + n - a[i];

		// Update
		int st = i/DEC;
		mide[st] = min(mide[st], mi[i]);
	}

	cout << accumulate(mi.begin(), mi.end(), 0);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> mi(n+1, 0);
	vector<int64_t> mide(n/DEC + 1, 0);
	vector<int64_t> miid(n/DEC + 1, 0);

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = i;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		while(ptr + DEC < a[i]) {
			if (a[mii] < mide[ptr/DEC]) {
				mii = miid[ptr/DEC];
			}
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		// Insert
		mi[i] = (n - i);
		if (mii != i) mi[i] += mi[mii] - (a[i] - mii);

		// Update
		int st = i/DEC;
		if (a[i] > mide[st]) {
			mide[st] = a[i];
			miid[st] = i;
		}
	}

	cout << accumulate(mi.begin(), mi.end(), 0);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> mi(n+1, 0);
	vector<int64_t> mide(n/DEC + 1, INF);
	mide[n/DEC] = 0;

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = INF;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			mii = min(mii, mi[ptr] + ptr);
			ptr += 1;
		}

		while(ptr + DEC < a[i]) {
			mii = min(mii, mide[ptr/DEC]);
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			mii = min(mii, mi[ptr] + ptr);
			ptr += 1;
		}

		// Insert
		mi[i] += (n - i);
		mi[i] += (mii - a[i]);

		// Update
		int st = i/DEC;
		mide[st] = min(mide[st], mi[i] + i);
	}

	cout << accumulate(mi.begin(), mi.end(), 0);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> mi(n+1, 0);
	vector<int64_t> mide(n/DEC + 1, 0);
	vector<int64_t> miid(n/DEC + 1, 0);

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = i;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		while(ptr + DEC < a[i]) {
			if (a[mii] < mide[ptr/DEC]) {
				mii = miid[ptr/DEC];
			}
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		// Insert
		mi[i] = (n - i);
		if (mii != i) mi[i] += mi[mii] - (a[i] - mii);

		// Update
		int st = i/DEC;
		if (a[i] > mide[st]) {
			mide[st] = a[i];
			miid[st] = i;
		}
	}

	cout << accumulate(mi.begin(), mi.end(), 0LL);
	return 0;
}


#include <iostream>
using namespace std;
struct node{
	int x;
	int xx;
	void assLeaf(int a, int pos){
		x = a;
		xx = pos;
	}
	void merge(node l, node r){
		x = max(l.x, r.x);
		xx = r.xx;
		if(x==l.x)
			xx = l.xx;
	}
};
class segTree{
	int N;
	node* A;
	public:
	void init(int n, int a[]){
		int sz;
		for(sz = 0; (1<<sz) <= n; sz++);
		sz = sz<<1;
		N = sz;
		A = new node[N];
		build(1,0,n-1,a);

	}
	void build(int ind, int L, int R, int a[]){
		if (L==R){
			A[ind].assLeaf(a[L], L);
			return ;
		}
		int left, right, mid;
		left = 2*ind;
		right = left+1;
		mid = (L+R)>>1;
		build(left, L, mid, a);
		build(right, mid+1, R, a);

		//cout << ind << " " << left << " " << right << endl;
		//cout.flush();

		A[ind].merge(A[left], A[right]);
	}
	node query(int ind, int L, int R, int x, int y, int a[]){
		if (x==L && y==R)
			return A[ind];
		int mid = (L+R)>>1;
		if(y<=mid)
			return query(2*ind, L, mid, x, y, a);
		else if(x>mid)
			return query(2*ind+1, mid+1, R, x, y, a);
		node left = query(2*ind, L, mid, x, mid, a);
		node right = query(2*ind+1, mid+1, R, mid+1, y, a);
		node ans;
		ans.merge(left, right);
		return ans;
	}
};

int main() {
	int n;
	cin>>n;
	int a[n];
	int i;
	for(i=0;i<n-1;i++){
		cin>>a[i];
		a[i]--;

	}
	a[n-1] = n-1;
	segTree ped;
	ped.init(n, a);
	int dp[n];

	dp[n-1] = 0;
	for(i=n-2;i>=0;i--){
		node M = ped.query(1, 0, n-1, i+1, a[i], a);
		int m = M.xx;
		dp[i] = dp[m] - (a[i]-m) +n-i-1;
	}
	int ans = 0;
	for(i=0;i<n;i++)
		ans += dp[i];
	cout<<ans<<endl;
	cout.flush();

	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> mi(n+1, 0);
	vector<int64_t> mide(n/DEC + 1, INF);
	mide[n/DEC] = 0;

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = INF;
		int64_t mid = -1;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			if (mii > mi[ptr]) {
				mii = mi[ptr];
				mid = ptr;
			}
			ptr += 1;
		}

		while(ptr + DEC <= a[i]) {
			if (mii > mide[ptr/DEC]) {
				mii = mide[ptr/DEC];
				mid = ptr;
			}
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			if (mii > mi[ptr]) {
				mii = mi[ptr];
				mid = ptr;
			}
			ptr += 1;
		}

		// Insert
		mi[i] = (n - i) + mii - (a[i] - mid);

		// Update
		int st = i/DEC;
		mide[st] = min(mide[st], mi[i]);
	}

	cout << accumulate(mi.begin(), mi.end(), 0);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> made(n/DEC + 1, 0);
	vector<int64_t> maid(n/DEC + 1, 0);
	for(int i=1; i<n; ++i) {
		if (a[i] > made[i/DEC]) {
			made[i/DEC] = a[i];
			maid[i/DEC] = i;
		}
	}

	vector<int64_t> mi(n+1, 0);

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = i;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		while(ptr + DEC < a[i]) {
			if (a[mii] < made[ptr/DEC]) {
				mii = maid[ptr/DEC];
			}
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		// Insert
		mi[i] = (n - i);
		if (mii != i) mi[i] += mi[mii] - (a[i] - mii);
	}

	cout << accumulate(mi.begin(), mi.end(), 0LL);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> mi(n+1, 0);
	vector<int64_t> mide(n/DEC + 1, INF);
	mide[n/DEC] = 0;

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = INF;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			mii = min(mii, mi[ptr] + ptr);
			ptr += 1;
		}

		while(ptr + DEC < a[i]) {
			mii = min(mii, mide[ptr/DEC]);
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			mii = min(mii, mi[ptr] + ptr);
			ptr += 1;
		}

		// Insert
		mi[i] += (n - i);
		mi[i] += (mii - a[i]);

		// Update
		int st = i/DEC;
		mide[st] = min(mide[st], mi[i] + i);
	}

	cout << accumulate(mi.begin(), mi.end(), 0LL);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int> made(n/DEC + 1, 0);
	vector<int> maid(n/DEC + 1, 0);
	for(int i=1; i<n; ++i) {
		if (a[i] > made[i/DEC]) {
			made[i/DEC] = a[i];
			maid[i/DEC] = i;
		}
	}

	vector<int64_t> mi(n+1, 0);

	for(int i=n-1; i>=1; --i) {
		// Query
		int mii = i;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		while(ptr + DEC < a[i]) {
			if (a[mii] < made[ptr/DEC]) {
				mii = maid[ptr/DEC];
			}
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		// Insert
		mi[i] += (n - i);
		mi[i] += mi[mii] - (a[i] - mii);
	}

	cout << accumulate(mi.begin(), mi.end(), 0LL);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> mi(n+1, 0);
	vector<int64_t> mide(n/DEC + 1, INF);
	mide[n/DEC] = 0;

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = INF;
		int64_t mid = -1;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			if (mii > mi[ptr]) {
				mii = mi[ptr];
				mid = ptr;
			}
			ptr += 1;
		}

		while(ptr + DEC < a[i]) {
			if (mii > mide[ptr/DEC]) {
				mii = mide[ptr/DEC];
				mid = ptr;
			}
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			if (mii > mi[ptr]) {
				mii = mi[ptr];
				mid = ptr;
			}
			ptr += 1;
		}

		// Insert
		mi[i] = (n - i) + mii - (a[i] - mid);

		// Update
		int st = i/DEC;
		mide[st] = min(mide[st], mi[i]);
	}

	cout << accumulate(mi.begin(), mi.end(), 0);
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

# define INF ((int64_t)1e18 + 42)
# define DEC (300)

# define EXIT(...) printf(__VA_ARGS__), exit(0)

int main()
{
	int n; cin >> n;

	vector<int> a(n);
	for(int i=1; i<n; ++i) {
		scanf("%d", &a[i]);
	}

	vector<int64_t> made(n/DEC + 1, 0);
	vector<int64_t> maid(n/DEC + 1, 0);
	for(int i=1; i<n; ++i) {
		if (a[i] > made[i/DEC]) {
			made[i/DEC] = a[i];
			maid[i/DEC] = i;
		}
	}

	vector<int64_t> mi(n+1, 0);

	for(int i=n-1; i>=1; --i) {
		// Query
		int64_t mii = i;

		int ptr = i+1;
		while(ptr % DEC != 0 && ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		while(ptr + DEC <= a[i]) {
			if (a[mii] < made[ptr/DEC]) {
				mii = maid[ptr/DEC];
			}
			ptr += DEC;
		}

		while(ptr <= a[i]) {
			if (a[mii] < a[ptr]) {
				mii = ptr;
			}
			ptr += 1;
		}

		// Insert
		mi[i] += (n - i);
		mi[i] += mi[mii] - (a[i] - mii);
	}

	cout << accumulate(mi.begin(), mi.end(), 0LL);
	return 0;
}


s=input().split()
n=int(s[0])
m = int(s[1])

a=[]
b=[]
c=[1] * m

ans=1

for i in range(n):
    s=input()
    a.append(s)
    b.append(1)
#print (n, m, a)

for i in range (m):
    t=0
    p=0
    for j in range(n):
        #print (a[n][m])
        if a[j][i] == '1':
            t+=1
            p=j
            q=i
    if t == 1:
        b[p] = 0
        c[q] = 0

g=0
for i in range (n):
    g+=b[i]

if g == 0:
    ans = 0

if ans:
    print("YES")
else:
    print("NO")


n, m = [int(x) for x in input().split(' ')]

ans = 'NO'
rows = [[int(x) for x in list(input())] for row in range(n)]

totals = [sum([rows[i][j] for i in range(n)]) for j in range(m)]

for row in rows:
    if min([t - r for (t,r) in zip(totals, row)]) > 0:
        ans = 'YES'
        break

print(ans)


def main():
    n, m = map(int, input().split())
    switches = [list(map(int, input())) for _ in range(n)]
    counts = list(map(sum, zip(*switches)))

    for switch in switches:
        unnecessary = True

        for i in range(m):
            if switch[i] and counts[i] < 2:
                unnecessary = False
                break

        if unnecessary:
            print("YES")
            return

    print("NO")

main()


switch, lamp = tuple(map(int, input().split(' ')))

matrix = []
for i in range(switch):
    temp = input()
    row = []
    for j in temp:
        row.append(int(j))
    matrix.append(row)

duplLamp = []

for k in range(len(matrix[0])):
    counter = 0
    for j in matrix:
        counter += j[k]

    duplLamp.append(counter)

for i in range(len(duplLamp)):
    duplLamp[i] -= 1
    if duplLamp[i] > 0:
        duplLamp[i] = 1

flag = True
for i in matrix:
    if duplLamp == i:
        print('YES')
        flag = False

if flag:
    print('NO')


switch, lamp = tuple(map(int, input().split(' ')))

matrix = []
for i in range(switch):
    temp = input()
    row = []
    for j in temp:
        row.append(int(j))
    matrix.append(row)

duplLamp = []

for k in range(len(matrix[0])):
    counter = 0
    for j in matrix:
        counter += j[k]

    duplLamp.append(counter)

for i in range(len(duplLamp)):
    duplLamp[i] -= 1
    if duplLamp[i] > 0:
        duplLamp[i] = 1

flag = True
for i in matrix:
    counter = 0
    for j in range(len(i)):
        if i[j] <= duplLamp[j]:
            counter += 1
    if counter == lamp:
        print('Yes')
        flag = False
        break

if flag:
    print('NO')


n,m=(int(i) for i in input().split())
a=[[] for i in range(n)]
s=[input() for i in range(n)]
b=[0]*m
f=[True]*n
for i in range(n):
    for j in range(m):
        if s[i][j]=='1':
            a[i].append(j)
            b[j]+=1
for i in range(n):
    for j in a[i]:
        if b[j]==1:
            f[i]=False
            break
if True in f:
    print('YES')
else:
    print('NO')


import sys
import math,bisect
sys.setrecursionlimit(10 ** 5)
from itertools import groupby,accumulate
from heapq import heapify,heappop,heappush
from collections import deque,Counter,defaultdict
def I(): return int(sys.stdin.readline())
def neo(): return map(int, sys.stdin.readline().split())
def Neo(): return list(map(int, sys.stdin.readline().split()))
n,m = neo()
A = [input() for i in range(n)]
f = 0
B = [0]*m
for i in range(n):
    for j in range(m):
        if A[i][j] == '1':
            B[j] += 1
#print(B)
for i in range(n):
    f = 0
    for j in range(m):
        if A[i][j] == '1' and B[j] <= 1:
            f = 1
    if f == 0:
        print('YES')
        exit()
print('NO')


n, m = list(map(int, input().split()))
a = []
s = [0] * m
for i in range(n):
    a.append(list(map(int, input().split())))
    for j in range(m):
        s[j] += a[-1][j]

for i in range(n):
    f = True
    for j in range(m):
        if s[j] - a[i][j] == 0:
            f = False
            break
    if f:
        print('YES')
        exit

print('NO')


import numpy as np

n, m = list(map(int, input().split()))
a = []
s = np.zeros((m, ))
for i in range(n):
    a.append(list(map(input().split())))
    s += np.array(a[-1])

print("YES")


n, m = list(map(int, input().split()))
a = []
s = [0] * m
for i in range(n):
    a.append(list(map(int, input().split())))
    for j in range(m):
        s[j] += a[-1][j]

for i in range(n):
    f = True
    for j in range(m):
        if s[j] - a[i][j] == 0:
            f = False
            break
    if f:
        print('YES')
        exit(0)

print('NO')


n, m = list(map(int, input().split()))
a = []
s = [0] * m
for i in range(n):
    a.append(list(map(int, input().split())))
    for j in range(m):
        s[j] += a[-1][j]

for i in range(n):
    f = True
    for j in range(m):
        if s[j] - a[i][j] == 0:
            f = False
            break
    if f:
        print('YES')
        exit()

print('NO')


n, m = list(map(int, input().split()))
a = []
s = [0] * m
for i in range(n):
    a.append(list(map(int, list(input()))))
    for j in range(m):
        s[j] += a[-1][j]

for i in range(n):
    f = True
    for j in range(m):
        if s[j] - a[i][j] == 0:
            f = False
            break
    if f:
        print('YES')
        exit(0)

print('NO')


n, m = list(map(int, input().split()))
a = []
s = [0] * m
for i in range(n):
    a.append(list(map(input().split())))
    for j in range(m):
        s[j] += a[-1][j]

for i in range(n):
    f = True
    for j in range(m):
        if s[j] - a[i][j] == 0:
            f = False
            break
    if f:
        print('YES')
        exit

print('NO')


n, m = list(map(int, input().split()))
# a = []
# s = [0] * m
# for i in range(n):
#     a.append(list(map(int, input().split())))
#     for j in range(m):
#         s[j] += a[-1][j]

# for i in range(n):
#     f = True
#     for j in range(m):
#         if s[j] - a[i][j] == 0:
#             f = False
#             break
#     if f:
#         print('YES')
#         exit

print('NO')


from sys import stdin

n, m = map(int, input().split())
s = stdin.readlines()

def main():
    l = [0] * m

    for q in s:
        for i, x in enumerate(q):
            if x == '1':
                l[i] += 1

    bad = False

    for q in s:
        nl = map(lambda x, y: x - y, l, map(int, q))
        if sum(map(lambda x: x == 0, nl)) == 0:
            bad = True
            break

    if bad: print('YES')
    else: print('NO')

main()


def orTogether(a,b):
    temp = [0]*len(a)
    for i in range(len(a)):
        temp[i] = a[i] | b[i]
    return temp

n,m = [int(k) for k in input().split(" ")]

inp = []
for i in range(n):
    temp = list(input())
    for j in range(len(temp)):
        temp[j] = int(temp[j])
    inp.append(temp)
arr = []
arr2 = []
arr.append([0]*m)
arr2.append([0]*m)

for switch in inp:
    arr.append(orTogether(arr[-1],switch))

for switch in inp[::-1]:
    arr2.append(orTogether(arr2[-1],switch))

total = [1]*m
arr2.append([0]*m)

shouldPrint = True

for i in range(len(arr)-1):
    if orTogether(arr[i],arr2[n-i-1]) == total:
        print("YES")
        shouldPrint = False
        break

if shouldPrint:
    print("NO")


# Getting switch and lamp counts in addition to the lamp
# combinations corresponding to each switch from codeforces.
switchCount,lampCount = tuple(map(int,input().split()))
switches = []
for i in range(switchCount):
    switches.append(int(input(),2))
# Defining method to determing if all lamps can be switched
# on, if switch with given index is not taken into account.
def canSwitchOnWithout(index):
    bitwiseOr = 0
    for i in range(switchCount):
        if i !=index:
            bitwiseOr = bitwiseOr | switches[i]
    return bitwiseOr
# Determining if a switch exists such that without it all
# lamps can still be turned on.
lampsOn,index,exists = int('1'*lampCount,2),0,False
while not exists and index<switchCount:
    if canSwitchOnWithout(index) == lampsOn:
        exists = not exists
    else: index = index + 1
# Final Verdict.
print('YES') if exists else print('NO')


####################
# 26th October 2019.
####################

##################################################################
# Getting switch and lamp counts in addition to the lamp
# combinations corresponding to each switch from codeforces.
switchCount,lampCount = tuple(map(int,input().split()))
switches = []
for i in range(switchCount):
    switches.append(int(input(),2))
# Defining method to determing if all lamps can be switched
# on, if switch with given index is not taken into account.
def canSwitchOnWithout(index):
    bitwiseOr = 0
    for i in range(switchCount):
        if i !=index:
            bitwiseOr = bitwiseOr | switches[i]
    return bitwiseOr
# Determining if a switch exists such that without it all
# lamps can still be turned on.
lampsOn,index,exists = int('1'*lampCount,2),0,False
while not exists and index<switchCount:
    if canSwitchOnWithout(index) == lampsOn:
        exists = not exists
    else: index = index + 1
# Final Verdict.
print('YES') if exists else print('NO')
##################################################################

                          ########################################
                          # Programming-Credits atifcppprogrammer.
                          ########################################


""" 616C """
""" 1152B """
import math
# import sys
def main():
	# n ,m= map(int,input().split())
	# arr = list(map(int,input().split()))
	# b = list(map(int,input().split()))
	# n = int(input())
	# string = str(input())
	n ,m = map(int,input().split())
	arr = []
	for _ in range(n):
		arr.append(list(str(input())))
	dp = [0 for _ in range(m)]
	for x in arr:
		for j in range(len(x)):
			if x[j]=='1':
				dp[j]+=1
	for i in range(n):
		for j in range(m):
			if(arr[i][j]=='1'):
				dp[j]-=1
		cnt = 0
		for k in range(m):
			if(dp[k]>0):
				cnt+=1
		if(cnt==m):
			print("YES")
			return
		for j in range(m):
			if(arr[i][j]=='1'):
				dp[j]+=1
	print("NO")
	return

main()
# def test():
# 	t = int(input())
# 	while t:
# 		main()
# 		t-=1
# test()


n,m=map(int,input().split())
ar=[]
for i in range(n):
    ar.append(list(map(int,list(input()))))
br=[0]*m
for i in range(n):
    for j in range(m):
        br[j]+=ar[i][j]
flag=False
for i in range(n):
    f1=True
    for j in range(m):
        if(ar[i][j]==1 and br[j]==1):
            f1=False
            break
    if(f1):
        flag=True
        break
if(flag):
    print("YES")
else:
    print("NO")


n, m = map(int, input().split())
a = [list(map(int, input())) for i in range(n)]

ignorable = [True] * n

for i in range(m):
    cnt = 0
    for j in range(n):
        cnt += a[j][i]
    if cnt == 1:
        for j in range(n):
            if a[j][i]:
                ignorable[j] = False

if any(ignorable):
    print('YES')
else:
    print('NO')


a=list(map(int,input().split()))
n=a[0]
m=a[1]
l=[]
for i in range(n):
    k=list(input())
    k=list(map(int,k))
    l.append(k)

f=[]
for i in range(m):
   f.append(0)

for i in range(m):
    s=0
    for j in range(n):
        s+=l[j][i]
    if(s!=1):
        f[i]+=1

bigflag=0
for i in range(n):
    flag=0
    for j in range(m):
        if(l[i][j]==1 and f[j]==0):
            flag=1
    if(flag==0):
        bigflag=1
        print("YES")
        break

if(bigflag==0):
    print("NO")


n,m = map(int,input().split())
a = [list(input()) for i in range(n)]
b = [0]*m
for i in range(n):
  for j in range(m):
    b[j] += int(a[i][j])
flg = 0
for i in range(n):
  for j in range(m):
    if a[i][j] == "1" and b[j] == 1:
      flg += 1
      break
if flg == n:
  print("NO")
else:
  print("YES")


n, m = [int(i) for i in input().split()]
a = []
for i in range(n):
    a.append(list(input()))

s = [0] * m
for i in range(m):
    for j in range(n):
        if a[j][i] == "1":
            s[i] += 1

for i in range(n):
    f = True
    for j in range(m):
        if s[j] - int(a[i][j]) == 0:
            f = False
            break
    if f:
        print("YES")
        quit()
print("NO")


import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.util.*

fun main(args: Array<String>) {
    Thread { solve() }.start()
}

fun solve() {
    val scanner = Scanner(System.`in`)
    val n = scanner.nextInt()
    val m = scanner.nextInt()
    val l = IntArray(m)
    val arr = Array(n) {
        val str = scanner.next()
        BooleanArray(m) {
            if (str[it] == '1') {
                l[it]++
                true
            }
            else
                false
        }
    }
    for (i in 0 until n) {
        var b = true
        for (j in 0 until m) {
            if (arr[i][j]) {
                if (l[j] < 2) {
                    b = false
                    break
                }
            }
        }
        if (b) {
            println("YES")
            return
        }
    }
    println("NO")
}

class Scanner(s: InputStream) {
    var st: StringTokenizer? = null
    var br: BufferedReader = BufferedReader(InputStreamReader(s))
    @Throws(IOException::class)
    operator fun next(): String {
        while (st == null || !st!!.hasMoreTokens())
            st = StringTokenizer(br.readLine())
        return st!!.nextToken()
    }
    @Throws(IOException::class)
    fun nextInt(): Int {
        return Integer.parseInt(next())
    }
    @Throws(IOException::class)
    fun nextLong(): Long {
        return java.lang.Long.parseLong(next())
    }
    @Throws(IOException::class)
    fun nextLine(): String {
        return br.readLine()
    }
    @Throws(IOException::class)
    fun nextDouble(): Double {
        return java.lang.Double.parseDouble(next())
    }
    @Throws(IOException::class)
    fun ready(): Boolean {
        return br.ready()
    }
}


fun main() {
    fun readInts() = readLine()!!.split(" ").map(String::toInt)

    val (numRows, numCols) = readInts()
    val matrix = Array(numRows) { "" }
    for (numRow in 0 until numRows) matrix[numRow] = readLine()!!
    val necessaryRows = mutableSetOf<Int>()
    for (column in 0 until numCols) {
        val rows = mutableSetOf<Int>()
        for (row in 0 until numRows) if (matrix[row][column] == '1') rows.add(row)
        if (rows.size == 1) necessaryRows.add(rows.first())
    }
    print(if (necessaryRows.size < numRows) "YES" else "NO")
}


import java.util.*
import kotlin.math.min

private val scan = Scanner(System.`in`)

fun main(args: Array<String>) {

    val n = scan.nextInt()
    val m = scan.nextInt()

    val counts = IntArray(m)
    Arrays.fill(counts, 0)

    val graph = (0 until n).map {
        scan.next()
                .mapIndexed { index, value ->
                    counts[index] += value.toInt() - 48
                    value.toInt() - 48
                }
    }

//    println(counts.toList())

    val crucial = mutableListOf<Int>()
    counts.forEachIndexed { index, value -> if (value == 1) crucial.add(index) }
    if (crucial.isEmpty()) {
        println("YES")
        return
    }

    if (graph.filter { item -> crucial.map { item[it] == 1 }.any { it } }.size == graph.size) {
        println("NO")
    } else {
        println("YES")
    }
}


#include<stdio.h>
#include<string.h>

int main(){
    int n,m;
    scanf("%d %d",&n, &m);

    int check[m];
    memset(check, 0, sizeof(check));
    char switches[n][m + 1];
    int j = 0;

    while(j < n){
        scanf("%s", switches[j]);

        int i = 0;
        while(switches[j][i]!= '\0'){
            if(switches[j][i] == '1')
                check[i]++;

            i++;
        }
        j++;

    }

    int exit = 0;
    j = 0;
    while(j < n){
        int i = 0;
        while(switches[j][i]!= '\0'){
            if(switches[j][i] == '1'){
                if(check[i] - 1 == 0){
                    printf("NO\n");
                    exit = 1;
                    break;
                }
            }
            i++;
        }

        if(exit)
            break;

        j++;
    }

    if(!exit){
        printf("YES\n");
    }

}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(){
    int n, m;
    scanf("%d %d", &n, &m);

    int lamps[m];
    int i = 0;
    int j = 0;
    memset(lamps, 0, sizeof(lamps));

    int somework;
    char dump[n][m];

    for(i = 0;i < n; i++){
        scanf("%s", dump[i]);
    }

    for(i = 0; i < n; i++){
        somework = 0;
        for(j = 0; j < m; j++){
            if(dump[i][j] - 48 > lamps[j]){
                lamps[j] = dump[i][j];
                somework = 1;
            }
        }

        if(!somework){
            break;
        }

    }

    if(somework){
        printf("NO\n");
    } else {
        printf("YES\n");
    }

}


#include<stdio.h>

int main(){
    int n,m;
    scanf("%d %d",&n, &m);

    int check[m];
    char switches[n][m];
    int j = 0;
    while(j < n){
        scanf("%s", switches[j]);

        int i = 0;
        while(switches[j][i]!= '\0'){
            if(switches[j][i] == '1')
                check[i]++;

            i++;
        }
        j++;

    }

    j = 0;
    int exit = 0;

    while(j < n){
        int i = 0;
        while(switches[n][i]!= '\0'){
            if(switches[j][i] == '1'){
                if(check[i] - 1 == 0){
                    printf("NO\n");
                    exit = 1;
                    break;
                }
            }
            i++;
        }

        if(exit)
            break;

        j++;
    }

    if(!exit){
        printf("YES\n");
    }

}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int n, m;

void checkWork(int lamps[], char dump[][m], int n, int m);

int main(){

        scanf("%d %d", &n, &m);

        int lamps[m];
        int i = 0;
        int j = 0;
        memset(lamps, 0, sizeof(lamps));

        int somework;
        char dump[n][m];

        for(i = 0;i < n; i++){
            scanf("%s", dump[i]);
        }

        checkWork(lamps, dump, n, m);

}

void checkWork(int lamps[], char dump[][m], int n, int m){
    int i = 0;
    int j = 0;
    int somework = 0;

    for(i = 0; i < n; i++){
        somework = 0;
        for(j = 0; j < m; j++){
            if(dump[i][j] - 48 > lamps[j]){
                lamps[j] = dump[i][j];
                somework = 1;
            }
        }

        if(!somework){
            break;
        }

    }

    if(somework){
        memset(lamps, 0, m * 4);

        for(i = n - 1; i > -1; i--){
            somework = 0;
            for(j = 0; j < m; j++){
                if(dump[i][j] - 48 > lamps[j]){
                    lamps[j] = dump[i][j];
                    somework = 1;
                }
            }

            if(!somework){
                break;
            }

        }

        if(somework){
            printf("NO\n");
        } else {
            printf("YES\n");
        }

    } else {
        printf("YES\n");
    }

}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(){
    int n, m;
    scanf("%d %d", &n, &m);

    int lamps[m];
    int i = 0;
    int j = 0;
    memset(lamps, 0, sizeof(lamps));

    int somework;
    char dump[3000];

    for(i = 0; i < n; i++){
        somework = 0;
        scanf("%s", dump);
        for(j = 0; j < m; j++){
            if(dump[j] - 48 > lamps[j]){
                lamps[j] = dump[j];
                somework = 1;
                //printf("%d\n", somework);

            }
        }

        if(!somework){
            for(i = i + 1; i < n ; i++){
                scanf("%s", dump);
            }
            break;
        }

    }

    if(somework){
        printf("NO\n");
    } else {
        printf("YES\n");
    }

}


#include<stdio.h>
#include<string.h>

int main(){
    int n,m;
    scanf("%d %d",&n, &m);

    int check[m];
    memset(check, 0, sizeof(check));
    char switches[n][m + 1];
    int j = 0;

    while(j < n){
        scanf("%s", switches[j]);

        int i = 0;
        while(switches[j][i]!= '\0'){
            if(switches[j][i] == '1')
                check[i]++;

            i++;
        }
        j++;

    }

    int yes = 0;

  //  for(j  = 0; j < m; j++){
   //     printf("%d ", check[j]);
   // }
    //printf("\n");

    j = 0;

    while(j < n){
        int i = 0;
        while(switches[j][i]!= '\0'){
            if(switches[j][i] == '1'){
                if(check[i] - 1 == 0){
                    break;
                }
            }
            i++;
        }
        if(i == m){
            yes = 1;
            break;
        }
        j++;
    }

    if(yes){
        printf("YES\n");
    } else {
        printf("NO\n");
    }

}


#include<stdio.h>

int main(){
    int n,m;
    scanf("%d %d",&n, &m);

    int check[m];
    char switches[n][m];
    int j = 0;
    while(j < n){
        scanf("%s", switches[j]);

        int i = 0;
        while(switches[j][i]!= '\0'){
            if(switches[j][i] == '1')
                check[i]++;

            i++;
        }
        j++;

    }

    j = 0;
    int exit = 0;

    while(j < n){
        while(switches[n][i]!= '\0'){
            if(switches[i] == '1'){
                if(check[i] - 1 == 0){
                    printf("NO\n");
                    exit = 1;
                    break;
                }
            }
            i++;
        }

        if(exit)
            break;

        j++;
    }

    if(!exit){
        printf("YES\n");
    }

}


#include<stdio.h>
#include<string.h>

int main(){
    int n,m;
    scanf("%d %d",&n, &m);

    int check[m];
    memset(check, 0, sizeof(check));
    char switches[n][m + 1];
    int j = 0;

    while(j < n){
        scanf("%s", switches[j]);

        int i = 0;
        while(switches[j][i]!= '\0'){
            if(switches[j][i] == '1')
                check[i]++;

            i++;
        }
        j++;

    }

    int yes = 0;

  //  for(j  = 0; j < m; j++){
   //     printf("%d ", check[j]);
   // }
    //printf("\n");

    j = 0;

    while(j < n){
        int i = 0;
        while(switches[j][i]!= '\0'){
            if(switches[j][i] == '1'){
                if(check[i] - 1 == 0){
                    break;
                }
            }
            i++;
        }
        if(i == m){
            printf("YES\n");
            return 0;
        }
        j++;
    }

    printf("NO\n");

}


#include <stdio.h>
char a[2001][2001];
int sum[2001];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    char dust;
    scanf("%c",&dust);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            scanf("%c",&a[i][j]);
            //printf("%c",a[i][j]);
            if(a[i][j]=='1')
            sum[j]++;
        }
        scanf("%c",&dust);
    }
    int ans=0;
    for(int i=0;i<n;i++)
    {
        int flag=0;
        for(int j=0;j<m;j++)
        {
            if(a[i][j]=='1'&&sum[j]==1)
            {
                flag=1;
            }
        }
        if(flag==0)
        {
            ans=1;
            break;
        }
    }
    if(ans==0)
    {
        printf("NO");
    }
    else
    {
        printf("YES");
    }
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int check (int * light, int M){
    for (int i = 0; i < M; i++){
        if (!light[i])
            return 0;
    }
    return 1;
}

void printanswer(int yes){
     if (yes)
        printf ("YES");
    else
        printf ("NO");
}

int main (){
    int N;
    int yes = 0;
    int M;
    int i;
    int z;
    int j;
    scanf ("%i", &N);
    scanf ("%i", &M);
    char A[N][M];
    int light[M];
    for (i = 0; i < N; i++){
        scanf ("%s", &A[i]);
    }
    for (i = 0; i < N; i++){
        memset(light,0,sizeof light);
        for (j = 0; j < N; j++){
            if (j != i){
                for (z = 0; z < M; z++){
                    if (A[j][z] == '1')
                        light[z] = 1;
                }
            }
        }
        for (int i = 0; i < M; i++)
            printf ("%i ", light[i]);
        printf ("\n");
        if (check(light, M)){
            yes = 1;
            break;
        }
    }
    printanswer(yes);
    system ("PAUSE");
}


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

void printanswer (int check){
     if (check)
        printf ("YES");
     else
         printf ("NO");
}

int main (){
    int N;
    int M;
    int i;
    int j;
    int check = 0;
    scanf ("%i", &N);
    scanf ("%i", &M);
    char A[N][M];
    char light[M];
    memset(light,48,sizeof light);
    int temp[M];
    for (i = 0; i < N; i++){
        scanf ("%s", &A[i]);
        for (j = 0; j < M; j++){
            if (A[i][j] == '1')
               light[j]++;
        }
    }
    for (i = 0; i < N && check == 0; i++){
        check = 1;
        for (j = 0; j < M; j++){
            if (light[j] == A[i][j])
                check = 0;
            //printf ("(%i %i) ", light[j], A[i][j]);
        }
    }
    printanswer(check);
    //system ("PAUSE");
}


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

void printanswer (int check){
     if (check)
        printf ("YES");
     else
         printf ("NO");
}

int main (){
    int N;
    int M;
    int i;
    int j;
    int check = 0;
    scanf ("%i", &N);
    scanf ("%i", &M);
    char A[N][M];
    int light[M];
    memset(light,0,sizeof light);
    for (i = 0; i < N; i++){
        scanf ("%s", &A[i]);
        for (j = 0; j < M; j++){
            if (A[i][j] == '1')
               light[j]++;
        }
    }
    for (i = 0; i < N && check == 0; i++){
        check = 1;
        for (j = 0; j < M; j++){
            if (light[j] == A[i][j] - '0')
                check = 0;
            //printf ("(%i %i) ", light[j], A[i][j]);
        }
    }
    printanswer(check);
    //system ("PAUSE");
}


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int check (int * light, int M){
    for (int i = 0; i < M; i++){
        if (!light[i])
            return 0;
    }
    return 1;
}

void printanswer(int yes){
     if (yes)
        printf ("YES");
    else
        printf ("NO");
}

int main (){
    int N;
    int yes = 0;
    int M;
    int i;
    int z;
    int j;
    scanf ("%i", &N);
    scanf ("%i", &M);
    char A[N][M];
    int light[M];
    for (i = 0; i < N; i++){
        scanf ("%s", &A[i]);
    }
    for (i = 0; i < N; i++){
        memset(light,0,sizeof light);
        for (j = 0; j < N; j++){
            if (j != i){
                for (z = 0; z < M; z++){
                    if (A[j][z] == '1')
                        light[z] = 1;
                }
            }
        }
        //for (int i = 0; i < M; i++)
            //printf ("%i ", light[i]);
        //printf ("\n");
        if (check(light, M)){
            yes = 1;
            break;
        }
    }
    printanswer(yes);
    //system ("PAUSE");
}


#include<stdio.h>
#include<stdlib.h>
int n,m;
char a[2007][2007];
int x[2007];
int cat(int i){
	int j,r=1;
	for(j=0;j<m;j++){
		x[j]-=a[i][j]=='1'?1:0;
	}
	for(j=0;j<m;j++){
		if(x[j]==0){
			r=0;
		}
	}
	for(j=0;j<m;j++){
		x[j]+=a[i][j]=='1'?1:0;
	}
	return r;
}
void run(){
	int i,j;
	while(scanf("%d%d",&n,&m)!=EOF){
		for(i=0;i<n;i++){
			scanf("%s",&a[i]);
		}
		for(i=0;i<m;i++){
			x[i]=0;
		}
		for(i=0;i<n;i++){
			for(j=0;j<m;j++){
				x[j]+=a[i][j]=='1'?1:0;
			}
		}
		for(i=0;i<n;i++){
			if(cat(i)==1){
				printf("YES\n");
				break;
			}
		}
		if(i<n){
			continue;
		}
		printf("NO\n");
	}
}
main(){
#ifndef	ONLINE_JUDGE
	freopen("e44b_min.in","rb",stdin);
	freopen("e44b_.out","wb",stdout);
#endif
	run();
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
int n,m;
char a[2007][2007];
int cat(int k){
	int i,j;
	char x[2007];
	for(i=0;i<m;i++){
		x[i]=0;
	}
	for(i=0;i<n;i++){
		if(i==k){
			continue;
		}
		for(j=0;j<m;j++){
			if(a[i][j]=='1'){
				x[j]=1;
			}
		}
	}
	for(i=0;i<m;i++){
		if(x[i]==0){
			return 0;
		}
	}
	return 1;
}
void run(){
	int i;
	while(scanf("%d%d",&n,&m)!=EOF){
		for(i=0;i<n;i++){
			scanf("%s",&a[i]);
		}
		for(i=0;i<n;i++){
			if(cat(i)==1){
				printf("YES\n");
				break;
			}
		}
		if(i<n){
			continue;
		}
		printf("NO\n");
	}
}
main(){
	run();
	return 0;
}


#include <stdio.h>
int n,m,cnt[2005];
char a[2005][2005];
int main()
{
	scanf("%d%d",&n,&m);
	for (int i=0;i<n;++i)
	{
		scanf("%s",a[i]);
		for (int j=0;j<m;++j) cnt[j]+=a[i][j]-'0';
	}
	for (int i=0;i<n;++i)
	{
		int flag=0;
		for (int j=0;j<m;++j) if (a[i][j]=='1') flag|=(cnt[j]==1);
		if (!flag)
		{
			puts("YES");
			return 0;
		}
	}
	puts("NO");
	return 0;
}


#include <stdio.h>
const int MAX = 2002;

int main (){
int i,j,n, m;
int a[MAX][MAX], c[MAX];

scanf("%d %d",&n, &m);
for (i=0;i<m;i++)
	c[i] = 0;

getchar();
for (i=0;i<n;i++){
	for (j=0;j<m;j++){
		char t;
		scanf("%c",&t);
		a[i][j] = t - '0';
		if (t == '1')
			c[j]++;
	}
	getchar();
}

for (i=0;i<n;i++){
	int ok = 1;
	for (j=0;j<m;j++)
		if(a[i][j] == 1 && c[j] == 1)
			ok = 0;
	if (ok){
		printf("YES\n");
		return 0;}
	 }

printf("NO\n");

return 0;
}


#include <stdio.h>
const int MAX = 2002;

int main (){
int i,j,n, m, sum = 0;
int a[MAX];
int sum_prev = sum;

scanf("%d %d",&n, &m);
for (i=0;i<m;i++)
	a[i] = 0;

getchar();
for (i=0;i<n;i++){
	sum_prev = sum;
	for (j=0;j<m;j++){
		char t;
		scanf("%c",&t);
		if (t == '1' && a[j] == 0){
			a[j] = 1;
			sum++;
			}
	}
	getchar();
	if (sum == sum_prev)
		break;
	}

if (sum == sum_prev)
	printf("YES\n");
else
	printf("NO\n");

return 0;
}


#include <stdio.h>
const int MAX = 2002;

int main (){
int i,j,n, m;
char a[MAX][MAX];
int c[MAX];

scanf("%d %d",&n, &m);
for (i=0;i<m;i++)
	c[i] = 0;

getchar();
for (i=0;i<n;i++){
	for (j=0;j<m;j++){
		scanf("%c",&a[i][j]);
		if (a[i][j]  == '1')
			c[j]++;
	}
	getchar();
}

for (i=0;i<n;i++){
	int ok = 1;
	for (j=0;j<m;j++)
		if(a[i][j] == '1' && c[j] == 1)
			ok = 0;
	if (ok){
		printf("YES\n");
		return 0;}
	 }

printf("NO\n");

return 0;
}


#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <malloc.h>
#include <memory.h>
int i,j,n,m,a[2005],f[2005],ff;
char s[2005][2005];

int main()
{
	memset(f,0,sizeof(f));
	scanf("%d %d",&n,&m);
	for (i=1;i<=n;i++) scanf("%s",s[i]);
	for (i=1;i<=n;i++)
	for (j=0;j<m;j++)
	if (s[i][j]=='1') f[j]++;
	for (i=1;i<=n;i++)
	{
		for (j=0;j<m;j++) a[j]=f[j];
		for (j=0;j<m;j++)
		if (s[i][j]=='1') a[j]--;
		for (j=0,ff=1;j<m;j++)
		if (a[j]<=0)
		{
			ff=0;
			break;
		}
		if (ff)
		{
			puts("YES");
			exit(0);
		}
	}
	puts("NO");
	return 0;
}


#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int main(void)
{
	int n,m,i,j,flag[2001],temp[2001],ans=0;
	for(i=0;i<=2000;i++)
	{
	temp[i]=-1;
	flag[i]=0;
	}
	scanf("%d %d",&n,&m);
	int a[n][m],waste[i],spr[i];
	for(i=0;i<n;i++)
	{
	waste[i]=0;
	spr[i]=0;
	}
	char s[2001];
	for(i=0;i<n;i++)
	{
			scanf("%s",s);
			for(j=0;j<m;j++)
			{
				a[i][j]=s[j]-'0';
			}
	}
	for(i=0;i<n;i++)
	for(j=0;j<m;j++)
	if(a[i][j]==1)
	spr[i]++;
	for(i=0;i<n;i++)
	{
		for(j=0;j<m;j++)
		{
			if(a[i][j]==1)
			{
			if(flag[j]==0)
			flag[j]=1;
			else
			waste[i]++;
			}
		}
	}
	for(i=0;i<n;i++)
	{
		if(waste[i]==spr[i])
		{
		ans=1;
		}
	else
	{
	ans=0;
	}
	}
	if(ans==1)
	printf("YES\n");
	else
	printf("NO\n");
	return 0;
}


#include<stdio.h>
int A[2000 + 10][2000 + 10] = { 0 };
int sum[2000 + 10] = { 0 };
int main()
{
//	freopen("input.txt", "r", stdin);
	int n;
	int m;
	scanf("%d %d", &n, &m);
	char c;
	int flag = 0;
	getchar();
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%c", &c);
			A[i][j] = c -'0';
		}
		getchar();
	}

	for (int j = 0; j < m; j++) {
		for (int i = 0; i < n; i++) {
			sum[j] += A[i][j];
		}
	}

	for (int i = 0; i < n; i++) {
		int f = 1;
		for (int j = 0; j < m; j++) {
			if (sum[j] - A[i][j] == 0) {
				f = 0;
				break;
			}
		}
		if (f == 1) {
			flag = 1;
			break;
		}
	}

	if (flag == 1)
		printf("YES\n");
	else
		printf("NO\n");
}


#include<stdio.h>
char A[2000 + 10][2000 + 10];
int sum[2000 + 10] = { 0 };
int main()
{
//	freopen("input.txt", "r", stdin);
	int n;
	int m;
	scanf("%d %d", &n, &m);
	char c;
	int flag = 0;
	getchar();
	for (int i = 0; i < n; i++) {
		scanf("%s", &A[i]);
		for (int j = 0; j < m; j++)
			sum[j] += A[i][j] - '0';
	}

	for (int i = 0; i < n; i++) {
		int f = 1;
		for (int j = 0; j < m; j++) {
			if (sum[j] - A[i][j] + '0'== 0) {
				f = 0;
				break;
			}
		}
		if (f == 1) {
			flag = 1;
			break;
		}
	}

	if (flag == 1)
		printf("YES\n");
	else
		printf("NO\n");
}


#include<stdio.h>
char A[2000 + 10][2000 + 10];
int sum[2000 + 10] = { 0 };
int main()
{
//	freopen("input.txt", "r", stdin);
	int n;
	int m;
	scanf("%d %d", &n, &m);
	char c;
	int flag = 0;
	getchar();
	for (int i = 0; i < n; i++) {
		scanf("%s", &A[i]);
	}

	for (int j = 0; j < m; j++) {
		for (int i = 0; i < n; i++) {
			sum[j] += A[i][j]-'0';
		}
	}

	for (int i = 0; i < n; i++) {
		int f = 1;
		for (int j = 0; j < m; j++) {
			if (sum[j] - A[i][j] + '0'== 0) {
				f = 0;
				break;
			}
		}
		if (f == 1) {
			flag = 1;
			break;
		}
	}

	if (flag == 1)
		printf("YES\n");
	else
		printf("NO\n");
}


#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>

/*int cmpfunc(const void *a ,const void *b)
{
    return *(int *)a - *(int *)b;
}*/
int main()
{
    int n,m,i,j,flag;
    scanf("%d %d",&n,&m);
    char str[m];
    int flag1[n+1][m+1],flag2[m+1];
    for(i=0;i<(n+1);i++)
    {
        for(j=0;j<(m+1);j++)
            flag1[i][j]=0;
    }
    for(i=0;i<(m+1);i++)
        flag2[i]=0;
    for(i=0;i<n;i++)
    {
        scanf("%s",str);
        for(j=0;j<m;j++)
        {
            if(str[j]=='1')
            {
                flag1[i+1][j+1]=1;
                flag2[j+1]+=1;
            }
        }
    }
    for(i=1;i<=n;i++)
    {
        flag=0;
        for(j=1;j<=m;j++)
        {
            if(flag1[i][j]==1&&flag2[j]==1)
                flag=1;
        }
        if(flag==0)
            break;
    }
    if(i==(n+1))
        printf("NO\n");
    else
        printf("YES\n");
    return 0;
}


#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>

/*int cmpfunc(const void *a ,const void *b)
{
    return *(int *)a - *(int *)b;
}*/
int main()
{
    int n,m,i,j;
    scanf("%d %d",&n,&m);
    char str[m];
    int flag1[n+1],flag2[m+1];
    for(i=0;i<(n+1);i++)
        flag1[i]=0;
    for(i=0;i<(m+1);i++)
        flag2[i]=0;
    for(i=0;i<n;i++)
    {
    //    printf("Yo\n");
        scanf("%s",str);
        for(j=0;j<m;j++)
        {
            if(str[j]=='1')
            {
                if(flag2[j+1]==0)
                    flag1[i+1]=1;
                flag2[j+1]=1;
            }
        }
    }
    for(i=1;i<=n;i++)
    {
        if(flag1[i]==0)
        {
            printf("YES\n");
            break;
        }
    }
    if(i==(n+1))
        printf("NO\n");
    return 0;
}


#include <stdio.h>
#include <stdbool.h>

static int _count[2000] = {};
static int _a[2000][2000] = {};
int main() {
    int N,M; scanf("%d %d\n", &N,&M);
    if(N == 1) { printf("NO\n"); return 0; }

    for(int i = 0 ; i < N ; ++i) for(int j = 0 ; j < M ; ++j) {
        char aij; scanf("%c ", &aij);
        _a[i][j] = aij - '0'; _count[j] += _a[i][j];
    }

    for(int i = 0 ; i < N ; ++i) { bool found = true;
        for(int j = 0 ; j < M && found ; ++j) {
            if(_a[i][j] == 1 && _count[j] < 2) found = false;
        }
        if(found) { printf("YES\n"); return 0; }
    }

    printf("NO\n");
    return 0;
}


#include <stdio.h>
#include <string.h>

#define N 2005

int a[N];
char s[N][N];

int main(int argc, char* argv[]) {
    int i, j, n, m, ok = 0;

    scanf("%d%d", &n, &m);
    getchar();
    for (i = 0; i < n; i++)
        gets(s[i]);

    memset(a, 0, sizeof a);
    for (j = 0; j < m; j++) {
        int cnt = 0;
        int id = -1;
        for (i = 0; i < n; i++)
            if (s[i][j] == '1') {
                cnt++;
                id = i;
            }
        if (cnt == 1)
            a[id] = 1;
    }

    for (i = 0; i < n; i++)
        if (a[i] == 0) {
            ok = 1;
            break;
        }

    puts(ok ? "YES" : "NO");

    return 0;
}


#include<stdio.h>

int main(void)
{
    int i,j,k,m,n,c,f;
    char a[2000][2000];
    scanf("%d%d",&n,&m);
//Here c means how many lamps can be on by just one switch

    for(i=0;i<n;i++)
        scanf("%s",a[i]);
    c=0;
    for(i=0;i<m;i++)
    {
        f=0;
        for(j=0;j<n;j++)
        {
            if(a[j][i]=='1') f++;

        }
        //printf("In col %d f=%d\n",i,f);
        if(f==1) c++;
    }
    //printf("c=%d\n",c);
    if(c<m) printf("YES");
    else printf("NO");

    return 0;

}