#include <bits/stdc++.h>
using namespace std;
long long fra[105];
int MOD = 998244353;
const int N = 1005;
struct PQ_tree {
  int fail, res, n, tot;
  vector<int> G[N << 2];
  int ty[N << 2], sz[N << 2], szc[N << 2];
  bool s[N];
  vector<int> ans;
  inline int getstate(int u) {
    if (szc[u] == 0) return 0;
    if (szc[u] == sz[u]) return 2;
    return 1;
  }
  void addson(int first, int second) {
    if (second) G[first].push_back(second);
  }
  void join(int first, int second) {
    for (auto v : G[second]) G[first].push_back(v);
  }
  int mergeP(vector<int> &vec) {
    if (vec.size() == 0) return 0;
    if (vec.size() == 1) return vec[0];
    G[++tot] = vec;
    return tot;
  }
  void init(int _n) {
    n = _n;
    tot = n + 1;
    memset(ty, 0, sizeof(ty));
    for (int i = 1; i <= n; i++) G[n + 1].push_back(i);
    fail = 0;
  }
  void dfs(int u) {
    sz[u] = u <= n;
    szc[u] = u <= n && s[u];
    for (auto v : G[u]) {
      dfs(v);
      sz[u] += sz[v];
      szc[u] += szc[v];
    }
  }
  int check(int u, int t) {
    if (fail) return 0;
    vector<int> vec[3];
    for (auto v : G[u]) vec[getstate(v)].push_back(v);
    if (vec[1].size() > 2 || (t && vec[1].size() > 1)) return fail = 1, 0;
    if (t == 0 && vec[1].size() == 1 && vec[2].size() == 0)
      return check(vec[1][0], 0);
    if (ty[u] == 0) {
      int p2 = mergeP(vec[2]);
      if (t == 0) {
        G[u] = vec[0];
        if (vec[1].size() == 0)
          addson(u, p2);
        else {
          int tmp1 = check(vec[1][0], 2);
          addson(tmp1, p2);
          if (vec[1].size() == 2) join(tmp1, check(vec[1][1], 1));
          addson(u, tmp1);
        }
        return u;
      } else {
        ty[u] = 1;
        G[u].clear();
        addson(u, p2);
        if (vec[1].size() == 1) join(u, check(vec[1][0], 1));
        addson(u, mergeP(vec[0]));
        if (t == 2) reverse(G[u].begin(), G[u].end());
      }
      return u;
    } else {
      if (getstate(G[u].front()) > getstate(G[u].back()))
        reverse(G[u].begin(), G[u].end());
      int flag = 0;
      vector<int> tG;
      for (auto v : G[u]) {
        int sta = getstate(v);
        if (sta == 0) {
          if (flag == 1) flag = 2;
          tG.push_back(v);
        } else if (sta == 2) {
          if (flag == 0)
            flag = 1;
          else if (flag == 2)
            return fail = 2, 0;
          tG.push_back(v);
        } else {
          int p1;
          if (flag == 0)
            flag = 1, p1 = check(v, 2);
          else if (flag == 1)
            flag = 2, p1 = check(v, 1);
          else
            return fail = 3, 0;
          for (auto first : G[v]) tG.push_back(first);
        }
      }
      if (t && flag == 2) return fail = 4, 0;
      if (t == 1) reverse(tG.begin(), tG.end());
      G[u] = tG;
      return u;
    }
  }
  void dfs_permutation(int u) {
    if (u <= n) {
      ans.push_back(u);
      return;
    }
    if (!ty[u]) {
      res = (long long)res * fra[G[u].size()] % MOD;
    } else if (G[u].size() != 1) {
      res = (long long)res * 2 % MOD;
    }
    for (auto v : G[u]) {
      dfs_permutation(v);
    }
  }
  int get_permutation() {
    res = 1;
    dfs_permutation(n + 1);
    return res;
  }
  void restrict(vector<int> res) {
    for (int i = 1; i <= n; i++) s[i] = 0;
    for (auto first : res) s[first] = 1;
    dfs(n + 1);
    check(n + 1, 0);
  }
};
void solve() {
  int n;
  scanf("%d", &n);
  char c[505][505];
  PQ_tree pq;
  pq.init(n);
  for (int i = 1; i <= n; i++) {
    scanf("%s", c[i] + 1);
    vector<int> v;
    for (int j = 1; j <= n; j++) {
      if (c[i][j] == '1') v.push_back(j);
    }
    pq.restrict(v);
  }
  if (pq.fail) {
    printf("NO\n");
    return;
  }
  pq.get_permutation();
  printf("YES\n");
  for (int i = 1; i <= n; i++) {
    for (auto it : pq.ans) {
      printf("%c", c[i][it]);
    }
    printf("\n");
  }
}
int main() {
  int t = 1;
  while (t--) {
    solve();
  }
  return 0;
}
