#include <bits/stdc++.h>
using namespace std;
int Arr[100000] = {0};
int size[100000] = {0};
int root(int i) {
  while (Arr[i] != i) {
    Arr[i] = Arr[Arr[i]];
    i = Arr[i];
  }
  return i;
}
void unin(int A, int B) {
  int root_A = root(A);
  int root_B = root(B);
  if (size[root_A] < size[root_B]) {
    Arr[root_A] = Arr[root_B];
    size[root_B] += size[root_A];
  } else {
    Arr[root_B] = Arr[root_A];
    size[root_A] += size[root_B];
  }
}
bool find(int A, int B) {
  if (root(A) == root(B))
    return true;
  else
    return false;
}
int main() {
  int n;
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    Arr[i] = i;
    size[i] = 1;
  }
  int a[n + 1];
  for (int i = 1; i <= n; ++i) cin >> a[i];
  string A[n + 1];
  for (int i = 1; i <= n; ++i) cin >> A[i];
  for (int i = 1; i <= n; ++i)
    for (int j = i; j <= n; ++j) {
      if (A[i][j] == '1') unin(i, j + 1);
    }
  vector<vector<int>> gr(n + 1);
  for (int i = 1; i <= n; ++i) {
    int d = root(i);
    gr[d].push_back(a[i]);
  }
  for (int i = 1; i <= n; ++i) {
    if (gr[i].size() != 0) sort(gr[i].begin(), gr[i].end());
  }
  for (int i = 1; i <= n; ++i) {
    int d = root(i);
    cout << gr[d].front() << " ";
    gr[d].erase(gr[d].begin());
  }
}
