Problem: Let's consider an n × n square matrix, consisting of digits one and zero.

We'll consider a matrix good, if it meets the following condition: in each row of the matrix all ones go in one group. That is, each row of the matrix looks like that 00...0011...1100...00 (or simply consists of zeroes if it has no ones).

You are given matrix a of size n × n, consisting of zeroes and ones. Your task is to determine whether you can get a good matrix b from it by rearranging the columns or not.

Input

The first line contains integer n (1 ≤ n ≤ 500) — the size of matrix a.

Each of n following lines contains n characters "0" and "1" — matrix a. Note that the characters are written without separators.

Output

Print "YES" in the first line, if you can rearrange the matrix columns so as to get a good matrix b. In the next n lines print the good matrix b. If there are multiple answers, you are allowed to print any of them.

If it is impossible to get a good matrix, print "NO".

Examples

Input

6
100010
110110
011001
010010
000100
011001


Output

YES
011000
111100
000111
001100
100000
000111


Input

3
110
101
011


Output

NO

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
struct PQtree {
  int type, father;
  vector<int> child;
} node[2010];
int n, status[2010], w[2010], size[2010], in[5010], B[2010],
    W[3] = {0, 2, 1}, ans[2010], C[600][600], len, kk;
vector<int> rem, A;
char getin() {
  char ch = getchar();
  while (ch < '0' || ch > '9') ch = getchar();
  return ch;
}
int getnext() {
  int k1 = rem[(rem.size()) - 1];
  rem.pop_back();
  node[k1].child.clear();
  node[k1].type = 0;
  node[k1].father = 0;
  return k1;
}
void reverse(int k) {
  vector<int> k1;
  for (int i = 0; i < node[k].child.size(); i++) k1.push_back(node[k].child[i]);
  node[k].child.clear();
  for (int i = (k1.size()) - 1; i >= 0; i--) node[k].child.push_back(k1[i]);
}
void change(int k1, int k2, int k3) {
  if (k1 == 0) return;
  for (int i = 0; i < node[k1].child.size(); i++)
    if (node[k1].child[i] == k2) {
      node[k1].child[i] = k3;
      return;
    }
}
int reduce() {
  memset(B, 0, sizeof(B));
  memset(size, 0, sizeof(size));
  memset(w, 0, sizeof(w));
  memset(status, 0xff, sizeof(status));
  queue<int> Q;
  for (int i = 1; i <= n; i++) {
    Q.push(i);
    status[i] = in[i];
    w[i] = in[i];
  }
  while (!Q.empty()) {
    int k = Q.front();
    Q.pop();
    int flag = 0;
    if (w[k] == A.size()) flag = 1;
    if (status[k] == 2) {
      vector<int> C[3];
      for (int i = 0; i < node[k].child.size(); i++) {
        int j = node[k].child[i];
        C[status[j]].push_back(j);
      }
      if (node[k].type == 1) {
        if (C[2].size() == 0) {
          if (flag == 1) {
            if (C[1].size() > 1) {
              int k1 = getnext();
              for (int i = 0; i < C[1].size(); i++) {
                node[k1].child.push_back(C[1][i]);
                node[C[1][i]].father = k1;
              }
              node[k1].father = k;
              node[k].child.clear();
              node[k1].type = 1;
              status[k1] = 1;
              for (int i = 0; i < C[0].size(); i++)
                node[k].child.push_back(C[0][i]);
              node[k].child.push_back(k1);
            }
          } else {
            node[k].type = 2;
            node[k].child.clear();
            if (C[0].size() > 1) {
              int k1 = getnext();
              node[k1].father = k;
              node[k].child.push_back(k1);
              node[k1].type = 1;
              status[k1] = 0;
              for (int i = 0; i < C[0].size(); i++) {
                node[k1].child.push_back(C[0][i]);
                node[C[0][i]].father = k1;
              }
            } else if (C[0].size())
              node[k].child.push_back(C[0][0]);
            if (C[1].size() > 1) {
              int k1 = getnext();
              node[k1].father = k;
              node[k].child.push_back(k1);
              node[k1].type = 1;
              status[k1] = 1;
              for (int i = 0; i < C[1].size(); i++) {
                node[k1].child.push_back(C[1][i]);
                node[C[1][i]].father = k1;
              }
            } else if (C[1].size())
              node[k].child.push_back(C[1][0]);
          }
        } else if (C[2].size() == 1) {
          if (flag == 1) {
            node[k].child.clear();
            if (C[1].size() == 1) {
              node[C[2][0]].child.push_back(C[1][0]);
              node[C[1][0]].father = C[2][0];
              for (int i = 0; i < C[0].size(); i++)
                node[k].child.push_back(C[0][i]);
              node[k].child.push_back(C[2][0]);
            } else if (C[1].size()) {
              int k1 = getnext(), k2 = C[2][0];
              node[k1].type = 1;
              node[k1].father = k2;
              status[k1] = 1;
              for (int i = 0; i < C[1].size(); i++) {
                node[k1].child.push_back(C[1][i]);
                node[C[1][i]].father = k1;
              }
              node[k2].child.push_back(k1);
              for (int i = 0; i < C[0].size(); i++)
                node[k].child.push_back(C[0][i]);
              node[k].child.push_back(k2);
            }
            if (node[k].child.size() == 1) {
              node[node[k].child[0]].father = node[k].father;
              change(node[k].father, k, node[k].child[0]);
              rem.push_back(k);
            }
          } else {
            node[k].child.clear();
            node[k].type = 2;
            if (C[0].size() == 1)
              node[k].child.push_back(C[0][0]);
            else if (C[0].size()) {
              int k1 = getnext();
              node[k1].type = 1;
              node[k1].father = k;
              status[k1] = 0;
              for (int i = 0; i < C[0].size(); i++) {
                node[k1].child.push_back(C[0][i]);
                node[C[0][i]].father = k1;
              }
              node[k].child.push_back(k1);
            }
            int k2 = C[2][0];
            for (int i = 0; i < node[k2].child.size(); i++) {
              node[k].child.push_back(node[k2].child[i]);
              node[node[k2].child[i]].father = k;
            }
            if (C[1].size() == 1)
              node[k].child.push_back(C[1][0]);
            else if (C[1].size()) {
              int k1 = getnext();
              node[k1].type = 1;
              node[k1].father = k;
              status[k1] = 1;
              for (int i = 0; i < C[1].size(); i++) {
                node[k1].child.push_back(C[1][i]);
                node[C[1][i]].father = k1;
              }
              node[k].child.push_back(k1);
            }
            rem.push_back(k2);
          }
        } else if (C[2].size() == 2) {
          if (flag == 0) return 0;
          node[k].child.clear();
          for (int i = 0; i < C[0].size(); i++)
            node[k].child.push_back(C[0][i]);
          int k1 = getnext();
          int k2 = C[2][0];
          node[k1].type = 2;
          node[k1].father = k;
          for (int i = 0; i < node[k2].child.size(); i++) {
            node[k1].child.push_back(node[k2].child[i]);
            node[node[k2].child[i]].father = k1;
          }
          rem.push_back(k2);
          status[k1] = 2;
          if (C[1].size() == 1) {
            node[k1].child.push_back(C[1][0]);
            node[C[1][0]].father = k1;
          } else if (C[1].size()) {
            int k3 = getnext();
            node[k3].type = 1;
            node[k3].father = k1;
            status[k3] = 1;
            for (int i = 0; i < C[1].size(); i++) {
              node[k3].child.push_back(C[1][i]);
              node[C[1][i]].father = k3;
            }
            node[k1].child.push_back(k3);
          }
          node[k].child.push_back(k1);
          k2 = C[2][1];
          for (int i = (node[k2].child.size()) - 1; i >= 0; i--) {
            node[k1].child.push_back(node[k2].child[i]);
            node[node[k2].child[i]].father = k1;
          }
          rem.push_back(k2);
          if (node[k].child.size() == 1) {
            node[k1].father = node[k].father;
            change(node[k].father, k, k1);
            rem.push_back(k);
          }
        } else
          return 0;
      } else {
        int now = 0, flag2 = 0;
        for (int i = 0; i < node[k].child.size(); i++) {
          int j = node[k].child[i];
          if (W[status[j]] < now) {
            flag2 = 1;
            break;
          }
          now = W[status[j]];
        }
        int flag3 = 0;
        now = 2;
        for (int i = 0; i < node[k].child.size(); i++) {
          int j = node[k].child[i];
          if (W[status[j]] > now) {
            flag3 = 1;
            break;
          }
          now = W[status[j]];
        }
        if ((flag2 == 0 || flag3 == 0) && C[2].size() == 1) {
          if (flag3 == 0) {
            reverse(k);
            C[0].clear();
            C[1].clear();
            C[2].clear();
            for (int i = 0; i < node[k].child.size(); i++) {
              int j = node[k].child[i];
              C[status[j]].push_back(j);
            }
          }
          node[k].child.clear();
          for (int i = 0; i < C[0].size(); i++)
            node[k].child.push_back(C[0][i]);
          int k2 = C[2][0];
          for (int i = 0; i < node[k2].child.size(); i++) {
            node[k].child.push_back(node[k2].child[i]);
            node[node[k2].child[i]].father = k;
          }
          rem.push_back(k2);
          for (int i = 0; i < C[1].size(); i++)
            node[k].child.push_back(C[1][i]);
        } else if (C[2].size() <= 2 && C[2].size() >= 1) {
          if (flag == 0) return 0;
          int two1 = -1, two2 = -1;
          for (int i = 0; i < node[k].child.size(); i++) {
            int j = node[k].child[i];
            if (status[j] == 2) {
              if (two1 != -1)
                two2 = i;
              else
                two1 = i;
            }
          }
          if (C[2].size() == 2) {
            for (int i = 0; i < two1; i++) {
              int j = node[k].child[i];
              if (status[j] != 0) return 0;
            }
            for (int i = two1 + 1; i < two2; i++) {
              int j = node[k].child[i];
              if (status[j] != 1) return 0;
            }
            for (int i = two2 + 1; i < node[k].child.size(); i++) {
              int j = node[k].child[i];
              if (status[j] != 0) return 0;
            }
            reverse(C[2][1]);
            node[k].child.clear();
            for (int i = 0; i < two1; i++) node[k].child.push_back(C[0][i]);
            int k2 = C[2][0];
            for (int i = 0; i < node[k2].child.size(); i++) {
              node[k].child.push_back(node[k2].child[i]);
              node[node[k2].child[i]].father = k;
            }
            rem.push_back(k2);
            for (int i = 0; i < C[1].size(); i++)
              node[k].child.push_back(C[1][i]);
            k2 = C[2][1];
            for (int i = 0; i < node[k2].child.size(); i++) {
              node[k].child.push_back(node[k2].child[i]);
              node[node[k2].child[i]].father = k;
            }
            rem.push_back(k2);
            for (int i = two1; i < C[0].size(); i++)
              node[k].child.push_back(C[0][i]);
          } else {
            int flag4 = 0;
            for (int i = 0; i < two1; i++) {
              int k1 = node[k].child[i];
              if (status[k1] == 1) {
                flag4 = 1;
                break;
              }
            }
            if (flag4) {
              reverse(k);
              two1 = (node[k].child.size()) - two1 - 1;
            }
            for (int i = 0; i < two1; i++) {
              int k1 = node[k].child[i];
              if (status[k1]) return 0;
            }
            int now = 1;
            for (int i = two1 + 1; i < node[k].child.size(); i++) {
              int k1 = node[k].child[i];
              if (status[k1] > now) return 0;
              now = status[k1];
            }
            C[0].clear();
            C[1].clear();
            C[2].clear();
            for (int i = 0; i < node[k].child.size(); i++) {
              int j = node[k].child[i];
              C[status[j]].push_back(j);
            }
            node[k].child.clear();
            for (int i = 0; i < two1; i++) node[k].child.push_back(C[0][i]);
            int k2 = C[2][0];
            for (int i = 0; i < node[k2].child.size(); i++) {
              node[k].child.push_back(node[k2].child[i]);
              node[node[k2].child[i]].father = k;
            }
            rem.push_back(k2);
            for (int i = 0; i < C[1].size(); i++)
              node[k].child.push_back(C[1][i]);
            for (int i = two1; i < C[0].size(); i++)
              node[k].child.push_back(C[0][i]);
          }
        } else if (C[2].size() == 0) {
          if (status[node[k].child[0]] == 1) reverse(k);
          int k1 = node[k].child.size();
          for (int i = 0; i < node[k].child.size(); i++) {
            int k2 = node[k].child[i];
            if (status[k2] == 1) {
              k1 = i;
              break;
            }
          }
          int k3 = node[k].child.size();
          for (int i = k1; i < node[k].child.size(); i++) {
            int k2 = node[k].child[i];
            if (status[k2] == 0) {
              k3 = i;
              break;
            }
          }
          if (flag == 0 && k3 != node[k].child.size()) return 0;
          if (flag == 1)
            for (int i = k3; i < node[k].child.size(); i++) {
              int k2 = node[k].child[i];
              if (status[k2] == 1) return 0;
            }
        } else
          return 0;
      }
    }
    if (flag) return 1;
    int k1 = node[k].father;
    size[k1]++;
    w[k1] += w[k];
    if (status[k1] == -1)
      status[k1] = status[k];
    else if (status[k1] != status[k])
      status[k1] = 2;
    if (size[k1] == node[k1].child.size()) Q.push(k1);
  }
}
void print(int k) {
  if (node[k].type == 0) {
    ans[++len] = k;
    return;
  }
  for (int i = 0; i < node[k].child.size(); i++) print(node[k].child[i]);
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    node[i].type = 0;
    node[i].father = n + 1;
    node[i].child.clear();
    node[n + 1].child.push_back(i);
  }
  node[n + 1].type = 1;
  for (int i = 2000; i > n + 1; i--) rem.push_back(i);
  for (int i = 1; i <= n; i++) {
    memset(in, 0, sizeof in);
    A.clear();
    for (int j = 1; j <= n; j++) {
      char ch = getin();
      C[i][j] = ch - '0';
      if (ch == '1') {
        A.push_back(j);
        in[j] = 1;
      }
    }
    kk = i;
    if (!reduce()) {
      puts("NO");
      return 0;
    }
  }
  int root = 1;
  while (node[root].father) root = node[root].father;
  puts("YES");
  print(root);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) printf("%d", C[i][ans[j]]);
    printf("\n");
  }
  return 0;
}