use std::{
    collections::HashSet,
    io::{stdin, stdout, BufReader, BufRead, BufWriter, Write, Read},
};

#[derive(Hash, PartialEq, Eq, Clone, Debug)]
struct State {
    row: usize,
    column: usize,
    bottom: Option<i32>,
    top: Option<i32>,
    front: Option<i32>,
    back: Option<i32>,
    right: Option<i32>,
    left: Option<i32>,
}

impl State {
    fn left(&self) -> Self {
        Self {
            column: self.column - 1,
            bottom: self.left,
            top: self.right,
            right: self.bottom,
            left: self.top,
            ..*self
        }
    }

    // fn right(&self) -> Self {
    //     Self {
    //         column: self.column + 1,
    //         bottom: self.right,
    //         top: self.left,
    //         right: self.top,
    //         left: self.bottom,
    //         ..*self
    //     }
    // }

    fn up(&self) -> Self {
        Self {
            row: self.row - 1,
            bottom: self.back,
            top: self.front,
            back: self.top,
            front: self.bottom,
            ..*self
        }
    }

    // fn down(&self) -> Self {
    //     Self {
    //         row: self.row + 1,
    //         bottom: self.front,
    //         top: self.back,
    //         back: self.bottom,
    //         front: self.top,
    //         ..*self
    //     }
    // }
}

struct Solution {
    a: Vec<Vec<i32>>,
    used: HashSet<State>,
    path: Vec<u8>,
}

impl Solution {
    fn new(a: Vec<Vec<i32>>) -> Self {
        Self {
            a,
            used: HashSet::new(),
            path: Vec::new(),
        }
    }

    fn dfs(&mut self, state: State) -> Option<(State, String)> {
        let field_color = self.a[state.row][state.column];
        let state = if let Some(color) = state.bottom {
            if color != field_color {
                return None;
            }
            state
        } else {
            State {
                bottom: Some(field_color),
                ..state
            }
        };
        if state.row == 0 && state.column == 0 {
            let path = self.path.iter().rev().copied().collect::<Vec<_>>();
            return Some((state, String::from_utf8_lossy(&path).to_string()));
        }
        if self.used.contains(&state) {
            return None;
        }
        self.used.insert(state.clone());
        let moves = self.try_go(&state);
        for (new_state, direction) in moves {
            self.path.push(direction);
            let result = self.dfs(new_state);
            if result.is_some() {
                return result;
            }
            self.path.pop();
        }
        None
    }

    fn try_go(&self, state: &State) -> Vec<(State, u8)> {
        // let rows = self.a.len();
        // let columns = self.a[state.row].len();
        let mut moves = Vec::new();
        if state.column > 0 {
            moves.push((state.left(), b'R'));
        }
        if state.row > 0 {
            moves.push((state.up(), b'D'));
        }
        // if state.column + 1 < columns {
        //     moves.push((state.right(), b'L'));
        // }
        // if state.row + 1 < rows {
        //     moves.push((state.down(), b'U'));
        // }
        moves
    }

    fn solve(&mut self) -> Option<(State, String)> {
        let start_row = self.a.len() - 1;
        let start_column = self.a[start_row].len() - 1;
        let start = State {
            row: start_row,
            column: start_column,
            bottom: None,
            top: None,
            front: None,
            back: None,
            left: None,
            right: None,
        };
        let result = self.dfs(start);
        dbg!(self.used.len());
        result
    }
}

fn solve_case<R: Read, W: Write>(reader: &mut BufReader<R>, writer: &mut BufWriter<W>) {
    let n = read_line(reader).split(' ').next().unwrap().parse().unwrap();
    let a = (0..n)
        .map(|_| {
            read_line(reader)
                .split(' ')
                .map(|x| x.parse().unwrap())
                .collect::<Vec<_>>()
        })
        .collect::<Vec<_>>();
    let answer = Solution::new(a).solve();
    if let Some((cube, _)) = answer {
        write!(
            writer,
            "Yes\n{} {} {} {} {} {}\n",
            cube.bottom.unwrap(),
            cube.left.unwrap_or(0),
            cube.back.unwrap_or(0),
            cube.front.unwrap_or(0),
            cube.right.unwrap_or(0),
            cube.top.unwrap_or(0),
        )
        .unwrap();
    } else {
        write!(writer, "No\n").unwrap();
    }
}

pub fn main() {
    let mut reader = BufReader::new(stdin().lock());
    let mut writer = BufWriter::new(stdout().lock());
    let tests = read_line(&mut reader).parse().unwrap();
    (0..tests).for_each(|_| solve_case(&mut reader, &mut writer))
}

fn read_line<R: Read>(reader: &mut BufReader<R>) -> String {
    let mut str = String::new();
    let _ = reader.read_line(&mut str).unwrap();
    str.trim().to_string()
}
