Problem:
Score : 1000 points

Problem Statement

We will host a rock-paper-scissors tournament with N people. The participants are called Person 1, Person 2, \ldots, Person N.
For any two participants, the result of the match between them is determined in advance.
This information is represented by positive integers A_{i,j} ( 1 \leq j < i \leq N ) as follows:

If A_{i,j} = 0, Person j defeats Person i.

If A_{i,j} = 1, Person i defeats Person j.

The tournament proceeds as follows:

We will arrange the N participants in a row, in the order Person 1, Person 2, \ldots, Person N from left to right.

We will randomly choose two consecutive persons in the row. They will play a match against each other, and we will remove the loser from the row.
We will repeat this process N-1 times, and the last person remaining will be declared the champion.

Find the number of persons with the possibility of becoming the champion.

Constraints

1 \leq N \leq 2000

A_{i,j} is 0 or 1.

Input

Input is given from Standard Input in the following format:

N
A_{2,1}
A_{3,1}A_{3,2}
:
A_{N,1}\ldotsA_{N,N-1}

Output

Print the number of persons with the possibility of becoming the champion.

Sample Input 1

3
0
10

Sample Output 1

2

Person 1 defeats Person 2, Person 2 defeats Person 3 and Person 3 defeats Person 1.
If Person 1 and Person 2 play the first match, Person 3 will become the champion.
If Person 2 and Person 3 play the first match, Person 1 will become the champion.

Sample Input 2

6
0
11
111
1111
11001

Sample Output 2

3

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

//By Tushar Gautam
#pragma GCC optimize ("-O2")
#include <bits/stdc++.h>
using namespace std;
#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define memreset(a) memset(a,0,sizeof(a))
#define testcase(t) int t;cin>>t;while(t--)
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i=0;i<e;++i)
#define forsn(i,s,e) for(int i=s;i<e;++i)
#define rforn(i,s) for(int i=s;i>=0;--i)
#define rforsn(i,s,e) for(int i=s;i>=e;--i)
#define bitcount(a) __builtin_popcount(a) // set bits (add ll)
#define ln '\n'
#define getcurrtime() cerr<<"Time = "<<((double)clock()/CLOCKS_PER_SEC)<<endl
#define dbgarr(v,s,e) cerr<<#v<<" = "; forsn(i,s,e) cerr<<v[i]<<", "; cerr<<endl
#define inputfile freopen("input.txt", "r", stdin)
#define outputfile freopen("output.txt", "w", stdout)
#define dbg(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
void err(istream_iterator<string> it) { cerr<<endl; }
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t"; err(++it, args...);
}
template<typename T1,typename T2>
ostream& operator <<(ostream& c,pair<T1,T2> &v){
	c<<"("<<v.fi<<","<<v.se<<")"; return c;
}
template <template <class...> class TT, class ...T>
ostream& operator<<(ostream& out,TT<T...>& c){
    out<<"{ ";
    forstl(x,c) out<<x<<" ";
    out<<"}"; return out;
}
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll,ll> p64;
typedef pair<int,int> p32;
typedef pair<int,p32> p96;
typedef vector<ll> v64;
typedef vector<int> v32; 
typedef vector<v32> vv32;
typedef vector<v64> vv64;
typedef vector<p32> vp32;
typedef vector<p64> vp64;
typedef vector<vp32> vvp32;
typedef map<int,int> m32;
const int LIM=1e5+5,MOD=1e9+7;
int t,n,m,k,x,y,w;
int mat[2005][2005];
//Push-Relabel Algorithm for Flows - Gap Heuristic, Complexity: O(V^3)
//To obtain the actual flow values, look at all edges with capacity > 0
//Zero capacity edges are residual edges
struct edge{
	int from, to, cap, flow, index;
	edge(int from, int to, int cap, int flow, int index):
		from(from), to(to), cap(cap), flow(flow), index(index) {}
};
struct PushRelabel{
	int n;
	vector<vector<edge> > g;
	vector<long long> excess;
	vector<int> height, active, count;
	queue<int> Q;
	PushRelabel(int n):
		n(n), g(n), excess(n), height(n), active(n), count(2*n) {}
	void addEdge(int from, int to, int cap){
		dbg(from,to);
		g[from].push_back(edge(from, to, cap, 0, g[to].size()));
		if(from==to)
			g[from].back().index++;
		g[to].push_back(edge(to, from, 0, 0, g[from].size()-1));
	}
	void enqueue(int v){
		if(!active[v] && excess[v] > 0)
		{
			active[v]=true;
			Q.push(v);
		}
	}
	void push(edge &e){
		int amt=(int)min(excess[e.from], (long long)e.cap - e.flow);
		if(height[e.from]<=height[e.to] || amt==0)
			return;
		e.flow += amt;
		g[e.to][e.index].flow -= amt;
		excess[e.to] += amt;
		excess[e.from] -= amt;
		enqueue(e.to);
	}
	void relabel(int v){
		count[height[v]]--;
		int d=2*n;
		for(auto &it:g[v]){
			if(it.cap-it.flow>0)
				d=min(d, height[it.to]+1);
		}
		height[v]=d;
		count[height[v]]++;
		enqueue(v);
	}
	void gap(int k){
		for(int v=0;v<n;v++){
			if(height[v]<k)
				continue;
			count[height[v]]--;
			height[v]=max(height[v], n+1);
			count[height[v]]++;
			enqueue(v);
		}
	}
	void discharge(int v){
		for(int i=0; excess[v]>0 && i<g[v].size(); i++)
			push(g[v][i]);
		if(excess[v]>0){
			if(count[height[v]]==1)
				gap(height[v]);
			else
				relabel(v);
		}
	}
	long long max_flow(int source, int dest){
		count[0] = n-1;
		count[n] = 1;
		height[source] = n;
		active[source] = active[dest] = 1;
		for(auto &it:g[source]){
			excess[source]+=it.cap;
			push(it);
		}
		while(!Q.empty()){
			int v=Q.front();
			Q.pop();
			active[v]=false;
			discharge(v);
		}
		long long max_flow=0;
		for(auto &e:g[source])
			max_flow+=e.flow;

		return max_flow;
	}
};
bool find(int x){
	int s=x,t=n;
	PushRelabel f(n+1);
	forn(i,n){
		forn(j,i){
			if(mat[i][j]){
				// dbg(i,j);
				if(j==x) continue;
				else f.addEdge(i,j,2005);
			}else{
				if(i==x) continue;
				else f.addEdge(j,i,2005);
			}
		}
		f.addEdge(i,t,1);
	}
	auto ans=f.max_flow(s,t);
	if(ans==n) return 1;
	else return 0;
}
signed main(){
	fastio;
	cin>>n;
	char ch;
	forn(i,n) forn(j,i) cin>>ch,mat[i][j]=ch=='1';
	int ans=0;
	forn(i,n) if(find(i)) ans++;
	cout<<ans<<ln;
	return 0;
}