extern crate core;

use std::fmt;
use std::cmp::{Ordering, min, max};
use std::f32::MAX;
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut, SubAssign};
use std::collections::{BTreeMap, VecDeque, BinaryHeap, BTreeSet};
use std::fmt::Display;

fn show<T: Display>(vec: &Vec<T>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        print!("[{}", vec[0]);
        for i in 1 .. vec.len() {
            print!(", {}", vec[i]);
        }
        println!("]");
    }
}
fn show2<T: Display>(vec: &Vec<Vec<T>>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        for l in vec {
            show(l);
        }
    }
}
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! read_value{
    () => {
        read_line!().trim().parse().ok().unwrap()
    }
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
macro_rules! let_mut_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let mut $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}

fn make_graph(size: usize, seed: i64) -> Vec<Vec<bool>> {
    let mut graph = vec![vec![false; size]; size];
    for i in 0 .. size {
        for j in 0 .. size {
            graph[i][j] = seed & (1_i64 << (i as i64 * size as i64 + j as i64)) != 0;
        }
    }
    graph
}
fn cal_in_degree(graph: &Vec<Vec<bool>>) -> Vec<i32> {
    let mut in_count = vec![0; graph.len()];
    for i in 0 .. graph.len() {
        for j in 0 .. graph[i].len() {
            if graph[i][j] {
                in_count[j] += 1;
            }
        }
    }
    let mut result = vec![0; graph.len()];
    for count in in_count {
        result[count] += 1;
    }
    result
}
fn cal_out_degree(graph: &Vec<Vec<bool>>) -> Vec<i32> {
    let mut out_count = vec![0; graph.len()];
    for i in 0 .. graph.len() {
        for j in 0 .. graph[i].len() {
            if graph[i][j] {
                out_count[i] += 1;
            }
        }
    }
    let mut result = vec![0; graph.len()];
    for count in out_count {
        result[count] += 1;
    }
    result
}
#[derive(Copy, Clone)]
struct Edge {
    to: usize, pair: usize, flow: i32
}
fn set_edge(from: usize, to: usize, flow: i32, nodes: &mut Vec<Vec<Edge>>) {
    let to_len = nodes[to].len();
    let from_len = nodes[from].len();
    nodes[from].push(Edge{to: to, pair: to_len, flow: flow});
    nodes[to].push(Edge{to: from, pair: from_len, flow: 0});
}
fn bfs(source: usize, drain: usize, nodes: &Vec<Vec<Edge>>, depth: &mut Vec<i32>) {
    let mut queue = VecDeque::new();
    queue.push_back(source);
    depth[source] = 0;
    while let Some(current) = queue.pop_front() {
        if current != drain {
            for e in &nodes[current] {
                if depth[e.to] == -1 && e.flow > 0 {
                    depth[e.to] = depth[current] + 1;
                    queue.push_back(e.to);
                }
            }
        }else {
            break
        }
    }
}
fn dfs(current: usize, nodes: &mut Vec<Vec<Edge>>, depth: &Vec<i32>, searching: &mut Vec<usize>) -> bool {
    if current + 1 == nodes.len() {
        true
    }else {
        while searching[current] < nodes[current].len() {
            let Edge{to: next, pair: pair, flow: flow} = nodes[current][searching[current]];
            if flow > 0 && depth[current] < depth[next] && dfs(next, nodes, depth, searching) {
                nodes[current][searching[current]].flow -= 1;
                nodes[next][pair].flow += 1;
                return true
            }
            searching[current] += 1;
        }
        false
    }
}
fn max_matching(size: usize, in_count: &Vec<i32>, out_count: &Vec<i32>) -> Option<Vec<Vec<bool>>> {
    if in_count.iter().sum::<i32>() != size as i32 || out_count.iter().sum::<i32>() != size as i32 {
        //println!("un match size: {}, from in: {}, from out: {}", size,  in_count.iter().sum::<i32>(), out_count.iter().sum::<i32>());
        return None
    }
    let mut nodes = vec![Vec::with_capacity(size + 1); size * 2 + 2];
    let mut in_count = in_count.clone();
    let mut out_count = out_count.clone();
    let source = size * 2;
    let drain = size * 2 + 1;
    let mut all_flow_in = 0;
    let mut all_flow_out = 0;
    for i in 0 .. size {
        for j in 0 .. out_count.len() {
            if out_count[j] != 0 {
                set_edge(source, i, j as i32, &mut nodes);
                out_count[j] -= 1;
                all_flow_out += j;
                break
            }
        }
        for j in 0 .. in_count.len() {
            if in_count[j] != 0 {
                set_edge(i + size, drain, j as i32, &mut nodes);
                in_count[j] -= 1;
                all_flow_in += j;
                break
            }
        }
        for j in 0 .. size {
            set_edge(i, j + size, 1, &mut nodes);
        }
    }
    if all_flow_in != all_flow_out {
        return None
    }
    let mut depth = vec![-1; size * 2 + 2];
    let mut searching = vec![0; drain];
    let mut has_flow = true;
    let mut flow = 0;
    while has_flow {
        has_flow = false;
        for i in 0 .. depth.len() {
            depth[i] = -1;
        }
        bfs(source, drain, &nodes, &mut depth);
        for i in 0 .. searching.len() {
            searching[i] = 0;
        }
        while dfs(source, &mut nodes, &depth, &mut searching) {
            has_flow = true;
            flow += 1;
        }
    }
    if all_flow_in != flow {
        None
    }else {
        let mut graph = vec![vec![false; size]; size];
        for i in 0 .. size {
            for e in &nodes[i] {
                if size <= e.to && e.to < source && e.flow == 0{
                    graph[i][e.to - size] = true;
                }
            }
        }
        Some(graph)
    }
}

fn main(){
    let_all!(n: usize);
    let in_count = read_line!(' '; i32);
    let out_count = read_line!(' '; i32);
    if let Some(graph) = max_matching(n, &in_count, &out_count) {
        println!("YES");
        for line in graph {
            println!("{}", line.iter().map(|&x| if x {"1"} else {"0"}).collect::<Vec<_>>().join(" "));
        }
    }else {
        println!("NO");
    }
}




Measured memory_bytes: 5048