#include <bits/stdc++.h>
using namespace std;
void INP();
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  if (0) return;
  cout << name << " : " << arg1 << '\n';
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  if (0) return;
  const char* comma = strchr(names + 1, ',');
  cout.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
long long int parent[301];
long long int rank_set[301];
long long int n;
void makeset() {
  for (long long int i = 0; i < n; i++) {
    parent[i] = i;
    rank_set[i] = 0;
  }
}
long long int find(long long int x) {
  if (parent[x] == x)
    return x;
  else
    return parent[x] = find(parent[x]);
}
void makeunion(long long int x, long long int y) {
  long long int a = find(x);
  long long int b = find(y);
  if (a == b) return;
  if (rank_set[a] >= rank_set[b]) {
    parent[b] = a;
    rank_set[a] += rank_set[b];
  } else {
    parent[a] = b;
    rank_set[b] += rank_set[a];
  }
}
void alpha() {
  cin >> n;
  long long int arr[n];
  for (long long int i = 0; i < n; i++) cin >> arr[i];
  string allowed[n];
  for (long long int i = 0; i < n; i++) {
    cin >> allowed[i];
  }
  makeset();
  for (long long int i = 0; i < n; i++) {
    for (long long int j = 0; j < allowed[i].size(); j++) {
      if (allowed[i][j] == '1') makeunion(i, j);
    }
  }
  for (long long int i = 0; i < n; i++) {
    for (long long int j = 0; j < n; j++) {
      if (i < j and arr[j] < arr[i] and find(i) == find(j)) {
        long long int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
      }
    }
  }
  for (long long int i = 0; i < n; i++) cout << arr[i] << " ";
  cout << '\n';
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  INP();
  long long int t = 1;
  while (t--) alpha();
  return 0;
}
inline void INP() {}
