#include <bits/stdc++.h>
using namespace std;
const int MXM = 31;
int M, A[MXM];
bool solved[71][32][2416];
int dp[71][32][2416];
vector<int> ds;
int solve(int i, int j, int k) {
  if (j == M) return k == i * (i - 1) / 2 ? i : 1e9;
  if (solved[i][j][k]) return dp[i][j][k];
  solved[i][j][k] = 1;
  dp[i][j][k] = 1e9;
  for (int x = 1; x + i <= 70; x++)
    if (k + A[j] * x >= (i + x) * (i + x - 1) / 2)
      dp[i][j][k] = min(dp[i][j][k], solve(x + i, j + 1, k + A[j] * x));
  return dp[i][j][k];
}
void gen(int i, int j, int k) {
  if (j == M) return;
  for (int x = 1; x + i <= 70; x++)
    if (k + A[j] * x >= (i + x) * (i + x - 1) / 2 &&
        solve(i, j, k) == solve(x + i, j + 1, k + A[j] * x)) {
      for (int z = 1; z <= x; z++) ds.push_back(A[j]);
      gen(x + i, j + 1, k + A[j] * x);
      return;
    }
}
const int MXV = 5000;
struct Edge {
  int u, v, c;
};
vector<Edge> E;
vector<int> edges[MXV] = {}, path_e;
bool visited[MXV] = {};
void add_edge(int u, int v, int c) {
  edges[u].push_back(E.size());
  E.push_back(Edge{u, v, c});
  edges[v].push_back(E.size());
  E.push_back(Edge{v, u, 0});
}
int dfs(int s, int t) {
  if (s == t) return 1;
  visited[s] = 1;
  for (int e : edges[s]) {
    int v = E[e].v;
    if (E[e].c && !visited[v] && dfs(v, t)) {
      path_e.push_back(e);
      return 1;
    }
  }
  return 0;
}
void clear_mf_aux(int &mnE) {
  mnE = 1e9;
  path_e.clear();
  memset((visited), 0, sizeof(visited));
}
int get_mf(int sink, int tank) {
  int mf = 0, mnE;
  clear_mf_aux(mnE);
  while (dfs(sink, tank)) {
    for (int e : path_e) mnE = min(mnE, E[e].c);
    for (int e : path_e) E[e].c -= mnE, E[e ^ 1].c += mnE;
    mf += mnE;
    clear_mf_aux(mnE);
  }
  return mf;
}
int g[71][71];
pair<int, int> pos[MXV];
int main() {
  cin >> M;
  for (int x = 0, qwe = M; x < qwe; x++) cin >> A[x];
  sort(A, A + M);
  int val = solve(0, 0, 0);
  if (val == (int)1e9) {
    cout << "=(\n";
    return 0;
  }
  cout << val << endl;
  gen(0, 0, 0);
  int sink = 0, tank = val + val * (val - 1) / 2 + 1, vcnt = val + 1;
  for (int x = 0, qwe = val; x < qwe; x++) {
    add_edge(sink, x + 1, ds[x]);
    for (int y = x + 1, qwe = val; y < qwe; y++)
      add_edge(x + 1, vcnt, 1), add_edge(y + 1, vcnt, 1),
          add_edge(vcnt, tank, 1), pos[vcnt] = {x, y}, vcnt++;
  }
  if (get_mf(sink, tank) < val * (val - 1) / 2) {
    cout << "=(\n";
    return 0;
  }
  for (int x = val + 1, qwe = tank; x < qwe; x++) {
    for (int e : edges[x])
      if (E[e].v - 1 < val)
        g[E[e].v - 1]
         [pos[x].first == E[e].v - 1 ? pos[x].second : pos[x].first] = E[e].c;
  }
  for (int x = 0, qwe = val; x < qwe; x++) {
    for (int y = 0, qwe = val; y < qwe; y++) {
      cout << g[x][y];
    }
    cout << "\n";
  }
}
