#include <bits/stdc++.h>
using namespace std;
int n, m[400][400];
struct ent {
  int x;
  int p;
  int sz;
  ent() { sz = 0; }
  set<int> s;
};
ent a[400];
int pr(int i) {
  if (a[i].p == i) return i;
  a[i].p = pr(a[i].p);
  return a[i].p;
}
void join(int i, int j) { a[pr(i)].p = pr(j); }
int main() {
  cin >> n;
  bool flag = false;
  int i135, n135 = 0;
  int i140, n140 = 0;
  for (int i = 0; i < n; ++i) {
    cin >> a[i].x;
    a[i].p = i;
    if (a[i].x == 135)
      ++n135, i135 = i;
    else if (a[i].x == 140)
      ++n140, i140 = i;
  }
  string s;
  for (int i = 0; i < n; ++i) {
    cin >> s;
    for (int j = i + 1; j < n; ++j) {
      if (s[j] == '1') join(i, j);
    }
  }
  for (int i = 0; i < n; ++i) pr(i);
  for (int i = 0; i < n; ++i) {
    a[a[i].p].s.insert(a[i].x);
  }
  if (flag) {
    cout << a[i135].p << ":" << a[a[i135].p].x << " " << a[a[i135].p].p << ":"
         << a[a[a[i135].p].p].x << endl;
    cout << a[i140].p << ":" << a[a[i140].p].x << " " << a[a[i140].p].p << ":"
         << a[a[a[i140].p].p].x << endl;
    cout << a[21].p << ":" << a[a[21].p].x << " " << a[a[21].p].p << ":"
         << a[a[a[21].p].p].x << endl;
    cout << pr(i135) << ":" << a[pr(i135)].x << " " << pr(pr(i135)) << ":"
         << a[pr(pr(i135))].x << endl;
    cout << pr(i140) << ":" << a[pr(i140)].x << " " << pr(pr(i140)) << ":"
         << a[pr(pr(i140))].x << endl;
  }
  int pr;
  for (int i = 0; i < n; ++i) {
    pr = *(a[a[i].p].s.begin());
    printf("%d ", pr);
    a[a[i].p].s.erase(pr);
  }
  return 0;
}
