#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e2+5;
int n, m;
char a[maxn][maxn];
map<string, int> mask_to_idx;
string masks[maxn];
bool is_sub(string& a, string& b) {
for (int i = 1; i <= n; i++) {
if (a[i-1] < b[i-1]) return 0;
}
return 1;
}
int par[maxn];
int finds(int u) {
if (par[u] == u) return u;
return par[u] = finds(par[u]);
}
void unions(int u, int v) {
u = finds(u), v = finds(v);
if (u == v) return;
par[v] = u;
}
vector<int> adj[maxn<<1];
int vis[maxn<<1], visid = 0, match[maxn<<1], from[maxn<<1];
bool dfs(int u) {
for (int v : adj[u]) {
if (vis[v] == visid) continue;
vis[v] = visid;
if (!match[v] || dfs(match[v])) {
match[v] = u;
return 1;
}
}
return 0;
}
int groupid = 0;
vector<int> groups[maxn];
int belongs[maxn];
int pri[maxn][maxn];
int privilege[maxn];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
string s; cin >> s;
for (int j = 1; j <= m; j++) {
a[i][j] = s[j-1];
}
}
int id = 0;
for (int j = 1; j <= m; j++) {
string mask = "";
for (int i = 1; i <= n; i++) {
mask += a[i][j];
}
mask_to_idx[mask] = ++id;
masks[id] = mask;
}
for (int i = 1; i <= m; i++) par[i] = i;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= m; j++) {
if (i == j) continue;
if (masks[i] == masks[j]) {
unions(i, j);
}
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= m; j++) {
if (i == j) continue;
if (par[i] == i && par[j] == j && is_sub(masks[i], masks[j])) {
adj[i].push_back(j+m);
}
}
}
int ans = 0;
for (int i = 1; i <= m; i++) {
if (par[i] == i) ans++;
}
for (int i = 1; i <= m; i++) {
if (par[i] == i) {
visid++;
ans -= dfs(i);
}
}
for (int i = m+1; i <= 2*m; i++) {
if (par[i-m] == i-m) {
if (match[i]) {
from[match[i]] = i-m;
}
}
}
for (int i = m+1; i <= 2*m; i++) {
if (par[i-m] == i-m) {
if (!match[i]) {
int j = i-m;
groupid++;
while (j) {
groups[groupid].push_back(j);
belongs[j] = groupid;
j = from[j];
}
}
}
}
cout << groupid << "\n";
for (int i = 1; i <= m; i++) {
belongs[i] = belongs[finds(i)];
cout << belongs[i] << " ";
}
cout << "\n";
for (int g = 1; g <= groupid; g++) {
vector<pair<string, int>> vec;
for (int i = 1; i <= n; i++) {
string mask = "";
for (int j : groups[g]) {
mask += a[i][j];
}
vec.push_back({mask, i});
}
sort(vec.begin(), vec.end());
reverse(vec.begin(), vec.end());
int pre_pri = 505;
string s = vec[0].first;
pri[vec[0].second][g] = pre_pri - 1;
for (int k = 0; k < groups[g].size(); k++) {
int j = groups[g][k];
if (s[k] == '0') {
privilege[j] = pre_pri;
}
}
for (int i = 1; i < n; i++) {
s = vec[i].first;
if (s == vec[i-1].first) {
pri[vec[i].second][g] = pri[vec[i-1].second][g];
} else {
pre_pri--;
for (int k = 0; k < groups[g].size(); k++) {
int j = groups[g][k];
if (!privilege[j] && s[k] == '0') {
privilege[j] = pre_pri;
}
}
pri[vec[i].second][g] = pre_pri - 1;
}
}
for (int j : groups[g]) {
if (!privilege[j]) privilege[j] = 1;
}
}
for (int i = 1; i <= m; i++) {
if (privilege[i] == 0) {
privilege[i] = privilege[finds(i)];
}
cout << (privilege[i]) << " ";
}
cout << "\n";
for (int i = 1; i <= n; i++) {
for (int g = 1; g <= groupid; g++) {
cout << pri[i][g] << " ";
}
cout << "\n";
}
}