#include <bits/stdc++.h>
using namespace std;
const int M = 1 << 9;
char str[M][M];
bool has_all(char *col, vector<int> &inds) {
  for (int i = 0; i < (int)inds.size(); ++i)
    if (col[inds[i]] == '0') return false;
  return true;
}
bool add_boundary_constraint(int &n, vector<char *> &a, vector<int> &bound,
                             int symbol) {
  if ((int)bound.size() > 0) {
    bool candidate_exists = false;
    for (int j = 0; j < (int)a.size(); ++j) {
      if (has_all(a[j], bound)) {
        a[j][n] = '0' + symbol;
        candidate_exists = true;
      } else
        a[j][n] = '0' + 1 - symbol;
    }
    if (!candidate_exists) {
      return false;
    }
    ++n;
  }
  return true;
}
int count(vector<char *> &v, int row) {
  int res = 0;
  for (int j = 0; j < (int)v.size(); ++j)
    if (v[j][row] == '1') ++res;
  return res;
}
bool go(vector<char *> &v, int n, int m) {
  int cnt[M * 4], cnt_a[M * 4], cnt_b[M * 4];
  int max_ind = -1;
  for (int i = 0; i < n; ++i) {
    cnt[i] = count(v, i);
    if (cnt[i] != m) {
      if (max_ind == -1 || cnt[max_ind] < cnt[i]) max_ind = i;
    }
  }
  if (max_ind == -1 || cnt[max_ind] <= 1) return true;
  vector<char *> a, b;
  for (int i = 0; i < m; ++i)
    if (v[i][max_ind] == '1')
      a.push_back(v[i]);
    else
      b.push_back(v[i]);
  int a_sz = cnt[max_ind];
  int b_sz = (int)b.size();
  vector<int> common;
  for (int i = 0; i < n; ++i) {
    cnt_a[i] = count(a, i);
    cnt_b[i] = count(b, i);
    if (cnt_a[i] > 0 && cnt_b[i] > 0 && cnt_a[i] + cnt_b[i] != m)
      common.push_back(i);
  }
  set<int> first_bound, second_bound;
  if ((int)common.size() > 0) {
    first_bound.insert(0);
    for (int j = 0; j < b_sz; ++j)
      if (b[j][common[0]] == '1')
        for (int k = 1; k < (int)common.size(); ++k)
          if (b[j][common[k]] == '1') first_bound.insert(k);
  }
  vector<int> bound1, bound2;
  for (int k = 0; k < (int)common.size(); ++k)
    if (first_bound.count(k) == 0)
      bound2.push_back(common[k]);
    else
      bound1.push_back(common[k]);
  int old_n = n;
  if (!add_boundary_constraint(n, a, bound1, 0)) return false;
  if (!add_boundary_constraint(n, a, bound2, 0)) return false;
  if (!go(a, n, a_sz)) {
    return false;
  }
  n = old_n;
  if (!add_boundary_constraint(n, b, bound1, 1)) return false;
  if (!add_boundary_constraint(n, b, bound2, 1)) return false;
  char *col;
  if ((int)bound1.size() > 0) {
    col = new char[M * 4];
    for (int i = 0; i < old_n; ++i)
      if (cnt[i] == m)
        col[i] = '1';
      else
        col[i] = '0';
    for (int i = old_n; i < n; ++i) col[i] = '1';
    b.push_back(col);
    ++b_sz;
  }
  if (!go(b, n, b_sz)) {
    return false;
  }
  v.clear();
  if ((int)bound1.size() == 0) {
    for (int j = 0; j < a_sz; ++j) v.push_back(a[j]);
    for (int j = 0; j < b_sz; ++j) v.push_back(b[j]);
    return true;
  }
  bool fake_found = false;
  for (int j = 0; j < b_sz; ++j) {
    bool is_fake = b[j] == col;
    if (is_fake) {
      if (fake_found) throw -1;
      fake_found = true;
      bool has_all_b = j > 0 && has_all(b[j - 1], bound1);
      bool has_all_a = has_all(a[0], bound1);
      if (has_all_a != has_all_b) {
        for (int k = a_sz - 1; k >= 0; --k) v.push_back(a[k]);
      } else {
        for (int k = 0; k < a_sz; ++k) v.push_back(a[k]);
      }
      bool has_all_b2 = j < b_sz - 1 && has_all(b[j + 1], bound1);
      bool has_all_a2 = has_all(a[a_sz - 1], bound1);
      if (has_all_b == has_all_b2) throw -1;
      if (has_all_a == has_all_a2) throw -1;
    } else
      v.push_back(b[j]);
  }
  if (!fake_found)
    while (true)
      ;
  return true;
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) scanf("%s", str[i]);
  vector<char *> v;
  for (int j = 0; j < n; ++j) {
    char *col = new char[M * 4];
    for (int i = 0; i < n; ++i) col[i] = str[i][j];
    v.push_back(col);
  }
  if (!go(v, n, n)) {
    puts("NO");
    return 0;
  }
  puts("YES");
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) putchar(v[j][i]);
    puts("");
  }
  return 0;
}
