// 2005 ACM Mid-Central Regional Programming Contest
// Problem A: Pascal's Travels
// Posed by Jerry Cain, Stanford University
// Coded by Tim Rolfe, Eastern Washington University
// Hacked by the MidCentral judges to ensure input/output consistency
//   (Jerry had a nice, well-documented solution that looked aweful after
//    we got through with it, so we used Tim's.)

import java.io.*;

public class pascal
{
   static private boolean DEBUG = false;

   static public void main ( String[] args ) throws Exception
   {
      byte   moves[][];      // Step by moves[row][col]
      long   paths[][],      // Number of paths INTO this cell
             rtnVal;         // Value returned by badNews
      long   start, elapsed; // Timing within Java
      int    size, n;        // Loop on size, read it into n
      int    row, tstrow,    // tstrow is row + moves[row][col]
             col, tstcol;    // ditto
      BufferedReader inp = null;
      String filename = "pascal.in";       // Building the file names
      String line;           // Current line being decoded

         try
         {  inp = new BufferedReader(new FileReader(filename)); }
         catch (Exception e)
         {  System.out.println(e);  System.exit(-1);  }
         line = inp.readLine();
         n = Integer.parseInt(line);
        while (n > 0) 
      {

         moves = new byte[n][n];

         for ( row = 0; row < n; row++ )
         {
            // Next line in the board specification
            line = inp.readLine();
            for ( col = 0; col < n; col++ )
               moves[row][col] = (byte) ( line.charAt(col) - '0' );
         }

         paths = new long[n][n];
         paths[0][0] = 1;  // Enable starting from here.

         start = System.currentTimeMillis();
         for ( row = 0; row < n; row++ )
            for ( col = 0; col < n; col++ )
            {
               if ( moves[row][col] == 0 )     // I.e., no path exists
                  continue;
               tstrow = row + moves[row][col];
               tstcol = col + moves[row][col];
               if ( tstrow < n )               // I.e., is in-bounds
                  paths[tstrow][col] += paths[row][col];
               if ( tstcol < n )
                  paths[row][tstcol] += paths[row][col];
            } // end for
         elapsed = System.currentTimeMillis() - start;

         System.out.println (paths[n-1][n-1]);

 	 /*
         Calling the recursive solution takes a while on judge's data!
         start = System.currentTimeMillis();

         rtnVal = badNews(0, 0, n, moves);
         elapsed = System.currentTimeMillis() - start;
         System.out.print ("               ");
         System.out.println (rtnVal + " paths found, " +
                             elapsed + " msec.\n");
	 */

         System.out.flush();

         line = inp.readLine();
         n = Integer.parseInt(line);
         
      }
   } // end void main()

   // Recursive back-tracking solution.  Numbers all generated by adding
   // together just the 1 values returned by arriving at [n-1][n-1].
   static long badNews ( int row, int col, int n, byte[][]moves )
   {
      long current = 0;
      int  tstRow = row + moves[row][col],
           tstCol = col + moves[row][col];

      if ( DEBUG )
         System.out.println (row + ", " + col);

      if ( row == n-1 && col == n-1 )
      {
         if ( DEBUG )
            System.out.println ("FOUND IT");
         current = 1;
      }
      else
      {
         // watch out for sink holes (zeroes) in the grid
         if ( tstRow < n && tstRow != row)
            current += badNews ( tstRow, col, n, moves );
         if ( tstCol < n && tstCol != col)
            current += badNews ( row, tstCol, n, moves );
      } // end if/else
      return current;
   } // end long badNews()
}
