using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Codeforces.R1360.E
{
    public static class Solver
    {
        public static void Main()
        {
            using (var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false })
            {
                Solve(Console.In, sw);
            }
        }

        public static void Solve(TextReader tr, TextWriter tw)
        {
            WriteAnswer(tw, Parse(tr));
        }

        private static void WriteAnswer(TextWriter tw, bool[] answers)
        {
            foreach (var answer in answers)
            {
                tw.WriteLine(answer ? "YES" : "NO");
            }
        }

        private static bool[] Parse(TextReader tr)
        {
            var t = int.Parse(tr.ReadLine());
            var res = new bool[t];

            for (int i = 0; i < t; ++i)
            {
                var n = int.Parse(tr.ReadLine());
                var board = new string[n];
                for (int j = 0; j < n; ++j)
                    board[j] = tr.ReadLine();
                res[i] = Calc(board);
            }
            return res;
        }

        public static bool Calc(string[] board)
        {
            for (int r = 0; r < board.Length - 1; ++r)
            {
                for (int c = 0; c < board[r].Length - 1; ++c)
                {
                    if (board[r][c] == '1' && board[r][c + 1] == '0' && board[r + 1][c] == '0')
                        return false;
                }
            }
            return true;
        }
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using CodeforcesRound644Div3.Extensions;
using CodeforcesRound644Div3.Questions;

namespace CodeforcesRound644Div3.Questions
{
    public class QuestionE : AtCoderQuestionBase
    {
        public override IEnumerable<object> Solve(TextReader inputStream)
        {
            var tests = inputStream.ReadInt();

            for (int t = 0; t < tests; t++)
            {
                var n = inputStream.ReadInt();
                var result = new int[n + 1][];
                for (int row = 0; row < n; row++)
                {
                    result[row] = inputStream.ReadLine().Select(c => c - '0').Concat(Enumerable.Repeat(1, 1)).ToArray();
                }
                result[n] = Enumerable.Repeat(1, n + 1).ToArray();

                yield return Check(result) ? "YES" : "NO";
            }
        }

        bool Check(int[][] result)
        {
            var n = result.Length - 1;
            for (int row = 0; row < n; row++)
            {
                for (int column = 0; column < n; column++)
                {
                    if (result[row][column] == 1 && result[row + 1][column] == 0 && result[row][column + 1] == 0)
                    {
                        return false;
                    }
                }
            }
            return true;
        }
    }
}

namespace CodeforcesRound644Div3
{
    class Program
    {
        static void Main(string[] args)
        {
            IAtCoderQuestion question = new QuestionE();
            var answers = question.Solve(Console.In);

            var writer = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            Console.SetOut(writer);
            foreach (var answer in answers)
            {
                Console.WriteLine(answer);
            }
            Console.Out.Flush();
        }
    }
}

#region Base Class

namespace CodeforcesRound644Div3.Questions
{

    public interface IAtCoderQuestion
    {
        IEnumerable<object> Solve(string input);
        IEnumerable<object> Solve(TextReader inputStream);
    }

    public abstract class AtCoderQuestionBase : IAtCoderQuestion
    {
        public IEnumerable<object> Solve(string input)
        {
            var stream = new MemoryStream(Encoding.Unicode.GetBytes(input));
            var reader = new StreamReader(stream, Encoding.Unicode);

            return Solve(reader);
        }

        public abstract IEnumerable<object> Solve(TextReader inputStream);
    }
}

#endregion

#region Extensions

namespace CodeforcesRound644Div3.Extensions
{
    internal static class TextReaderExtensions
    {
        internal static int ReadInt(this TextReader reader) => int.Parse(ReadString(reader));
        internal static long ReadLong(this TextReader reader) => long.Parse(ReadString(reader));
        internal static double ReadDouble(this TextReader reader) => double.Parse(ReadString(reader));
        internal static string ReadString(this TextReader reader) => reader.ReadLine();

        internal static int[] ReadIntArray(this TextReader reader, char separator = ' ') => ReadStringArray(reader, separator).Select(int.Parse).ToArray();
        internal static long[] ReadLongArray(this TextReader reader, char separator = ' ') => ReadStringArray(reader, separator).Select(long.Parse).ToArray();
        internal static double[] ReadDoubleArray(this TextReader reader, char separator = ' ') => ReadStringArray(reader, separator).Select(double.Parse).ToArray();
        internal static string[] ReadStringArray(this TextReader reader, char separator = ' ') => reader.ReadLine().Split(separator);

        // Supports primitive type only.
        internal static T1 ReadValue<T1>(this TextReader reader) => (T1)Convert.ChangeType(reader.ReadLine(), typeof(T1));

        internal static (T1, T2) ReadValue<T1, T2>(this TextReader reader, char separator = ' ')
        {
            var inputs = ReadStringArray(reader, separator);
            var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
            var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
            return (v1, v2);
        }

        internal static (T1, T2, T3) ReadValue<T1, T2, T3>(this TextReader reader, char separator = ' ')
        {
            var inputs = ReadStringArray(reader, separator);
            var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
            var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
            var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
            return (v1, v2, v3);
        }

        internal static (T1, T2, T3, T4) ReadValue<T1, T2, T3, T4>(this TextReader reader, char separator = ' ')
        {
            var inputs = ReadStringArray(reader, separator);
            var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
            var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
            var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
            var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
            return (v1, v2, v3, v4);
        }

        internal static (T1, T2, T3, T4, T5) ReadValue<T1, T2, T3, T4, T5>(this TextReader reader, char separator = ' ')
        {
            var inputs = ReadStringArray(reader, separator);
            var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
            var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
            var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
            var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
            var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
            return (v1, v2, v3, v4, v5);
        }

        internal static (T1, T2, T3, T4, T5, T6) ReadValue<T1, T2, T3, T4, T5, T6>(this TextReader reader, char separator = ' ')
        {
            var inputs = ReadStringArray(reader, separator);
            var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
            var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
            var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
            var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
            var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
            var v6 = (T6)Convert.ChangeType(inputs[5], typeof(T6));
            return (v1, v2, v3, v4, v5, v6);
        }

        internal static (T1, T2, T3, T4, T5, T6, T7) ReadValue<T1, T2, T3, T4, T5, T6, T7>(this TextReader reader, char separator = ' ')
        {
            var inputs = ReadStringArray(reader, separator);
            var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
            var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
            var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
            var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
            var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
            var v6 = (T6)Convert.ChangeType(inputs[5], typeof(T6));
            var v7 = (T7)Convert.ChangeType(inputs[6], typeof(T7));
            return (v1, v2, v3, v4, v5, v6, v7);
        }
    }
}

#endregion


using System;
using System.Linq;

public class Foo
{
    public static void Main()
    {
        int t = int.Parse(Console.ReadLine());
        for (int i = 0; i < t; i++)
        {
            int n = int.Parse(Console.ReadLine());
            var field = new int[n, n];
            for (int j = 0; j < n; j++)
            {
                int[] xx = Console.ReadLine().Select(x => x - '0').ToArray();
                for (int k = 0; k < n; k++)
                    field[j, k] = xx[k];
            }

            bool result = true;
            for (int j = 0; j < n-1; j++)
            {
                for (int k = 0; k < n-1; k++)
                    if (field[j, k] == 1 && field[j + 1, k] == 0 && field[j, k + 1] == 0)
                        result = false;
            }

            if (result)
                Console.WriteLine("YES");
            else
            {
                Console.WriteLine("NO");
            }
        }

    }
}


using System;
using System.Linq;

public class Foo
{
    public static void Main()
    {
        int t = int.Parse(Console.ReadLine());
        for (int i = 0; i < t; i++)
        {
            int n = int.Parse(Console.ReadLine());
            var field = new int[n, n];
            for (int j = 0; j < n; j++)
            {
                int[] xx = Console.ReadLine().Split().Select(int.Parse).ToArray();
                for (int k = 0; k < n; k++)
                    field[j, k] = xx[k];
            }

            bool result = true;
            for (int j = 0; j < n-1; j++)
            {
                for (int k = 0; k < n-1; k++)
                    if (field[j, k] == 1 && field[j + 1, k] == 0 && field[j, k + 1] == 0)
                        result = false;
            }

            if (result)
                Console.WriteLine("YES");
            else
            {
                Console.WriteLine("NO");
            }
        }

    }
}


use std::io::*;

// Input Impl {{{
struct Input {
    buf: Vec<String>,
}

impl Input {
    fn new() -> Self {
        Input { buf: Vec::new() }
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        if self.buf.is_empty() {
            self.buf = self
                .next_line()
                .split_whitespace()
                .rev()
                .map(String::from)
                .collect();
        }

        self.buf.pop().unwrap().parse().ok().expect("err")
    }

    fn next_line(&mut self) -> String {
        let mut line = String::new();
        stdin().read_line(&mut line).expect("read err");
        line
    }
}
// }}}

fn main() {
    let mut input = Input::new();
    let mut vals = [[false; 51]; 51];
    for _ in 0..input.next() {
        let n: usize = input.next();
        for i in 0..n {
            let line = input.next_line();
            let mut j = 0;
            for c in line.chars() {
                vals[i][j] = if c == '0' { false } else { true };
                j += 1;
            }
        }

        let mut okay = true;
        for i in 0..n - 1 {
            for j in 0..n - 1 {
                if vals[i][j] {
                    if !vals[i + 1][j] && !vals[i][j + 1] {
                        okay = false;
                    }
                }
            }
        }
        println!("{}", if okay { "YES" } else { "NO" });
    }
}


use std::io::*;

// Input Impl {{{
struct Input {
    buf: Vec<String>,
}

impl Input {
    fn new() -> Self {
        Input { buf: Vec::new() }
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        if self.buf.is_empty() {
            self.buf = self
                .next_line()
                .split_whitespace()
                .rev()
                .map(String::from)
                .collect();
        }

        self.buf.pop().unwrap().parse().ok().expect("err")
    }

    fn next_line(&mut self) -> String {
        let mut line = String::new();
        stdin().read_line(&mut line).expect("read err");
        line
    }
}
// }}}

fn main() {
    let mut input = Input::new();
    let mut vals = [[false; 60]; 60];
    for _ in 0..input.next() {
        let n: usize = input.next();
        for i in 0..n {
            let line = input.next_line();
            let mut j = 0;
            for c in line.chars() {
                vals[i][j] = if c == '0' { false } else { true };
                j += 1;
            }
        }

        let mut okay = true;
        for i in 0..n - 1 {
            for j in 0..n - 1 {
                if vals[i][j] {
                    if !vals[i + 1][j] && !vals[i][j + 1] {
                        okay = false;
                    }
                }
            }
        }
        println!("{}", if okay { "YES" } else { "NO" });
    }
}


use std::io::*;

// Input Impl {{{
struct Input {
    buf: Vec<String>,
}

impl Input {
    fn new() -> Self {
        Input { buf: Vec::new() }
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        if self.buf.is_empty() {
            self.buf = self
                .next_line()
                .split_whitespace()
                .rev()
                .map(String::from)
                .collect();
        }

        self.buf.pop().unwrap().parse().ok().expect("err")
    }

    fn next_line(&mut self) -> String {
        let mut line = String::new();
        stdin().read_line(&mut line).expect("read err");
        line
    }
}
// }}}

fn main() {
    let mut input = Input::new();
    for _ in 0..input.next() {
        let mut vals = [[false; 51]; 51];
        let n: usize = input.next();
        for i in 0..n {
            let line = input.next_line();
            let mut j = 0;
            for c in line.chars() {
                vals[i][j] = if c == '0' { false } else { true };
                j += 1;
            }
        }

        let mut okay = true;
        for i in 0..n - 1 {
            for j in 0..n - 1 {
                if vals[i][j] {
                    if !vals[i + 1][j] && !vals[i][j + 1] {
                        okay = false;
                    }
                }
            }
        }
        println!("{}", if okay { "YES" } else { "NO" });
    }
}


use std::io::*;

// Input Impl {{{
struct Input {
    buf: Vec<String>,
}

impl Input {
    fn new() -> Self {
        Input { buf: Vec::new() }
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        if self.buf.is_empty() {
            self.buf = self
                .next_line()
                .split_whitespace()
                .rev()
                .map(String::from)
                .collect();
        }

        self.buf.pop().unwrap().parse().ok().expect("err")
    }

    fn next_line(&mut self) -> String {
        let mut line = String::new();
        stdin().read_line(&mut line).expect("read err");
        line
    }
}
// }}}

fn main() {
    let mut input = Input::new();
    for _ in 0..input.next() {
        let mut vals = [[false; 60]; 60];
        let n: usize = input.next();
        for i in 0..n {
            let line = input.next_line();
            let mut j = 0;
            for c in line.chars() {
                vals[i][j] = if c == '0' { false } else { true };
                j += 1;
            }
        }

        let mut okay = true;
        for i in 0..n - 1 {
            for j in 0..n - 1 {
                if vals[i][j] {
                    if !vals[i + 1][j] && !vals[i][j + 1] {
                        okay = false;
                    }
                }
            }
        }
        println!("{}", if okay { "YES" } else { "NO" });
    }
}


use std::fmt::Debug;
use std::str::FromStr;

pub struct TokenReader {
    reader: std::io::Stdin,
    tokens: Vec<String>,
    index: usize,
}

impl TokenReader {
    pub fn new() -> Self {
        Self {
            reader: std::io::stdin(),
            tokens: Vec::new(),
            index: 0,
        }
    }

    pub fn next<T>(&mut self) -> T
    where
        T: FromStr,
        T::Err: Debug,
    {
        if self.index >= self.tokens.len() {
            self.load_next_line();
        }
        self.index += 1;
        self.tokens[self.index - 1].parse().unwrap()
    }

    pub fn vector<T>(&mut self) -> Vec<T>
    where
        T: FromStr,
        T::Err: Debug,
    {
        if self.index >= self.tokens.len() {
            self.load_next_line();
        }
        self.index = self.tokens.len();
        self.tokens.iter().map(|tok| tok.parse().unwrap()).collect()
    }

    pub fn load_next_line(&mut self) {
        let mut line = String::new();
        self.reader.read_line(&mut line).unwrap();

        self.tokens = line
            .split_whitespace()
            .map(|tok| tok.to_string())
            .collect::<Vec<String>>();
        self.index = 0;
    }
}

fn can_build(mat: &Vec<Vec<u8>>) -> bool {
    let n = mat.len();
    let has_backing = |i, j| -> bool {
        if i == n - 1 || j == n - 1 {
            return true;
        }

        let line_below: &Vec<u8> = &mat[i + 1];
        let line_right: &Vec<u8> = &mat[i];
        let below = line_below[j];
        let right = line_right[j + 1];
        below == '1' as u8 || right == '1' as u8
    };

    for i in 0..n as usize {
        for j in 0..n as usize {
            if mat[i][j] == '1' as u8 && !has_backing(i, j) {
                return false;
            }
        }
    }
    true
}

fn main() {
    let mut reader = TokenReader::new();
    let tests = reader.next::<i32>();

    for _ in 0..tests {
        let n = reader.next::<usize>();
        let mut mat = vec![vec![0; n]; n];
        for i in 0..n {
            mat[i] = reader.next::<String>().as_bytes().to_vec();
        }

        let valid = can_build(&mat);
        println!("{}", if valid { "YES" } else { "NO" });
    }
}


use std::io::*;
fn main() {
    let mut s: String = String::new();
    std::io::stdin().read_to_string(&mut s).ok();
    let mut itr = s.trim().split_whitespace();
    let t: usize = itr.next().unwrap().parse().unwrap();
    let mut out = Vec::new();
    for _ in 0..t {
        let n: usize = itr.next().unwrap().parse().unwrap();
        let grid: Vec<Vec<char>> = (0..n)
            .map(|_| itr.next().unwrap().chars().collect())
            .collect();

        let mut ok = true;
        for i in 0..n - 1 {
            for j in 0..n - 1 {
                if grid[i][j] == '1' {
                    if grid[i][j + 1] == '0' && grid[i + 1][j] == '0' {
                        ok = false;
                        break;
                    }
                }
            }
            if !ok {
                break;
            }
        }
        writeln!(out, "{}", if ok { "YES" } else { "NO" }).ok();
    }
    stdout().write_all(&out).unwrap();
}


#![allow(dead_code)]
#![allow(unused_imports)]

use std::cmp::*;
use std::collections::*;
use std::io;
use std::ops;
use std::str::FromStr;

#[derive(Clone, Debug, Default)]
struct ProblemState {
}

impl Problem {
    fn solve(&mut self) {
        let n: usize = self.scan();
        let a: Vec<String> = self.scan_line_vec(n);

        for i in 0..n {
            for j in 0..n {
                if a[i].as_bytes()[j] == '1' as u8 {
                    if i == n - 1 || j == n - 1 {
                        continue;
                    }

                    if a[i + 1].as_bytes()[j] == '1' as u8 || a[i].as_bytes()[j + 1] == '1' as u8 {
                        continue;
                    }

                    println!("NO");
                    return;
                }
            }
        }

        println!("YES");
    }
}

fn main() {
    Problem::new().solve_cases();
}

struct Problem {
    input_state: InputState,
    problem_state: ProblemState,
}

struct InputState {
    stdin: io::Stdin,
    buffer: String,
    tokens: VecDeque<String>,
}

impl Problem {
    fn new() -> Self {
        Self {
            input_state: InputState {
                stdin: io::stdin(),
                buffer: String::new(),
                tokens: VecDeque::new(),
            },
            problem_state: Default::default(),
        }
    }

    fn solve_cases(&mut self) {
        for _ in 0usize..self.scan() {
            self.solve()
        }
    }

    fn scan<T: FromStr>(&mut self) -> T {
        while self.input_state.tokens.is_empty() {
            self.input_state.stdin.read_line(&mut self.input_state.buffer).unwrap();

            for token in self.input_state.buffer.split_ascii_whitespace() {
                self.input_state.tokens.push_back(token.to_string());
            }

            self.input_state.buffer.clear();
        }

        self.input_state.tokens.pop_front().unwrap().parse().ok().unwrap()
    }

    fn scan_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).into_iter().map(|_| self.scan()).collect()
    }

    fn scan_line(&mut self) -> String {
        let mut line = String::new();
        self.input_state.stdin.read_line(&mut line).unwrap();
        while line.ends_with('\n') || line.ends_with('\r') { line.pop(); }
        line
    }

    fn scan_line_vec(&mut self, n: usize) -> Vec<String> {
        (0..n).into_iter().map(|_| self.scan_line()).collect()
    }
}

impl ops::Deref for Problem {
    type Target = ProblemState;

    fn deref(&self) -> &ProblemState {
        &self.problem_state
    }
}

impl ops::DerefMut for Problem {
    fn deref_mut(&mut self) -> &mut ProblemState {
        &mut self.problem_state
    }
}


#[allow(unused_imports)]
use std::cmp::{min, max};
use std::io::{BufWriter, stdin, stdout, Write};

#[derive(Default)]
struct Scanner {
  buf: Vec<String>
}

impl Scanner {
  fn next<T: std::str::FromStr>(&mut self) -> T {
    loop {
      if let Some(token) = self.buf.pop() {
        return token.parse().ok().expect("Failed parse");
      }
      let mut input = String::new();
      stdin().read_line(&mut input).expect("Failed read");
      self.buf = input.split_whitespace().rev().map(String::from).collect();
    }
  }

  fn next_chars(&mut self) -> Vec<char> {
    self.next::<String>().chars().collect()
  }
}

fn main() {
  let mut scan = Scanner::default();
  let tests: usize = scan.next();
  for _ in 0..tests {
    let n: usize = scan.next();
    let mtx: Vec<Vec<char>> = (0..n).map(|_| scan.next_chars()).collect();
    let mut flag = true;
    for i in (0..n) {
      for j in (0..n) {
        if mtx[i][j] == '1' {
          if !(i == n-1 || j == n-1 || mtx[i+1][j] == '1' || mtx[i][j+1] == '1') {
            flag = false;
          }
        }
      }
    }
    if flag {
      println!("YES");
    } else {
      println!("NO");
    }
  }
}


use std::cmp::*;
use std::collections::*;
use std::f64::consts::PI;
use std::io::*;
use std::str::*;
use std::string::*;

macro_rules! read {
    (($($t:tt),*)) => {
        ( $(read!($t)),* )
    };
    ([[$t:tt; $len1:expr]; $len2:expr]) => {
        (0..$len2).map(|_| read!([$t; $len1])).collect::<Vec<_>>()
    };

    ([$t:tt; $len:expr]) => {
        (0..$len).map(|_| read!($t)).collect::<Vec<_>>()
    };

    (chars) => {
        read!(String).chars().collect::<Vec<char>>()
    };

    (usize1) => {
        read!(usize) - 1
    };

    ($t:ty) => {{
        let stdin = stdin();
        let stdin = stdin.lock();
        let token: String = stdin
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect();

        token.parse::<$t>().unwrap()
    }};
}

macro_rules! input {
    (mut $name:ident: $t:tt, $($r:tt)*) => {
        let mut $name = read!($t);
        input!($($r)*);
    };

    (mut $name:ident: $t:tt) => {
        let mut $name = read!($t);
    };

    ($name:ident: $t:tt, $($r:tt)*) => {
        let $name = read!($t);
        input!($($r)*);
    };

    ($name:ident: $t:tt) => {
        let $name = read!($t);
    };
}

macro_rules! min {
    ($a:expr $(,)*) => {{
        $a
    }};
    ($a:expr, $b:expr $(,)*) => {{
        std::cmp::min($a, $b)
    }};
    ($a:expr, $($rest:expr),+ $(,)*) => {{
        std::cmp::min($a, min!($($rest),+))
    }};
}

macro_rules! chmin {
    ($base:expr, $($cmps:expr),+ $(,)*) => {{
        let cmp_min = min!($($cmps),+);
        if $base > cmp_min {
            $base = cmp_min;
            true
        } else {
            false
        }
    }};
}

macro_rules! max {
    ($a:expr $(,)*) => {{
        $a
    }};
    ($a:expr, $b:expr $(,)*) => {{
        std::cmp::max($a, $b)
    }};
    ($a:expr, $($rest:expr),+ $(,)*) => {{
        std::cmp::max($a, max!($($rest),+))
    }};
}

macro_rules! chmax {
    ($base:expr, $($cmps:expr),+ $(,)*) => {{
        let cmp_max = max!($($cmps),+);
        if $base < cmp_max {
            $base = cmp_max;
            true
        } else {
            false
        }
    }};
}

#[derive(Eq, PartialEq, Clone, Debug)]
pub struct Rev<T>(pub T);

impl<T: PartialOrd> PartialOrd for Rev<T> {
    fn partial_cmp(&self, other: &Rev<T>) -> Option<std::cmp::Ordering> {
        other.0.partial_cmp(&self.0)
    }
}

impl<T: Ord> Ord for Rev<T> {
    fn cmp(&self, other: &Rev<T>) -> std::cmp::Ordering {
        other.0.cmp(&self.0)
    }
}

struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        IO(r, std::io::BufWriter::new(w))
    }

    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.to_string().as_bytes()).unwrap();
    }

    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let s: String = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect();

        return s.parse::<T>().ok().unwrap();
    }

    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }

    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}

fn prime_factorization(n: i64) -> HashMap<i64, i64> {
    let mut n = n;
    let mut res = HashMap::new();
    let mut i = 2;
    while i * i <= n {
        while n % i == 0 {
            n /= i;
            let count = res.entry(i).or_insert(0);
            *count += 1;
        }
        i += 1;
    }

    if n > 1 {
        res.insert(n, 1);
    }

    return res;
}

//
// struct Combination {
//     MOD: i64,
//     fac: Vec<i64>,
//     fac_inv: Vec<i64>,
// }
//
// impl Combination {
//     pub fn new(n: i64) -> Self {
//         let MOD: i64 = 1_000_000_007;
//         let mut fac: Vec<i64> = vec![0; n as usize + 1];
//         let mut fac_inv: Vec<i64> = vec![0; n as usize + 1];
//
//         let get_inverse = |mut n: i64| -> i64 {
//             let (mut res, mut p) = (1, MOD - 2);
//
//             while p != 0 {
//                 if p & 1 == 1 {
//                     res = (res * n) % MOD;
//                 }
//                 n = (n * n) % MOD;
//                 p >>= 1;
//             }
//
//             return res;
//         };
//
//         fac[0] = 1;
//
//         for i in 1..n + 1 {
//             fac[i as usize] = (fac[i as usize - 1] * i) % MOD;
//         }
//
//         for i in 0..n + 1 {
//             fac_inv[i as usize] = get_inverse(fac[i as usize]);
//         }
//
//         Combination {
//             MOD: MOD,
//             fac: fac,
//             fac_inv: fac_inv,
//         }
//     }
//
//     fn nCr(&self, n: i64, r: i64) -> i64 {
//         if n < r {
//             return 0;
//         }
//
//         let a: i64 = self.fac[n as usize];
//         let b: i64 = self.fac_inv[(n - r) as usize];
//         let c: i64 = self.fac_inv[r as usize];
//         let bc: i64 = (b * c) % self.MOD;
//
//         return (a * bc) % self.MOD;
//     }
//
//     fn nPr(&self, n: i64, r: i64) -> i64 {
//         if n < r {
//             return 0;
//         }
//
//         let a: i64 = self.fac[n as usize];
//         let b: i64 = self.fac_inv[(n - r) as usize];
//
//         return (a * b) % self.MOD;
//     }
//
//     fn nHr(&self, n: i64, r: i64) -> i64 {
//         if n == 0 && r == 0 {
//             return 1;
//         }
//
//         return self.nCr(n + r - 1, r);
//     }
// }

#[derive(Copy, Clone, Eq, PartialEq)]
struct Edge {
    to: usize,
    cost: i64,
}

fn dijkstra(graph: &Vec<Vec<Edge>>, s: &usize) -> Vec<i64> {
    use std::collections::BinaryHeap;
    let mut dist = vec![1e18 as i64; graph.len()];
    let mut heap = BinaryHeap::new();
    dist[*s] = 0;
    heap.push(Rev((0, *s)));
    while let Some(Rev((cost, v))) = heap.pop() {
        if dist[v] < cost {
            continue;
        }

        for e in &graph[v] {
            if dist[e.to] <= dist[v] + e.cost {
                continue;
            }
            dist[e.to] = dist[v] + e.cost;
            heap.push(Rev((dist[e.to], e.to)));
        }
    }
    return dist;
}

struct LCA {
    par: Vec<Vec<Option<usize>>>,
    dist: Vec<i64>,
}

impl LCA {
    pub fn new(graph: &Vec<Vec<usize>>, root: usize) -> LCA {
        let V = graph.len();
        let mut K = 1;

        while (1 << K) < V {
            K += 1;
        }

        let mut par = vec![vec![None; V]; K];
        let mut dist = vec![-1; V];
        let graph = graph.to_vec();

        fn dfs(
            v: usize,
            p: Option<usize>,
            d: i64,
            graph: &Vec<Vec<usize>>,
            par: &mut Vec<Vec<Option<usize>>>,
            dist: &mut Vec<i64>,
        ) {
            par[0][v] = p;
            dist[v] = d;
            for &to in &graph[v] {
                match p {
                    Some(p) => {
                        if to != p {
                            dfs(to, Some(v), d + 1, graph, par, dist)
                        }
                    }
                    None => dfs(to, Some(v), d + 1, graph, par, dist),
                }
            }
        }

        dfs(root, None, 0, &graph, &mut par, &mut dist);

        for k in 0..K - 1 {
            for v in 0..V {
                match par[k][v] {
                    Some(x) => par[k + 1][v] = par[k][x],
                    None => (),
                }
            }
        }

        LCA {
            par: par,
            dist: dist,
        }
    }

    pub fn query(&self, u: usize, v: usize) -> usize {
        let mut u = u;
        let mut v = v;
        if self.dist[u] < self.dist[v] {
            return self.query(v, u);
        }

        let K = self.par.len();
        for k in 0..K {
            if ((self.dist[u] - self.dist[v]) >> k & 1) == 1 {
                u = self.par[k][u].unwrap();
            }
        }

        if u == v {
            return u;
        }

        for k in (0..K - 1).rev() {
            if self.par[k][u] != self.par[k][v] {
                u = self.par[k][u].unwrap();
                v = self.par[k][v].unwrap();
            }
        }

        return self.par[0][u].unwrap();
    }
}

struct Doubling {
    N: usize,
    LOG: usize,
    next: Vec<Vec<Option<usize>>>,
}

impl Doubling {
    pub fn new(vec: &Vec<usize>, lim: &usize) -> Doubling {
        let N = vec.len();
        let lim = *lim;
        let mut LOG = 1;
        while (1 << LOG) < 2 * lim {
            LOG += 1;
        }

        let mut next = vec![vec![None; N]; LOG];

        for i in 0..N {
            next[0][i] = Some(vec[i]);
        }

        for k in 0..LOG - 1 {
            for i in 0..N {
                match next[k][i] {
                    Some(x) => next[k + 1][i] = next[k][x],
                    None => (),
                }
            }
        }

        Doubling {
            N: N,
            LOG: LOG,
            next: next,
        }
    }

    pub fn query(&self, i: usize, n: usize) -> usize {
        let mut i = i;
        for k in (0..self.LOG).rev() {
            if (n >> k) & 1 == 1 {
                i = self.next[k][i].unwrap();
            }
        }
        return i;
    }
}

struct UnionFind {
    par: Vec<i32>,
}

impl UnionFind {
    pub fn new(n: usize) -> UnionFind {
        UnionFind { par: vec![-1; n] }
    }

    pub fn root(&mut self, x: usize) -> usize {
        if self.par[x] < 0 {
            return x;
        } else {
            let a = self.par[x] as usize;
            self.par[x] = self.root(a) as i32;
            return self.par[x] as usize;
        }
    }

    pub fn is_same(&mut self, x: usize, y: usize) -> bool {
        self.root(x) == self.root(y)
    }

    pub fn merge(&mut self, x: usize, y: usize) -> bool {
        let mut x = self.root(x);
        let mut y = self.root(y);
        if x == y {
            return false;
        } else {
            if self.par[x] > self.par[y] {
                std::mem::swap(&mut x, &mut y);
            }
            self.par[x] += self.par[y];
            self.par[y] = x as i32;
            return true;
        }
    }

    pub fn size(&mut self, x: usize) -> i64 {
        let a = self.root(x);
        return -self.par[a] as i64;
    }
}

trait Monoid {
    fn id() -> Self;
    fn op(&self, rhs: &Self) -> Self;
}

#[derive(Clone, Debug)]
struct Min(i64);

#[derive(Clone, Debug)]
struct RangeUpdate(i64);

#[derive(Clone, Debug)]
struct RangeAdd(i64);

#[derive(Clone, Debug)]
struct Sum(i64);

impl Monoid for Sum {
    fn id() -> Self {
        Sum(0)
    }

    fn op(&self, rhs: &Self) -> Self {
        Sum(self.0 + rhs.0)
    }
}

impl Monoid for Min {
    fn id() -> Self {
        Min(std::i32::MAX as i64)
    }

    fn op(&self, rhs: &Self) -> Self {
        Min(std::cmp::min(self.0, (*rhs).0))
    }
}

trait Operator {
    type T;
    fn id() -> Self;
    fn op(&self, rhs: &Self) -> Self;
    fn act(&self, tar: &Self::T, x: usize) -> Self::T;
}

impl Operator for RangeUpdate {
    type T = Min;
    fn id() -> Self {
        RangeUpdate(0)
    }

    fn op(&self, rhs: &Self) -> Self {
        (*rhs).clone()
    }

    fn act(&self, tar: &Self::T, x: usize) -> Self::T {
        Min(self.0)
    }
}

impl Operator for RangeAdd {
    type T = Sum;
    fn id() -> Self {
        RangeAdd(0)
    }

    fn op(&self, rhs: &Self) -> Self {
        RangeAdd(self.0 + rhs.0)
    }

    // Sum(tar.0 + self.0 * x as i64)
    fn act(&self, tar: &Self::T, x: usize) -> Self::T {
        Sum(tar.0 + self.0 * x as i64)
    }
}

struct LazySegTree<M: Monoid, O: Operator<T=M>> {
    dat: Vec<M>,
    lzy: Vec<O>,
    need_update: Vec<bool>,
    size: usize,
}

impl<M: Monoid + Clone, O: Operator<T=M> + Clone> LazySegTree<M, O> {
    pub fn new(vec: Vec<M>) -> LazySegTree<M, O> {
        let n = vec.len();
        let mut sz = 1;
        while sz < n {
            sz <<= 1;
        }
        let mut dat = vec![M::id(); sz << 1];
        for i in 0..n {
            dat[i + sz] = vec[i].clone();
        }
        for k in (1..sz).rev() {
            dat[k] = dat[k << 1].op(&dat[(k << 1) + 1]);
        }

        return LazySegTree {
            dat: dat,
            lzy: vec![O::id(); sz << 1],
            need_update: vec![false; sz << 1],
            size: sz,
        };
    }

    pub fn eval(&mut self, l: usize, r: usize, k: usize) {
        if !self.need_update[k] {
            return;
        }
        self.dat[k] = self.lzy[k].act(&self.dat[k], r - l);
        if (k << 1) < self.dat.len() {
            self.lzy[k << 1] = self.lzy[k << 1].op(&self.lzy[k]);
            self.lzy[(k << 1) + 1] = self.lzy[(k << 1) + 1].op(&self.lzy[k]);
            self.need_update[k << 1] = true;
            self.need_update[(k << 1) + 1] = true;
        }
        self.lzy[k] = O::id();
        self.need_update[k] = false;
    }

    pub fn update(&mut self, a: usize, b: usize, x: O) {
        let sz = self.size;
        self._update(a, b, &x, 0, sz, 1);
    }

    pub fn _update(&mut self, a: usize, b: usize, x: &O, l: usize, r: usize, k: usize) {
        self.eval(l, r, k);
        if b <= l || r <= a {
            return;
        } else if a <= l && r <= b {
            self.lzy[k] = self.lzy[k].op(x);
            self.need_update[k] = true;
            self.eval(l, r, k);
        } else {
            let mid = (l + r) >> 1;
            self._update(a, b, x, l, mid, k << 1);
            self._update(a, b, x, mid, r, (k << 1) + 1);
            self.dat[k] = self.dat[k << 1].op(&self.dat[(k << 1) + 1]);
        }
    }

    pub fn query(&mut self, a: usize, b: usize) -> M {
        let sz = self.size;
        return self._query(a, b, 0, sz, 1);
    }

    pub fn _query(&mut self, a: usize, b: usize, l: usize, r: usize, k: usize) -> M {
        self.eval(l, r, k);
        if b <= l || r <= a {
            return M::id();
        } else if a <= l && r <= b {
            return self.dat[k].clone();
        } else {
            let mid = (l + r) >> 1;
            let vl = self._query(a, b, l, mid, k << 1);
            let vr = self._query(a, b, mid, r, (k << 1) + 1);
            return vl.op(&vr);
        }
    }
}

struct SegTree<M: Monoid> {
    dat: Vec<M>,
    size: usize,
}

impl<M: Monoid + Clone> SegTree<M> {
    pub fn new(n: usize) -> SegTree<M> {
        let mut sz = 1;
        while sz < n {
            sz <<= 1;
        }

        SegTree::<M> {
            dat: vec![M::id(); sz * 2],
            size: sz,
        }
    }

    pub fn update(&mut self, k: usize, val: M) {
        let mut k = k + self.size;
        self.dat[k] = val;
        while k > 0 {
            k = k >> 1;
            self.dat[k] = self.dat[k << 1].op(&self.dat[(k << 1) + 1]);
        }
    }

    pub fn query(&self, a: usize, b: usize) -> M {
        let mut lx = M::id();
        let mut rx = M::id();
        let mut l = a + self.size;
        let mut r = b + self.size;
        while l < r {
            if (l & 1) == 1 {
                lx = lx.op(&self.dat[l]);
                l += 1;
            }

            if (r & 1) == 1 {
                r -= 1;
                rx = self.dat[r].op(&rx);
            }

            l >>= 1;
            r >>= 1;
        }

        return lx.op(&rx);
    }
}

fn decode(v: Vec<char>) -> Vec<(char, usize)> {
    let mut res = Vec::new();
    let mut now = v[0];
    let mut cnt = 1;

    for i in 1..v.len() {
        if v[i] == now {
            cnt += 1;
        } else {
            res.push((now, cnt));
            cnt = 1;
            now = v[i];
        }
    }
    res.push((now, cnt));

    return res;
}

use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};

type Num = usize;

#[derive(Clone, Copy)]
pub struct ModInt<T: Copy + Clone>(pub T);

impl Add<ModInt<Num>> for ModInt<Num> {
    type Output = ModInt<Num>;
    fn add(self, rhs: ModInt<Num>) -> ModInt<Num> {
        self + rhs.0
    }
}

impl Add<Num> for ModInt<Num> {
    type Output = ModInt<Num>;
    fn add(self, mut rhs: Num) -> ModInt<Num> {
        if rhs >= MOD {
            rhs %= MOD;
        }
        let mut t = rhs + self.0;
        if t >= MOD {
            t = t - MOD;
        }
        ModInt(t)
    }
}

impl Sub<Num> for ModInt<Num> {
    type Output = ModInt<Num>;
    fn sub(self, rhs: Num) -> ModInt<Num> {
        let rhs = if rhs >= MOD { rhs % MOD } else { rhs };
        let value = if self.0 < rhs { self.0 + MOD } else { self.0 };
        ModInt(value - rhs)
    }
}

impl Sub<ModInt<Num>> for ModInt<Num> {
    type Output = ModInt<Num>;
    fn sub(self, rhs: ModInt<Num>) -> ModInt<Num> {
        self - rhs.0
    }
}

impl AddAssign<Num> for ModInt<Num> {
    fn add_assign(&mut self, other: Num) {
        *self = *self + other;
    }
}

impl AddAssign<ModInt<Num>> for ModInt<Num> {
    fn add_assign(&mut self, other: ModInt<Num>) {
        *self = *self + other;
    }
}

impl SubAssign<Num> for ModInt<Num> {
    fn sub_assign(&mut self, other: Num) {
        *self = *self - other;
    }
}

impl SubAssign<ModInt<Num>> for ModInt<Num> {
    fn sub_assign(&mut self, other: ModInt<Num>) {
        *self = *self - other;
    }
}

impl Div<Num> for ModInt<Num> {
    type Output = ModInt<Num>;
    fn div(self, mut rhs: Num) -> ModInt<Num> {
        if rhs >= MOD {
            rhs %= MOD;
        }
        self * ModInt(rhs).pow(MOD - 2)
    }
}

impl Div<ModInt<Num>> for ModInt<Num> {
    type Output = ModInt<Num>;
    fn div(self, rhs: ModInt<Num>) -> ModInt<Num> {
        self / rhs.0
    }
}

impl DivAssign<Num> for ModInt<Num> {
    fn div_assign(&mut self, rhs: Num) {
        *self = *self / rhs
    }
}

impl DivAssign<ModInt<Num>> for ModInt<Num> {
    fn div_assign(&mut self, rhs: ModInt<Num>) {
        *self = *self / rhs
    }
}

impl Mul<ModInt<Num>> for ModInt<Num> {
    type Output = ModInt<Num>;

    fn mul(self, rhs: ModInt<Num>) -> ModInt<Num> {
        self * rhs.0
    }
}

impl Mul<Num> for ModInt<Num> {
    type Output = ModInt<Num>;

    fn mul(self, mut rhs: Num) -> ModInt<Num> {
        if rhs >= MOD {
            rhs %= MOD;
        }
        let t = (self.0 * rhs) % MOD;
        ModInt(t)
    }
}

impl MulAssign<Num> for ModInt<Num> {
    fn mul_assign(&mut self, rhs: Num) {
        *self = *self * rhs;
    }
}

impl MulAssign<ModInt<Num>> for ModInt<Num> {
    fn mul_assign(&mut self, rhs: ModInt<Num>) {
        *self = *self * rhs;
    }
}

impl ModInt<Num> {
    pub fn pow(self, e: Num) -> ModInt<Num> {
        let mut result = ModInt(1);
        let mut cur = self;
        let mut e = e;
        while e > 0 {
            if e & 1 == 1 {
                result *= cur;
            }
            e >>= 1;
            cur *= cur;
        }
        result
    }
}

const MOD: usize = 1e9 as usize + 7;

fn solve() {
    input! {
        n: usize,
        a: [chars; n]
    }

    let m = n;

    let mut v = vec![vec![false; m]; n];
    for i in 0..n {
        for j in 0..m {
            if a[i][j] as u8 - '0' as u8 == 1 {
                v[i][j] = true;
            } else {
                v[i][j] = false;
            }
        }
    }

    let mut flag = true;

    for i in (0..n - 1).rev() {
        for j in (0..n - 1).rev() {
            if v[i][j] && !v[i + 1][j] && !v[i][j + 1] {
                flag = false;
            }
        }
    }

    println!("{}", if flag { "YES" } else { "NO" });
}

fn main() {
    input! {
        t: usize
    }

    for _ in 0..t {
        solve();
    }
}


#![allow(unused_imports)]
#![allow(non_snake_case, unused)]

use std::cmp::*;
use std::collections::*;
use std::ops::*;

// https://atcoder.jp/contests/hokudai-hitachi2019-1/submissions/10518254

macro_rules! eprint {
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = write!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! eprintln {
	() => { eprintln!(""); };
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = writeln!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! dbg {
	($v:expr) => {{
		let val = $v;
		eprintln!("[{}:{}] {} = {:?}", file!(), line!(), stringify!($v), val);
		val
	}}
}

macro_rules! mat {
	($($e:expr),*) => { Vec::from(vec![$($e),*]) };
	($($e:expr,)*) => { Vec::from(vec![$($e),*]) };
	($e:expr; $d:expr) => { Vec::from(vec![$e; $d]) };
	($e:expr; $d:expr $(; $ds:expr)+) => { Vec::from(vec![mat![$e $(; $ds)*]; $d]) };
}

macro_rules! ok {
	($a:ident$([$i:expr])*.$f:ident()$(@$t:ident)*) => {
		$a$([$i])*.$f($($t),*)
	};
	($a:ident$([$i:expr])*.$f:ident($e:expr$(,$es:expr)*)$(@$t:ident)*) => { {
		let t = $e;
		ok!($a$([$i])*.$f($($es),*)$(@$t)*@t)
	} };
}

pub fn readln() -> String {
	let mut line = String::new();
	::std::io::stdin().read_line(&mut line).unwrap_or_else(|e| panic!("{}", e));
	line
}

macro_rules! read {
	($($t:tt),*; $n:expr) => {{
		let stdin = ::std::io::stdin();
		let ret = ::std::io::BufRead::lines(stdin.lock()).take($n).map(|line| {
			let line = line.unwrap();
			let mut it = line.split_whitespace();
			_read!(it; $($t),*)
		}).collect::<Vec<_>>();
		ret
	}};
	($($t:tt),*) => {{
		let line = readln();
		let mut it = line.split_whitespace();
		_read!(it; $($t),*)
	}};
}

macro_rules! _read {
	($it:ident; [char]) => {
		_read!($it; String).chars().collect::<Vec<_>>()
	};
	($it:ident; [u8]) => {
		Vec::from(_read!($it; String).into_bytes())
	};
	($it:ident; usize1) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1
	};
	($it:ident; [usize1]) => {
		$it.map(|s| s.parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1).collect::<Vec<_>>()
	};
	($it:ident; [$t:ty]) => {
		$it.map(|s| s.parse::<$t>().unwrap_or_else(|e| panic!("{}", e))).collect::<Vec<_>>()
	};
	($it:ident; $t:ty) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<$t>().unwrap_or_else(|e| panic!("{}", e))
	};
	($it:ident; $($t:tt),+) => {
		($(_read!($it; $t)),*)
	};
}

pub fn main() {
	let _ = ::std::thread::Builder::new().name("run".to_string()).stack_size(32 * 1024 * 1024).spawn(run).unwrap().join();
}

const MOD: i64 = 1_000_000_007;
const INF: i64 = std::i64::MAX/3;

fn solve() {
    let t = read!(usize);
    for i in 0..t {
        let n = read!(usize);
        let b = read!(String;n);
        let mut board = vec![vec![0;n];n];
        for x in 0..n {
            for (y,c) in b[x].chars().enumerate() {
                board[x][y] = c as u8 - '0' as u8;
            }
        }
        for x in 0..n {
            for y in 0..n {
                if board[x][y]==0 {
                    continue;
                }
                if x!=n-1 && y!=n-1 {
                    continue;
                }
                let mut q = VecDeque::new();
                q.push_back((x,y));
                while let Some((cx,cy)) = q.pop_front() {
                    board[cx][cy] = 0;
                    for (dx,dy) in [(-1,0),(0,-1)].iter() {
                        let nx = cx as i64 + dx;
                        let ny = cy as i64 + dy;
                        if nx<0 || nx>=n as i64 || ny<0 || ny>=n as i64 {
                            continue;
                        }
                        if board[nx as usize][ny as usize]==0 {
                            continue;
                        }
                        q.push_back((nx as usize,ny as usize));
                        board[nx as usize][ny as usize] = 0;
                    }
                }
            }
        }
        let mut flag = true;
        for x in 0..n {
            for y in 0..n {
                if board[x][y]==1 {
                    flag = false;
                }
            }
        }
        match flag {
            true => println!("YES"),
            false => println!("NO"),
        };
    }
}

fn run() {
    solve();
}


#![allow(unused_imports)]
#![allow(non_snake_case, unused)]

use std::cmp::*;
use std::collections::*;
use std::ops::*;

// https://atcoder.jp/contests/hokudai-hitachi2019-1/submissions/10518254

macro_rules! eprint {
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = write!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! eprintln {
	() => { eprintln!(""); };
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = writeln!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! dbg {
	($v:expr) => {{
		let val = $v;
		eprintln!("[{}:{}] {} = {:?}", file!(), line!(), stringify!($v), val);
		val
	}}
}

macro_rules! mat {
	($($e:expr),*) => { Vec::from(vec![$($e),*]) };
	($($e:expr,)*) => { Vec::from(vec![$($e),*]) };
	($e:expr; $d:expr) => { Vec::from(vec![$e; $d]) };
	($e:expr; $d:expr $(; $ds:expr)+) => { Vec::from(vec![mat![$e $(; $ds)*]; $d]) };
}

macro_rules! ok {
	($a:ident$([$i:expr])*.$f:ident()$(@$t:ident)*) => {
		$a$([$i])*.$f($($t),*)
	};
	($a:ident$([$i:expr])*.$f:ident($e:expr$(,$es:expr)*)$(@$t:ident)*) => { {
		let t = $e;
		ok!($a$([$i])*.$f($($es),*)$(@$t)*@t)
	} };
}

pub fn readln() -> String {
	let mut line = String::new();
	::std::io::stdin().read_line(&mut line).unwrap_or_else(|e| panic!("{}", e));
	line
}

macro_rules! read {
	($($t:tt),*; $n:expr) => {{
		let stdin = ::std::io::stdin();
		let ret = ::std::io::BufRead::lines(stdin.lock()).take($n).map(|line| {
			let line = line.unwrap();
			let mut it = line.split_whitespace();
			_read!(it; $($t),*)
		}).collect::<Vec<_>>();
		ret
	}};
	($($t:tt),*) => {{
		let line = readln();
		let mut it = line.split_whitespace();
		_read!(it; $($t),*)
	}};
}

macro_rules! _read {
	($it:ident; [char]) => {
		_read!($it; String).chars().collect::<Vec<_>>()
	};
	($it:ident; [u8]) => {
		Vec::from(_read!($it; String).into_bytes())
	};
	($it:ident; usize1) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1
	};
	($it:ident; [usize1]) => {
		$it.map(|s| s.parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1).collect::<Vec<_>>()
	};
	($it:ident; [$t:ty]) => {
		$it.map(|s| s.parse::<$t>().unwrap_or_else(|e| panic!("{}", e))).collect::<Vec<_>>()
	};
	($it:ident; $t:ty) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<$t>().unwrap_or_else(|e| panic!("{}", e))
	};
	($it:ident; $($t:tt),+) => {
		($(_read!($it; $t)),*)
	};
}

pub fn main() {
	let _ = ::std::thread::Builder::new().name("run".to_string()).stack_size(32 * 1024 * 1024).spawn(run).unwrap().join();
}

const MOD: i64 = 1_000_000_007;
const INF: i64 = std::i64::MAX/3;

fn solve() {
    let t = read!(usize);
    for i in 0..t {
        let n = read!(usize);
        let b = read!(String;n);
        let mut board = vec![vec![0;n];n];
        for x in 0..n {
            for (y,c) in b[x].chars().enumerate() {
                board[x][y] = c as u8 - '0' as u8;
            }
        }
        for x in 0..n {
            for y in 0..n {
                if board[x][y]==0 {
                    continue;
                }
                if x!=n-1 && y!=n-1 {
                    continue;
                }
                let mut q = VecDeque::new();
                q.push_back((x,y));
                while let Some((cx,cy)) = q.pop_front() {
                    board[cx][cy] = 0;
                    for (dx,dy) in [(-1,0),(0,-1)].iter() {
                        let nx = cx as i64 + dx;
                        let ny = cy as i64 + dy;
                        if nx<0 || nx>=n as i64 || ny<0 || ny>=n as i64 {
                            continue;
                        }
                        if board[nx as usize][ny as usize]==0 {
                            continue;
                        }
                        q.push_back((nx as usize,ny as usize));
                    }
                }
            }
        }
        let mut flag = true;
        for x in 0..n {
            for y in 0..n {
                if board[x][y]==1 {
                    flag = false;
                }
            }
        }
        match flag {
            true => println!("YES"),
            false => println!("NO"),
        };
    }
}

fn run() {
    solve();
}


#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(dead_code)]

use std::char::*;
use std::cmp::*;
use std::collections::*;
use std::io::*;
use std::str::FromStr;

macro_rules! debug {($($a:expr),*) => {println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);}}
macro_rules! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; let mut next = || { iter . next ( ) . unwrap ( ) } ; input_inner ! { next , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let mut bytes = std :: io :: Read :: bytes ( std :: io :: BufReader :: new ( stdin . lock ( ) ) ) ; let mut next = move || -> String { bytes . by_ref ( ) . map ( | r | r . unwrap ( ) as char ) . skip_while ( | c | c . is_whitespace ( ) ) . take_while ( | c |! c . is_whitespace ( ) ) . collect ( ) } ; input_inner ! { next , $ ( $ r ) * } } ; }
macro_rules! input_inner { ( $ next : expr ) => { } ; ( $ next : expr , ) => { } ; ( $ next : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ next , $ t ) ; input_inner ! { $ next $ ( $ r ) * } } ; }
macro_rules! read_value { ( $ next : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ next , $ t ) ) ,* ) } ; ( $ next : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ next , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ next : expr , chars ) => { read_value ! ( $ next , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ next : expr , usize1 ) => { read_value ! ( $ next , usize ) - 1 } ; ( $ next : expr , $ t : ty ) => { $ next ( ) . parse ::<$ t > ( ) . expect ( "Parse error" ) } ; }

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

use std::f64;

fn min<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { a }
    else { b }
}

fn max<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { b }
    else { a }
}

use std::hash::Hash;
fn inc<T: Hash+Ord>(map:&mut BTreeMap<T,i64>, key:T) {
    let count = map.entry(key).or_insert(0);
    *count += 1;
}

fn digit(ch: char) -> i64 {
    return (ch as u8 - b'0') as i64
}

const MAX:usize = 30;
const INF:i64 = std::i64::MAX;
const MOD:i64 = 1e9 as i64 + 7;

fn main() {
    let t:usize = read();

    'outer: for _ in 0..t {
        let n:usize = read();
        let c:Vec<Vec<char>> = (0..n).map(|_| read::<String>().chars().collect()).collect();
        //debug!(c);

        for i in 0..n {
            for j in 0..n {
                if c[i][j] == '0' { continue; }
                let mut f1 = false;
                let mut f2 = false;
                // 下
                if i==n-1 {
                    f1 = true;
                } else {
                    if c[i+1][j] == '1' {
                        f1 = true;
                    }
                }
                // 右
                if j==n-1 {
                    f2 = true;
                } else {
                    if c[i][j+1] == '1' {
                        f2 = true;
                    }
                }
                if !f1 && !f2 {
                    println!("NO");
                    continue 'outer;
                }
            }
        }
        println!("YES");
    }

}

/*

*/


// ---------- begin scannner ----------
#[allow(dead_code)]
mod scanner {
    use std::str::FromStr;
    use std::str::SplitWhitespace;
    use std::io::Read;
    use std;
    pub struct Scanner<'a> {
        it: SplitWhitespace<'a>
    }
    impl<'a> Scanner<'a> {
        pub fn new(s: &'a String) -> Scanner<'a> {
            Scanner {
                it: s.split_whitespace()
            }
        }
        pub fn next<T: FromStr>(&mut self) -> T {
            match self.it.next().unwrap().parse::<T>() {
                Ok(v) => v,
                _ => panic!("Scanner error")
            }
        }
        pub fn next_chars(&mut self) -> Vec<char> {
            self.next::<String>().chars().collect()
        }
    }
    pub fn read_string() -> String {
        let mut s = String::new();
        std::io::stdin().read_to_string(&mut s).unwrap();
        s
    }
}
// ---------- end scannner ----------

use std::io::Write;

fn main() {
    let sc = scanner::read_string();
    let mut sc = scanner::Scanner::new(&sc);
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());
    run(&mut sc, &mut out);
}

fn run(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<std::io::StdoutLock>) {
    let t: usize = sc.next();
    for _ in 0..t {
        let n: usize = sc.next();
        let s: Vec<Vec<char>> = (0..n).map(|_| sc.next_chars()).collect();
        let mut ok = true;
        for i in 0..(2 * n - 1) {
            for j in 0..=i {
                let (x, y) = (i - j, j);
                if x < n && y < n && s[x][y] == '1' {
                    let mut valid = false;
                    valid |= x == n - 1;
                    valid |= y == n - 1;
                    if x + 1 < n && s[x + 1][y] == '1' {
                        valid = true;
                    }
                    if y + 1 < n && s[x][y + 1] == '1' {
                        valid = true;
                    }
                    ok &= valid;
                }
            }
        }
        let ans = if ok {
            "YES"
        } else {
            "NO"
        };
        writeln!(out, "{}", ans).ok();
    }
}


#![allow(unused_imports)]

use std::cmp::{max, min};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
use std::io::stdin;
use std::str::FromStr;

fn main() {
    for _testcase in 0..input() {
        solve();
    }
}

fn solve() {
    let n: usize = input();
    let s: Vec<Vec<u8>> = input_lines::<String>(n)
        .into_iter()
        .map(|x| {
            x.chars()
                .map(|x| x.to_string().parse::<u8>().unwrap())
                .collect()
        })
        .collect();

    // dbg!(&s);

    let mut ans = "YES";
    for i in 0..n-1 {
        for j in 0..n-1 {
            if s[i][j] == 1 && (s[i+1][j] == 0 && s[i][j+1] == 0) {
                ans = "NO";
                break;
            }
        }
    }
    println!("{}", ans);
}

pub fn input<T: FromStr>() -> T {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim().parse().ok().unwrap()
}

pub fn input_vec<T: FromStr>() -> Vec<T> {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim()
        .split_whitespace()
        .map(|x| x.parse().ok().unwrap())
        .collect::<Vec<_>>()
}

pub fn input_lines<T: FromStr>(l: usize) -> Vec<T> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input());
    }
    res
}

pub fn input_lines_two<T: FromStr, U: FromStr>(l: usize) -> Vec<(T, U)> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input_two());
    }
    res
}

pub fn input_lines_three<T: FromStr, U: FromStr, V: FromStr>(l: usize) -> Vec<(T, U, V)> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input_three());
    }
    res
}

pub fn input_two<T: FromStr, U: FromStr>() -> (T, U) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse::<T>().ok().unwrap(),
        s[1].parse::<U>().ok().unwrap(),
    )
}

pub fn input_three<T: FromStr, U: FromStr, V: FromStr>() -> (T, U, V) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse::<T>().ok().unwrap(),
        s[1].parse::<U>().ok().unwrap(),
        s[2].parse::<V>().ok().unwrap(),
    )
}

pub fn input_four<T: FromStr, U: FromStr, V: FromStr, W: FromStr>() -> (T, U, V, W) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse().ok().unwrap(),
        s[1].parse().ok().unwrap(),
        s[2].parse().ok().unwrap(),
        s[3].parse().ok().unwrap(),
    )
}


#![allow(dead_code, unused_imports)]

use std::fmt::Debug;
use std::str::FromStr;

fn read_stdin() -> String {
    let mut s = String::new();
    std::io::stdin()
        .read_line(&mut s)
        .expect("cannot read stdin");
    s.trim().to_string()
}

fn read<T>() -> T
where
    T: std::str::FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Debug,
{
    read_stdin().parse::<T>().unwrap()
}

fn read_usize() -> usize {
    read::<usize>()
}

fn read_2<A, B>() -> (A, B)
where
    A: std::str::FromStr,
    <A as std::str::FromStr>::Err: std::fmt::Debug,
    B: std::str::FromStr,
    <B as std::str::FromStr>::Err: std::fmt::Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    (a, b)
}

fn read_3<A, B, C>() -> (A, B, C)
where
    A: std::str::FromStr,
    <A as std::str::FromStr>::Err: std::fmt::Debug,
    B: std::str::FromStr,
    <B as std::str::FromStr>::Err: std::fmt::Debug,
    C: std::str::FromStr,
    <C as std::str::FromStr>::Err: std::fmt::Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    (a, b, c)
}

fn read_multiple<T: FromStr>() -> Vec<T>
where
    <T as std::str::FromStr>::Err: Debug,
{
    read_stdin()
        .split_whitespace()
        .map(|x| x.parse::<T>().expect("cannot parse stdin"))
        .collect()
}

fn count<T>(iter: &mut impl Iterator<Item = T>) -> Vec<(T, usize)>
where
    T: std::cmp::Ord,
{
    let mut iter = iter.collect::<Vec<_>>();
    iter.sort();
    let (mut v, o, c) =
        iter.into_iter()
            .fold((Vec::new(), None, 0), |(mut v, last, count), item| {
                if let Some(o) = last {
                    if item == o {
                        (v, Some(o), count + 1)
                    } else {
                        v.push((o, count));
                        (v, Some(item), 1)
                    }
                } else {
                    (v, Some(item), 1)
                }
            });
    if let Some(i) = o {
        v.push((i, c));
    }
    v
}

fn max_subarray(v: impl Iterator<Item = i64>) -> (i64, (usize, usize)) {
    //assert!(v.len() > 0);
    let mut best_sum = 0;
    let (mut best_start, mut best_end) = (0, 0);
    let mut current_sum = 0;
    let mut current_start = 0;
    for (end, val) in v.enumerate() {
        if current_sum <= 0 {
            current_start = end;
            current_sum = val;
        } else {
            current_sum += val;
        }
        if current_sum > best_sum {
            best_sum = current_sum;
            best_start = current_start;
            best_end = end + 1;
        }
    }
    (best_sum, (best_start, best_end))
}

fn gcd(a: u64, b: u64) -> u64 {
    let mut a = a;
    let mut b = b;
    while a != b {
        if a > b {
            a = a - b
        } else {
            b = b - a
        }
    }
    a
}

fn factorize(mut n: u64) -> Vec<u64> {
    if n <= 3 {
        return vec![n];
    }
    let mut v = Vec::new();
    while n % 2 == 0 {
        n /= 2;
        v.push(2);
    }
    while n % 3 == 0 {
        n /= 3;
        v.push(3);
    }
    let mut f = 6;
    while (f - 1) * (f - 1) <= n {
        while n % (f - 1) == 0 {
            n /= f - 1;
            v.push(f - 1);
        }
        while n % (f + 1) == 0 {
            n /= f + 1;
            v.push(f + 1);
        }
        f += 6;
    }
    v
}

fn factors(n: u64) -> Vec<u64> {
    let factors = factorize(n);
    factors
}

use std::collections::VecDeque;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    for _ in 0..read_usize() {
        /*let (n, k) = read_2::<u64, u64>();
        println!("{} {}", n, k);
        for f in factorize(n).iter().rev() {
            if n / f <= k {
                println!("{}", f);
                break;
            }
        }*/
        let n = read_usize();
        let mut p = Vec::new();
        for _ in 0..n {
            p.push(read_stdin().chars().collect::<Vec<_>>());
        }
        let mut good = true;
        'outer: for i in 0..n - 1 {
            for j in 0..n - 1 {
                if p[i][j] == '1' {
                    if p[i][j + 1] == '0' && p[i + 1][j] == '0' {
                        good = false;
                        break 'outer;
                    }
                }
            }
        }
        if good {
            println!("YES")
        } else {
            println!("NO")
        }
    }
    Ok(())
}


macro_rules! parse_line {
    ($t: ty) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let a_str = a_str.trim();
        a_str.parse::<$t>().expect("parse error")
    });
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let mut a_iter = a_str.split_whitespace();
        (
            $(
            a_iter.next().unwrap().parse::<$t>().expect("parse error"),
            )+
        )
    })
}

#[allow(unused_macros)]
macro_rules! parse_line_to_vec {
    ($t: ty) => {{
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        (a_str
            .split_whitespace()
            .map(|x| x.parse::<$t>().unwrap())
            .collect::<Vec<$t>>())
    }};
}

use std::io::Write;

fn solve(writer: &mut std::io::BufWriter<std::io::Stdout>) {
    let n = parse_line!(usize);
    let field: Vec<Vec<u8>> = (0..n).map(|_| parse_line!(String).bytes().collect()).collect();
    let mut ok = true;
    for i in 0..n - 1 {
        for j in 0..n - 1 {
            ok &= field[i][j] == b'0' || field[i + 1][j] == b'1' || field[i][j + 1] == b'1';
        }
    }
    if ok {
        writeln!(writer, "YES").unwrap();
    }else{
        writeln!(writer, "NO").unwrap();
    }
}

fn main() {
    let tests = parse_line!(usize);
    let mut writer = std::io::BufWriter::new(std::io::stdout());
    for _ in 0..tests {
        solve(&mut writer);
    }
}


/*
    date   : 2020 / 5 / 5
    author : quickn (quickn.ga)
    email  : quickwshell@gmail.com
*/

use std::io::{self, BufWriter, Write};

mod scanner {
    use std::{io, str};
    /* https://github.com/EbTech/rust-algorithms */

    /// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts
    /// **REQUIRES** Rust 1.34 or higher
    pub struct UnsafeScanner<R> {
        reader: R,
        buf_str: Vec<u8>,
        buf_iter: str::SplitAsciiWhitespace<'static>,
    }

    impl<R: io::BufRead> UnsafeScanner<R> {
        pub fn new(reader: R) -> Self {
            Self {
                reader,
                buf_str: Vec::new(),
                buf_iter: "".split_ascii_whitespace(),
            }
        }

        /// This function should be marked unsafe, but noone has time for that in a
        /// programming contest. Use at your own risk!
        pub fn token<T: str::FromStr>(&mut self) -> T {
            loop {
                if let Some(token) = self.buf_iter.next() {
                    return token.parse().ok().expect("Failed parse");
                }
                self.buf_str.clear();
                self.reader
                    .read_until(b'\n', &mut self.buf_str)
                    .expect("Failed read");
                self.buf_iter = unsafe {
                    let slice = str::from_utf8_unchecked(&self.buf_str);
                    std::mem::transmute(slice.split_ascii_whitespace())
                }
            }
        }
    }
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let (mut scan, mut sout) = (
        scanner::UnsafeScanner::new(stdin.lock()),
        BufWriter::new(stdout.lock()),
    );
    let t: usize = scan.token();
    for _i in 0..t {
        let n: usize = scan.token();
        let mut arr: Vec<Vec<bool>> = vec![vec![false;n];n];
        for i in 0..n {
            let s: String = scan.token();
            let s_chars: Vec<char> = s.chars().collect();
            for j in 0..n {
                match s_chars[j] {
                    '0' => {arr[i][j] = false;},
                     _ => {arr[i][j] = true;},
                }
            }
        }
        let mut failed = false;
        for i in 0..(n-1) {
            for j in 0..(n-1) {
                if arr[i][j] == true {
                    if arr[i+1][j] != true && arr[i][j+1] != true {
                        failed = true;
                        break;
                    }
                }
            }
            if failed { break; }
        }
        if failed {
            writeln!(sout, "NO").ok();
        } else {
            writeln!(sout, "YES").ok();
        }
    }
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, [ $t:tt ]) => {{
        let len = read_value!($next, usize);
        (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    }};

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused)]
macro_rules! debug {
    ($($format:tt)*) => (write!(std::io::stderr(), $($format)*).unwrap());
}
#[allow(unused)]
macro_rules! debugln {
    ($($format:tt)*) => (writeln!(std::io::stderr(), $($format)*).unwrap());
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (let _ = write!(out,$($format)*););
    }
    input! {
        s: [[chars]],
    }
    for s in s {
        let n = s.len();
        let mut ok = true;
        for i in (0..n - 1).rev() {
            for j in (0..n - 1).rev() {
                // Is it possible to place 1 on (i, j)?
                if s[i][j] != '1' { continue; }
                if s[i][j + 1] == '0' && s[i + 1][j] == '0' {
                    ok = false;
                }
            }
        }
        puts!("{}\n", if ok { "YES" } else { "NO" });
    }
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}


//! https://github.com/hatoo/competitive-rust-snippets
//!
//! MIT License
//!
//! Copyright (c) 2018 hatoo
//!
//! Permission is hereby granted, free of charge, to any person obtaining a copy
//! of this software and associated documentation files (the "Software"), to deal
//! in the Software without restriction, including without limitation the rights
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//! copies of the Software, and to permit persons to whom the Software is
//! furnished to do so, subject to the following conditions:
//!
//! The above copyright notice and this permission notice shall be included in all
//! copies or substantial portions of the Software.
//!
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//! SOFTWARE.
#![allow(
    unused_imports,
    unused_attributes,
    unused_macros,
    dead_code,
    non_snake_case
)]
use std::cmp::{max, min, Ordering};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::io::{stdin, stdout, BufWriter, Write};
use std::iter::FromIterator;
#[macro_export]
macro_rules !get {(@inner [$src :expr ] chars ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .chars () .collect ::<Vec <char >>() } } ;(@inner [$src :expr ] usize1 ) =>{{get !(@inner [$src ] usize ) -1 } } ;(@inner [$src :expr ] [usize1 ] ) =>{{get !(@inner [$src ] [usize ] ) .into_iter () .map (|v |v -1 ) .collect ::<Vec <usize >>() } } ;(@inner [$src :expr ] [[usize1 ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [usize1 ] ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [usize1 ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [usize1 ] ) ) .flatten () .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [[chars ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] chars ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [chars ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] chars ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [($($tt :tt ) ,*) ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] ($($tt ) ,*) ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] ($($tt :tt ) ,*) ) =>{{let mut buf :String =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;let mut iter =buf .split_whitespace () ;($(get !(@inner_elem_parse [$tt ] iter .next () .unwrap () ) ,) *) } } ;(@inner [$src :expr ] [$t :ty ] ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .split_whitespace () .map (|t |t .parse ::<$t >() .unwrap () ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [[$t :ty ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [$t ] ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [$t :ty ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [$t ] ) ) .flatten () .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] $t :ty ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .split_whitespace () .next () .unwrap () .parse ::<$t >() .unwrap () } } ;(@inner_elem_parse [usize1 ] $elem :expr ) =>{{get !(@inner_elem_parse [usize ] $elem ) -1 } } ;(@inner_elem_parse [$t :ty ] $elem :expr ) =>{{$elem .parse ::<$t >() .unwrap () } } ;($tt :tt ) =>{{use std ::io ::BufRead ;let get_stdin =std ::io ::stdin () ;let mut locked_stdin =get_stdin .lock () ;get !(@inner [&mut locked_stdin ] $tt ) } } ;}
macro_rules !debug {($($a :expr ) ,*$(,) *) =>{#[cfg (debug_assertions ) ] eprintln !(concat !($("| " ,stringify !($a ) ,"={:?} " ) ,*,"|" ) ,$(&$a ) ,*) ;} ;}
macro_rules !echo {($($a :expr ) ,*) =>{let mut s =Vec ::new () ;$(s .push (format !("{}" ,$a ) ) ;) *println !("{}" ,s .join (" " ) ) ;} }
#[macro_export]
macro_rules !chmin {($base :expr ,$($cmps :expr ) ,+$(,) *) =>{{let cmp_min =min !($($cmps ) ,+) ;if $base >cmp_min {$base =cmp_min ;true } else {false } } } ;}
#[macro_export]
macro_rules !chmax {($base :expr ,$($cmps :expr ) ,+$(,) *) =>{{let cmp_max =max !($($cmps ) ,+) ;if $base <cmp_max {$base =cmp_max ;true } else {false } } } ;}
#[macro_export]
macro_rules !min {($a :expr $(,) *) =>{{$a } } ;($a :expr ,$b :expr $(,) *) =>{{std ::cmp ::min ($a ,$b ) } } ;($a :expr ,$($rest :expr ) ,+$(,) *) =>{{std ::cmp ::min ($a ,min !($($rest ) ,+) ) } } ;}
#[macro_export]
macro_rules !max {($a :expr $(,) *) =>{{$a } } ;($a :expr ,$b :expr $(,) *) =>{{std ::cmp ::max ($a ,$b ) } } ;($a :expr ,$($rest :expr ) ,+$(,) *) =>{{std ::cmp ::max ($a ,max !($($rest ) ,+) ) } } ;}
const BIG_STACK_SIZE: bool = true;
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let t = get!(usize);
    'test: for _ in 0..t {
        let n = get!(usize);
        let mut mat = get!([[chars]; n]);
        for row in 0..mat.len() {
            let mut ok = true;
            for col in (0..mat[0].len()).rev() {
                let cur = mat[row][col];
                if ok && cur == '1' {
                    mat[row][col] = '*';
                    continue;
                }
                if cur == '0' {
                    ok = false;
                    continue;
                }
            }
        }
        for col in 0..n {
            let mut ok = true;
            for row in (0..n).rev() {
                let cur = mat[row][col];
                if cur == '*' {
                    ok = true;
                    continue;
                }
                if ok && cur == '1' {
                    mat[row][col] = '*';
                    continue;
                }
                if ok && cur == '0' {
                    ok = false;
                    continue;
                }
                if !ok && cur == '1' {
                    echo!("NO");
                    continue 'test;
                }
            }
        }

        echo!("YES");
    }
}


//! https://github.com/hatoo/competitive-rust-snippets
//!
//! MIT License
//!
//! Copyright (c) 2018 hatoo
//!
//! Permission is hereby granted, free of charge, to any person obtaining a copy
//! of this software and associated documentation files (the "Software"), to deal
//! in the Software without restriction, including without limitation the rights
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//! copies of the Software, and to permit persons to whom the Software is
//! furnished to do so, subject to the following conditions:
//!
//! The above copyright notice and this permission notice shall be included in all
//! copies or substantial portions of the Software.
//!
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//! SOFTWARE.
#![allow(
    unused_imports,
    unused_attributes,
    unused_macros,
    dead_code,
    non_snake_case
)]
use std::cmp::{max, min, Ordering};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::io::{stdin, stdout, BufWriter, Write};
use std::iter::FromIterator;
#[macro_export]
macro_rules !get {(@inner [$src :expr ] chars ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .chars () .collect ::<Vec <char >>() } } ;(@inner [$src :expr ] usize1 ) =>{{get !(@inner [$src ] usize ) -1 } } ;(@inner [$src :expr ] [usize1 ] ) =>{{get !(@inner [$src ] [usize ] ) .into_iter () .map (|v |v -1 ) .collect ::<Vec <usize >>() } } ;(@inner [$src :expr ] [[usize1 ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [usize1 ] ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [usize1 ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [usize1 ] ) ) .flatten () .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [[chars ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] chars ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [chars ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] chars ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [($($tt :tt ) ,*) ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] ($($tt ) ,*) ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] ($($tt :tt ) ,*) ) =>{{let mut buf :String =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;let mut iter =buf .split_whitespace () ;($(get !(@inner_elem_parse [$tt ] iter .next () .unwrap () ) ,) *) } } ;(@inner [$src :expr ] [$t :ty ] ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .split_whitespace () .map (|t |t .parse ::<$t >() .unwrap () ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [[$t :ty ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [$t ] ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [$t :ty ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [$t ] ) ) .flatten () .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] $t :ty ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .split_whitespace () .next () .unwrap () .parse ::<$t >() .unwrap () } } ;(@inner_elem_parse [usize1 ] $elem :expr ) =>{{get !(@inner_elem_parse [usize ] $elem ) -1 } } ;(@inner_elem_parse [$t :ty ] $elem :expr ) =>{{$elem .parse ::<$t >() .unwrap () } } ;($tt :tt ) =>{{use std ::io ::BufRead ;let get_stdin =std ::io ::stdin () ;let mut locked_stdin =get_stdin .lock () ;get !(@inner [&mut locked_stdin ] $tt ) } } ;}
macro_rules !debug {($($a :expr ) ,*$(,) *) =>{#[cfg (debug_assertions ) ] eprintln !(concat !($("| " ,stringify !($a ) ,"={:?} " ) ,*,"|" ) ,$(&$a ) ,*) ;} ;}
macro_rules !echo {($($a :expr ) ,*) =>{let mut s =Vec ::new () ;$(s .push (format !("{}" ,$a ) ) ;) *println !("{}" ,s .join (" " ) ) ;} }
#[macro_export]
macro_rules !chmin {($base :expr ,$($cmps :expr ) ,+$(,) *) =>{{let cmp_min =min !($($cmps ) ,+) ;if $base >cmp_min {$base =cmp_min ;true } else {false } } } ;}
#[macro_export]
macro_rules !chmax {($base :expr ,$($cmps :expr ) ,+$(,) *) =>{{let cmp_max =max !($($cmps ) ,+) ;if $base <cmp_max {$base =cmp_max ;true } else {false } } } ;}
#[macro_export]
macro_rules !min {($a :expr $(,) *) =>{{$a } } ;($a :expr ,$b :expr $(,) *) =>{{std ::cmp ::min ($a ,$b ) } } ;($a :expr ,$($rest :expr ) ,+$(,) *) =>{{std ::cmp ::min ($a ,min !($($rest ) ,+) ) } } ;}
#[macro_export]
macro_rules !max {($a :expr $(,) *) =>{{$a } } ;($a :expr ,$b :expr $(,) *) =>{{std ::cmp ::max ($a ,$b ) } } ;($a :expr ,$($rest :expr ) ,+$(,) *) =>{{std ::cmp ::max ($a ,max !($($rest ) ,+) ) } } ;}
const BIG_STACK_SIZE: bool = true;
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let t = get!(usize);
    'test: for _ in 0..t {
        let n = get!(usize);
        let mut mat = get!([[chars]; n]);
        let mut ok1 = true;
        let mut ok2 = true;
        {
            let mut mat = mat.clone();
            for row in 0..mat.len() {
                let mut ok = true;
                for col in (0..mat[0].len()).rev() {
                    let cur = mat[row][col];
                    if ok && cur == '1' {
                        mat[row][col] = '*';
                        continue;
                    }
                    if cur == '0' {
                        ok = false;
                        continue;
                    }
                }
            }
            'x: for col in 0..n {
                let mut ok = true;
                for row in (0..n).rev() {
                    let cur = mat[row][col];
                    if cur == '*' {
                        ok = true;
                        continue;
                    }
                    if ok && cur == '1' {
                        mat[row][col] = '*';
                        continue;
                    }
                    if ok && cur == '0' {
                        ok = false;
                        continue;
                    }
                    if !ok && cur == '1' {
                        ok1 = false;
                        break 'x;
                    }
                }
            }
        }
        {
            let mut mat = mat.clone();
            for col in 0..mat.len() {
                let mut ok = true;
                for row in (0..mat[0].len()).rev() {
                    let cur = mat[row][col];
                    if ok && cur == '1' {
                        mat[row][col] = '*';
                        continue;
                    }
                    if cur == '0' {
                        ok = false;
                        continue;
                    }
                }
            }
            'y: for row in 0..n {
                let mut ok = true;
                for col in (0..n).rev() {
                    let cur = mat[row][col];
                    if cur == '*' {
                        ok = true;
                        continue;
                    }
                    if ok && cur == '1' {
                        mat[row][col] = '*';
                        continue;
                    }
                    if ok && cur == '0' {
                        ok = false;
                        continue;
                    }
                    if !ok && cur == '1' {
                        ok2 = false;
                        break 'y;
                    }
                }
            }
        }

        if ok1 || ok2 {
            echo!("YES");
        } else {
            echo!("NO");
        }
    }
}


//! https://github.com/hatoo/competitive-rust-snippets
//!
//! MIT License
//!
//! Copyright (c) 2018 hatoo
//!
//! Permission is hereby granted, free of charge, to any person obtaining a copy
//! of this software and associated documentation files (the "Software"), to deal
//! in the Software without restriction, including without limitation the rights
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//! copies of the Software, and to permit persons to whom the Software is
//! furnished to do so, subject to the following conditions:
//!
//! The above copyright notice and this permission notice shall be included in all
//! copies or substantial portions of the Software.
//!
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//! SOFTWARE.
#![allow(
    unused_imports,
    unused_attributes,
    unused_macros,
    dead_code,
    non_snake_case
)]
use std::cmp::{max, min, Ordering};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::io::{stdin, stdout, BufWriter, Write};
use std::iter::FromIterator;
#[macro_export]
macro_rules !get {(@inner [$src :expr ] chars ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .chars () .collect ::<Vec <char >>() } } ;(@inner [$src :expr ] usize1 ) =>{{get !(@inner [$src ] usize ) -1 } } ;(@inner [$src :expr ] [usize1 ] ) =>{{get !(@inner [$src ] [usize ] ) .into_iter () .map (|v |v -1 ) .collect ::<Vec <usize >>() } } ;(@inner [$src :expr ] [[usize1 ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [usize1 ] ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [usize1 ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [usize1 ] ) ) .flatten () .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [[chars ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] chars ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [chars ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] chars ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [($($tt :tt ) ,*) ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] ($($tt ) ,*) ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] ($($tt :tt ) ,*) ) =>{{let mut buf :String =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;let mut iter =buf .split_whitespace () ;($(get !(@inner_elem_parse [$tt ] iter .next () .unwrap () ) ,) *) } } ;(@inner [$src :expr ] [$t :ty ] ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .split_whitespace () .map (|t |t .parse ::<$t >() .unwrap () ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [[$t :ty ] ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [$t ] ) ) .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] [$t :ty ;$n :expr ] ) =>{{(0 ..$n ) .map (|_ |get !(@inner [$src ] [$t ] ) ) .flatten () .collect ::<Vec <_ >>() } } ;(@inner [$src :expr ] $t :ty ) =>{{let mut buf =String ::new () ;$src .read_line (&mut buf ) .unwrap () ;buf .trim () .split_whitespace () .next () .unwrap () .parse ::<$t >() .unwrap () } } ;(@inner_elem_parse [usize1 ] $elem :expr ) =>{{get !(@inner_elem_parse [usize ] $elem ) -1 } } ;(@inner_elem_parse [$t :ty ] $elem :expr ) =>{{$elem .parse ::<$t >() .unwrap () } } ;($tt :tt ) =>{{use std ::io ::BufRead ;let get_stdin =std ::io ::stdin () ;let mut locked_stdin =get_stdin .lock () ;get !(@inner [&mut locked_stdin ] $tt ) } } ;}
macro_rules !debug {($($a :expr ) ,*$(,) *) =>{#[cfg (debug_assertions ) ] eprintln !(concat !($("| " ,stringify !($a ) ,"={:?} " ) ,*,"|" ) ,$(&$a ) ,*) ;} ;}
macro_rules !echo {($($a :expr ) ,*) =>{let mut s =Vec ::new () ;$(s .push (format !("{}" ,$a ) ) ;) *println !("{}" ,s .join (" " ) ) ;} }
#[macro_export]
macro_rules !chmin {($base :expr ,$($cmps :expr ) ,+$(,) *) =>{{let cmp_min =min !($($cmps ) ,+) ;if $base >cmp_min {$base =cmp_min ;true } else {false } } } ;}
#[macro_export]
macro_rules !chmax {($base :expr ,$($cmps :expr ) ,+$(,) *) =>{{let cmp_max =max !($($cmps ) ,+) ;if $base <cmp_max {$base =cmp_max ;true } else {false } } } ;}
#[macro_export]
macro_rules !min {($a :expr $(,) *) =>{{$a } } ;($a :expr ,$b :expr $(,) *) =>{{std ::cmp ::min ($a ,$b ) } } ;($a :expr ,$($rest :expr ) ,+$(,) *) =>{{std ::cmp ::min ($a ,min !($($rest ) ,+) ) } } ;}
#[macro_export]
macro_rules !max {($a :expr $(,) *) =>{{$a } } ;($a :expr ,$b :expr $(,) *) =>{{std ::cmp ::max ($a ,$b ) } } ;($a :expr ,$($rest :expr ) ,+$(,) *) =>{{std ::cmp ::max ($a ,max !($($rest ) ,+) ) } } ;}
const BIG_STACK_SIZE: bool = false;
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let t = get!(usize);
    'test: for _ in 0..t {
        let n = get!(usize);
        let mut mat = get!([[chars]; n]);
        for row in (0..n).rev() {
            if mat[row][n - 1] != '1' {
                continue;
            }
            mat[row][n - 1] = '*';

            let mut q = VecDeque::new();
            if n > 1 {
                q.push_back((row, n - 2));
            }
            if row > 0 {
                q.push_back((row - 1, n - 1));
            }
            while let Some((r, c)) = q.pop_front() {
                if mat[r][c] != '1' {
                    continue;
                }
                mat[r][c] = '*';
                if r > 0 {
                    q.push_back((r - 1, c));
                }
                if c > 0 {
                    q.push_back((r, c - 1));
                }
            }
        }
        for col in (0..n).rev() {
            if mat[n - 1][col] != '1' {
                continue;
            }
            mat[n - 1][col] = '*';

            let mut q = VecDeque::new();
            if n > 1 {
                q.push_back((n - 2, col));
            }
            if col > 0 {
                q.push_back((n - 1, col - 1));
            }
            while let Some((r, c)) = q.pop_front() {
                if mat[r][c] != '1' {
                    continue;
                }
                mat[r][c] = '*';
                if r > 0 {
                    q.push_back((r - 1, c));
                }
                if c > 0 {
                    q.push_back((r, c - 1));
                }
            }
        }

        let mut ok = true;
        for i in 0..n {
            for j in 0..n {
                if mat[i][j] == '1' {
                    ok = false;
                    break;
                }
            }
        }
        if ok {
            echo!("YES");
        } else {
            echo!("NO");
        }
    }
}
fn solve2() {
    let t = get!(usize);
    'test: for _ in 0..t {
        let n = get!(usize);
        let mut mat = get!([[chars]; n]);
        let mut ok1 = true;
        let mut ok2 = true;
        {
            let mut mat = mat.clone();
            for row in 0..mat.len() {
                let mut ok = true;
                for col in (0..mat[0].len()).rev() {
                    let cur = mat[row][col];
                    if ok && cur == '1' {
                        mat[row][col] = '*';
                        continue;
                    }
                    if cur == '0' {
                        ok = false;
                        continue;
                    }
                }
            }
            'x: for col in 0..n {
                let mut ok = true;
                for row in (0..n).rev() {
                    let cur = mat[row][col];
                    if cur == '*' {
                        ok = true;
                        continue;
                    }
                    if ok && cur == '1' {
                        mat[row][col] = '*';
                        continue;
                    }
                    if ok && cur == '0' {
                        ok = false;
                        continue;
                    }
                    if !ok && cur == '1' {
                        ok1 = false;
                        break 'x;
                    }
                }
            }
        }
        {
            let mut mat = mat.clone();
            for col in 0..mat.len() {
                let mut ok = true;
                for row in (0..mat[0].len()).rev() {
                    let cur = mat[row][col];
                    if ok && cur == '1' {
                        mat[row][col] = '*';
                        continue;
                    }
                    if cur == '0' {
                        ok = false;
                        continue;
                    }
                }
            }
            'y: for row in 0..n {
                let mut ok = true;
                for col in (0..n).rev() {
                    let cur = mat[row][col];
                    if cur == '*' {
                        ok = true;
                        continue;
                    }
                    if ok && cur == '1' {
                        mat[row][col] = '*';
                        continue;
                    }
                    if ok && cur == '0' {
                        ok = false;
                        continue;
                    }
                    if !ok && cur == '1' {
                        ok2 = false;
                        break 'y;
                    }
                }
            }
        }

        if ok1 || ok2 {
            echo!("YES");
        } else {
            echo!("NO");
        }
    }
}


package main
import (
	"fmt"
	"os"
	"strconv"
	"bufio"
)

func main() {
	for t := nextInt(); t != 0; t-- {
		n := nextInt()
		mat := make([][]bool, n)
		for i := range mat {
			mat[i] = make([]bool, n)
			s := next()
			for idx, v := range s {
				mat[i][idx] = v == '1'
			}
		}
		// algo
		res := true
		for i, row := range mat {
			if i == n-1 {
				continue
			}
			for j := range row {
				if j == n-1 {
					continue
				}
				if mat[i][j] && mat[i][j+1] == mat[i+1][j] && mat[i+1][j] == false {
					res = false
					break
				}
			}
			if !res {
				break
			}
		}
		// Print
		if res {
			fmt.Println("YES")
		} else {
			fmt.Println("NO")
		}
	}
}

// -*-*-*-*-*-*-*-*-
// * I/O utilities *
// -*-*-*-*-*-*-*-*-
func init() {
	sc.Split(bufio.ScanWords)
}
var sc = bufio.NewScanner(os.Stdin)

func next() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	a, _ := strconv.Atoi(next())
	return a
}

func nextInt64() int64 {
	a, _ := strconv.ParseInt(next(), 10, 64)
	return a
}

func nextFloat64() float64 {
	a, _ := strconv.ParseFloat(next(), 64)
	return a
}

func nextInts(n int) []int {
	ret := make([]int, n)
	for i := 0; i < n; i++ {
		ret[i] = nextInt()
	}
	return ret
}
func nextFloats(n int) []float64 {
	ret := make([]float64, n)
	for i := 0; i < n; i++ {
		ret[i] = nextFloat64()
	}
	return ret
}
func nextStrings(n int) []string {
	ret := make([]string, n)
	for i := 0; i < n; i++ {
		ret[i] = next()
	}
	return ret
}

func split(s string) []string {
	ret := make([]string, len([]rune(s)))
	for i, v := range []rune(s) {
		ret[i] = string(v)
	}
	return ret
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	tc := readNum(reader)

	for tc > 0 {
		tc--
		n := readNum(reader)
		G := make([][]byte, n)

		for i := 0; i < n; i++ {
			G[i], _ = reader.ReadBytes('\n')
		}
		res := solve(n, G)

		if res {
			fmt.Println("YES")
		} else {
			fmt.Println("NO")
		}
	}
}

func solve(n int, G [][]byte) bool {
	dp := make([][]bool, n)

	for i := 0; i < n; i++ {
		dp[i] = make([]bool, n)
	}

	for i := 0; i < n; i++ {
		if G[i][n-1] == '1' {
			dp[i][n-1] = true
		}
		if G[n-1][i] == '1' {
			dp[n-1][i] = true
		}
	}

	for i := n - 2; i >= 0; i-- {
		for j := n - 2; j >= 0; j-- {
			if G[i][j] == '0' {
				continue
			}
			if !dp[i+1][j] && !dp[i][j+1] {
				return false
			}
			dp[i][j] = true
		}
	}

	return true
}