#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > grafo;
vector<bool> visitados;
vector<vector<int> > subG;
vector<int> tarj_low;
vector<int> tarj_num;
vector<int> pila;
vector<int> comp;
int cont, sol;
void TARJAN(int x) {
  tarj_low[x] = tarj_num[x] = cont++;
  pila.push_back(x);
  visitados[x] = true;
  for (int i = 0; i < (int)(grafo[x].size()); i++) {
    int v = grafo[x][i];
    if (tarj_num[v] == -1) TARJAN(v);
    if (visitados[v]) tarj_low[x] = min(tarj_low[x], tarj_low[v]);
  }
  if (tarj_low[x] == tarj_num[x]) {
    while (1) {
      int aux = pila.back();
      pila.pop_back();
      comp[aux] = sol;
      visitados[aux] = false;
      if (x == aux) break;
    }
    sol++;
  }
}
int main() {
  int n;
  cin >> n;
  vector<int> datos;
  for (int i = 0; i < (int)(n); i++) {
    int num;
    cin >> num;
    datos.push_back(num);
  }
  for (int i = 0; i < (int)(n); i++) {
    vector<int> aux;
    grafo.push_back(aux);
    subG.push_back(aux);
    comp.push_back(0);
    visitados.push_back(false);
    tarj_low.push_back(0);
    tarj_num.push_back(-1);
  }
  for (int i = 0; i < (int)(n); i++) {
    for (int j = 0; j < (int)(n); j++) {
      char aux;
      cin >> aux;
      int num = aux - '0';
      if (num == 1) grafo[i].push_back(j);
    }
  }
  for (int i = 0; i < (int)(n); i++) {
    if (tarj_num[i] == -1) {
      TARJAN(i);
    }
  }
  for (int i = 0; i < (int)(n); i++) {
    subG[comp[i]].push_back(i);
  }
  for (int i = 0; i < (int)(n); i++) {
    vector<int> orden;
    for (int j = 0; j < (int)(subG[i].size()); j++) {
      orden.push_back(datos[subG[i][j]]);
    }
    sort((orden).begin(), (orden).end());
    for (int j = 0; j < (int)(subG[i].size()); j++) {
      datos[subG[i][j]] = orden[j];
    }
  }
  for (int i = 0; i < (int)(n); i++) {
    if (i != 0) cout << " ";
    cout << datos[i];
  }
  cout << endl;
  return 0;
}
