#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll M = 1000000007;
const ll M1 = 998244353;
using vl = vector<ll>;
using pll = pair<ll, ll>;
ll power(ll x, ll y) {
  if (y == 0) return 1;
  ll res = power(x, y / 2);
  res = (res * res);
  if (y & 1) res = (res * x);
  return res;
}
ll powermod(ll x, ll y, ll mod) {
  if (y == 0) return 1;
  ll res = powermod(x, y / 2, mod);
  res = (res * res) % mod;
  if (y & 1) res = (res * x) % mod;
  return res;
}
ll findxor(ll a) {
  switch (a & 3) {
    case 0:
      return a;
    case 1:
      return 1;
    case 2:
      return a + 1;
    case 3:
      return 0;
  }
  return -1;
}
int n;
vector<int> visi;
vector<string> gr;
void dfs(int node, vector<int> &rec_visit) {
  visi[node] = 1;
  rec_visit.push_back(node);
  for (int con_node = 0; con_node < n; con_node++) {
    if (visi[con_node] || gr[node][con_node] == '0') continue;
    dfs(con_node, rec_visit);
  }
}
void solve() {
  cin >> n;
  int ans[n];
  for (int i = 0; i < n; i++) cin >> ans[i];
  gr.resize(n);
  visi.resize(n, 0);
  for (int i = 0; i < n; i++) cin >> gr[i];
  for (int i = 0; i < n; i++) {
    if (visi[i]) continue;
    vector<int> rec_visit;
    dfs(i, rec_visit);
    vector<int> val;
    for (int j = 0; j < rec_visit.size(); j++) val.push_back(ans[rec_visit[j]]);
    sort(val.begin(), val.end());
    sort(rec_visit.begin(), rec_visit.end());
    for (int j = 0; j < rec_visit.size(); j++) ans[rec_visit[j]] = val[j];
  }
  for (int i = 0; i < n; i++) cout << ans[i] << " ";
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int t = 1;
  for (int i = 1; i <= t; i++) {
    solve();
  }
  return 0;
}
