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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
using Debug = System.Diagnostics.Debug;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using Number = System.Int64;
namespace Program {
    public class Solver {
        Random rnd = new Random(0);

        public void Solve() {
            var n = ri;
            var a = Enumerate(n + 2, x => new int[n + 2]);
            for (int i = 0; i < n; i++) {
                var s = i == 0 ? "" : rs;
                for (int j = 0; j < i; j++) {
                    a[i + 1][j + 1] = s[j] - '0';
                    a[j + 1][i + 1] = 1 - a[i + 1][j + 1];
                }
            }
            /*
            n = 2000;
            a = Enumerate(n + 2, x => new int[n + 2]);
            for (int i = 1; i <= n; i++)
                for (int j = i + 1; j <= n; j++) {
                    var u = rnd.Next() % 2;
                    a[i][j] = u; a[j][i] = 1 - u;
                }
            */
            for (int i = 1; i <= n; i++) {
                a[i][0] = a[i][n + 1] = 1;
            }
            var lose = Enumerate(n + 2, x => new bitset());
            var adj = Enumerate(n + 2, x => new bitset());

            for (int i = 1; i <= n + 1; i++) {
                adj[i][i - 1] = true;
                lose[i][i - 1] = a[i][i - 1] == 0;
                for (int j = i - 1; j >= 1; j--) {
                    if (!adj[i][j]) continue;
                    if (a[i][j] == 0) lose[i][j] = true;
                    for (int k = 0; k < 32; k++) {
                        if (a[i][j] == 1)
                            adj[i].a[k] |= adj[j].a[k];
                        else adj[i].a[k] |= lose[j].a[k];
                    }
                }
            }
            var ans = 0;
            for (int i = 1; i <= n; i++)
                if (adj[i][0] && adj[n + 1][i]) ans++;
            Console.WriteLine(ans);

        }
        class bitset {
            public ulong[] a = new ulong[32];
            const int B = 64;
            public bool this[int index] {
                get { return (a[index / B] >> index & 1) == 1; }
                set {
                    if (value)
                        a[index / B] |= 1ul << index;
                    else a[index / B] &= ~(1ul << index);
                }
            }
        }



        const long INF = 1L << 60;
        int ri => sc.Integer();
        long rl => sc.Long();
        double rd => sc.Double();
        string rs => sc.Scan();
        public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

        static IEnumerable<int> Rep(int n) => Enumerable.Range(0, n);
        static IEnumerable<int> RRep(int n) => Enumerable.Range(0, n).Reverse();
        static T[] Enumerate<T>(int n, Func<int, T> f) {
            var a = new T[n];
            for (int i = 0; i < a.Length; ++i) a[i] = f(i);
            return a;
        }
        static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
    }
}

#region main
static class Ex {
    static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
    static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
        return string.Join(st, ie);
    }
    static public void Main() {
        Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
        var solver = new Program.Solver();
        solver.Solve();
        Console.Out.Flush();
    }
}
#endregion
#region Ex
namespace Program.IO {
    using System.IO;
    using System.Text;
    using System.Globalization;

    public class Printer : StreamWriter {
        public override IFormatProvider FormatProvider => CultureInfo.InvariantCulture;
        public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
    }

    public class StreamScanner {
        public StreamScanner(Stream stream) { str = stream; }

        public readonly Stream str;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        public bool isEof = false;

        private byte read() {
            if (isEof) return 0;
            if (ptr >= len) {
                ptr = 0;
                if ((len = str.Read(buf, 0, 1024)) <= 0) {
                    isEof = true;
                    return 0;
                }
            }
            return buf[ptr++];
        }

        public char Char() {
            byte b = 0;
            do b = read(); while ((b < 33 || 126 < b) && !isEof);
            return (char)b;
        }
        public string Scan() {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
            return sb.ToString();
        }
        public string ScanLine() {
            var sb = new StringBuilder();
            for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
            return sb.ToString();
        }
        public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
        public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
        public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
    }
}

#endregion