#include <bits/stdc++.h>
using namespace std;
struct pat {
  int x, y;
  pat(int x = 0, int y = 0) : x(x), y(y) {}
  bool operator<(const pat &p) const { return x == p.x ? y < p.y : x < p.x; }
};
template <typename TP>
inline void read(TP &tar) {
  TP ret = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    ret = ret * 10 + (ch - '0');
    ch = getchar();
  }
  tar = ret * f;
}
namespace RKK {
const int N = 2011;
void AO() {
  puts("NO");
  exit(0);
}
int n;
char str[N][N];
int ansp[N], ani;
vector<int> ve[N << 2];
int rt;
int tp[N << 2];
int cn;
int rev[N << 2];
int size[N << 2], cnt[N << 2];
void dfs(int x, int p) {
  if (x <= n) {
    size[x] = 1, cnt[x] = (str[p][x] == '1');
    return;
  }
  size[x] = cnt[x] = 0;
  for (int i = 0; i < ve[x].size(); i++)
    dfs(ve[x][i], p), size[x] += size[ve[x][i]], cnt[x] += cnt[ve[x][i]];
}
void fuckdown(int x) {
  if (!rev[x]) return;
  reverse(ve[x].begin(), ve[x].end());
  for (int i = 0; i < ve[x].size(); i++) rev[ve[x][i]] ^= 1;
  rev[x] = 0;
}
void dorev(int x) {
  if (tp[x] != 2) AO();
  tp[x] = 1, rev[x] = 1;
  fuckdown(x);
}
int solve(int x, int d) {
  if (x <= n) return x;
  fuckdown(x);
  if (!tp[x]) {
    vector<int> vf, v0, vv;
    for (int i = 0; i < ve[x].size(); i++)
      if (size[ve[x][i]] == cnt[ve[x][i]])
        vf.push_back(ve[x][i]);
      else if (!cnt[ve[x][i]])
        v0.push_back(ve[x][i]);
      else
        vv.push_back(ve[x][i]);
    if (vv.size() + (d != 0) > 2) AO();
    if (!vf.size() && vv.size() == 1 && !d)
      for (int i = 0; i < ve[x].size(); i++)
        if (ve[x][i] == vv[0]) return ve[x][i] = solve(vv[0], 0), x;
    int a = vf.size() ? (vf.size() == 1 ? vf[0] : (ve[++cn] = vf, cn)) : -1;
    vector<int> t;
    if (d != 1 && vv.size()) t.push_back(solve(vv[0], 2));
    if (~a) t.push_back(a);
    if (d != 2 && vv.size() > !d) t.push_back(solve(vv.back(), 1));
    int g = t.size() == 1 ? t[0] : (ve[++cn] = t, tp[cn] = 2, cn);
    if (!v0.size())
      return g;
    else {
      int b = ++cn;
      if (d) {
        int y = v0.size() == 1 ? v0[0] : (ve[++cn] = v0, cn);
        tp[b] = 1;
        if (d == 1)
          ve[b].push_back(g), ve[b].push_back(y);
        else
          ve[b].push_back(y), ve[b].push_back(g);
      } else
        ve[b] = v0, ve[b].push_back(g);
      return b;
    }
  } else {
    int l = ve[x][0], r = ve[x].back();
    if (d == 1 && size[l] != cnt[l] && (!cnt[l] || size[r] == cnt[r])) dorev(x);
    if (d == 2 && size[r] != cnt[r] && (!cnt[r] || size[l] == cnt[l])) dorev(x);
    int lst = -1, c = 0, ac = 0;
    int sora = 0;
    for (int i = 0, y, t; i < ve[x].size(); i++) {
      y = ve[x][i];
      if (size[y] == cnt[y])
        t = 2;
      else if (!cnt[y])
        t = 0;
      else
        t = 1;
      if (~lst) {
        if ((d == 1 && t > lst) || (d == 2 && t < lst)) AO();
        if (!t && lst) sora = 1;
        if (sora && t && !lst) AO();
      }
      lst = t;
      if (t == 1) c++;
      if (t) ac++;
    }
    sora = 2;
    if (c + (d != 0) > 2) AO();
    for (int i = 0; i < ve[x].size(); i++) {
      int &y = ve[x][i], t = cnt[y];
      if (t && t < size[y]) {
        if (d || ac == 1)
          y = solve(y, d);
        else
          y = solve(y, sora);
      }
      if (t) sora = 1;
    }
    return x;
  }
}
void getans(int x) {
  if (x <= n) {
    ansp[++ani] = x;
    return;
  }
  fuckdown(x);
  for (int i = 0; i < ve[x].size(); i++) getans(ve[x][i]);
}
int main() {
  read(n);
  for (int i = 1; i <= n; i++) scanf("%s", str[i] + 1), ve[n + 1].push_back(i);
  cn = rt = n + 1;
  for (int i = 1; i <= n; i++) {
    dfs(rt, i);
    if (cnt[rt]) rt = solve(rt, 0);
  }
  getans(rt);
  puts("YES");
  for (int i = 1; i <= n; i++, putchar('\n'))
    for (int j = 1; j <= n; j++) putchar(str[i][ansp[j]]);
  return 0;
}
}  // namespace RKK
int main() { return RKK::main(); }
