import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class NewYearPermutation {

	public static void main(String args[] ) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	    PrintWriter w = new PrintWriter(System.out);

	    int n = ip(br.readLine());

	    int a[] = new int[n];
	    StringTokenizer st2 = new StringTokenizer(br.readLine());
	    for(int i=0;i<n;i++)
	    	a[i] = ip(st2.nextToken());

	    char check[][] = new char[n][n];
	    for(int i=0;i<n;i++)
	    		check[i] = br.readLine().toCharArray();

	    int ans[] = new int[n];
	    boolean visited[] = new boolean[n];

	    for(int i=0;i<n;i++){
	    	if(visited[i] == false){

	    		ArrayList<Integer> temp2 = new ArrayList<Integer>();
	    			//bfs(i,temp2);

	    		LinkedList<Integer> q = new LinkedList();
	    		q.add(i);
	    		visited[i] = true;

	    		while(!q.isEmpty()){
	    			int curr = q.remove();
	    			temp2.add(curr);
	    			for(int j=0;j<n;j++)
	    				if(check[curr][j] == '1' && !visited[j]){
	    					q.add(j);
	    					visited[j] = true;
	    				}
	    		}

	    		int len = temp2.size();

	    		int temp[] = new int[len];
	    		for(int j=0;j<len;j++)
	    			temp[j] = a[temp2.get(j)];

	    		int temp3[] = new int[len];
	    		for(int j=0;j<len;j++)
	    			temp3[j] = temp2.get(j);

	    		Arrays.sort(temp);
	    		Arrays.sort(temp3);

	    		for(int j=0;j<len;j++)
	    			ans[temp3[j]] = temp[j];
	    	}
	    }

	    for(int i=0;i<n;i++)
	    	w.print(ans[i] + " ");

	    w.println();
	    w.close();
	}

	public static int ip(String s){
		return Integer.parseInt(s);
	}
}


import java.util.Scanner;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author marim
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		Scanner in = new Scanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskB solver = new TaskB();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskB {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n = in.nextInt();
        int[] p = new int[n];

        for (int i = 0; i < n; i++) {
            p[i] = in.nextInt();
        }

        boolean[][] t = new boolean[n][n];

        for (int i = 0; i < n; i++) {
            String s = in.next();
            for (int j = 0; j < s.length(); j++) {
                if (s.charAt(j) == '1') {
                    t[i][j] = true;
                }
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    if (t[i][j] && t[j][k]) {
                        t[i][k] = true;
                    }
                }
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (t[i][j] && p[i] > p[j]) {
                    int tmp = p[i];
                    p[i] = p[j];
                    p[j] = tmp;
                }
            }
        }

        for (int i = 0; i < n; i++) {
            out.print(p[i] + " ");
        }
        out.println();
    }
}


import java.util.Scanner;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author marim
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		Scanner in = new Scanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskB solver = new TaskB();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskB {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n = in.nextInt();
        int[] p = new int[n];

        for (int i = 0; i < n; i++) {
            p[i] = in.nextInt();
        }

        boolean[][] t = new boolean[n][n];

        for (int i = 0; i < n; i++) {
            String s = in.next();
            for (int j = 0; j < s.length(); j++) {
                if (s.charAt(j) == '1') {
                    t[i][j] = true;
                }
            }
        }

        for (int j = 0; j < n; j++) {
            for (int i = 0; i < n; i++) {
                for (int k = 0; k < n; k++) {
                    if (t[i][j] && t[j][k]) {
                        t[i][k] = true;
                    }
                }
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (t[i][j] && p[i] > p[j]) {
                    int tmp = p[i];
                    p[i] = p[j];
                    p[j] = tmp;
                }
            }
        }

        for (int i = 0; i < n; i++) {
            out.print(p[i] + " ");
        }
        out.println();
    }
}


import java.util.Scanner;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author marim
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		Scanner in = new Scanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskB solver = new TaskB();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskB {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n = in.nextInt();
        int[] p = new int[n];

        for (int i = 0; i < n; i++) {
            p[i] = in.nextInt();
        }

        boolean[][] t = new boolean[n][n];

        for (int i = 0; i < n; i++) {
            String s = in.next();
            for (int j = 0; j < s.length(); j++) {
                if (s.charAt(j) == '1') {
                    t[i][j] = true;
                }
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    if (t[i][j] && t[j][k]) {
                        t[i][k] = true;
                    }
                }
            }
        }

        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; j < n; j++) {
                    if (t[i][j] && p[i] > p[j]) {
                        int tmp = p[i];
                        p[i] = p[j];
                        p[j] = tmp;
                    }
                }
            }
        }

        for (int i = 0; i < n; i++) {
            out.print(p[i] + " ");
        }
        out.println();
    }
}


import java.util.Scanner;

public class Main {
    static final int MAX = Integer.MAX_VALUE;
    static int[] f = new int[1000];

    public static void main(String[] args) {
        Scanner io = new Scanner(System.in);
        int n = io.nextInt();

        int[] a = new int[n];
        for (int i = 0; i < n; i++, f[i] = i) a[i] = io.nextInt();

        for (int i = 0, fx, fy; i < n; i++) {
            String s = io.nextLine();
            while (s.length() == 0) s = io.nextLine();
            for (int j = 0; j < s.length(); j++)
                if (s.charAt(j) == '1') {
                    fx = find(i);
                    fy = find(j);
                    f[fx] = fy;
                }
        }

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (a[i] > a[j] && find(i) == find(j)) {
                    int t = a[i];
                    a[i] = a[j];
                    a[j] = t;
                }
            }
        }

        for (int i = 0; i < n; i++) System.out.print(a[i] + " ");
    }

    static int find(int x) {
        return f[x] == x ? x : (f[x] = find(f[x]));
    }

}


import java.util.Scanner;

public class Main {
    static final int MAX = Integer.MAX_VALUE;

    public static void main(String[] args) {
        Scanner io = new Scanner(System.in);
        int n = io.nextInt();

        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = io.nextInt();

        int[][] g = new int[n][n];
        for (int i = 0; i < n; i++) {
            String s = io.nextLine();
            while (s.length() == 0) s = io.nextLine();
            for (int j = 0; j < s.length(); j++) g[i][j] = s.charAt(j) - '0';
        }

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (a[i] > a[j] && g[i][j] == 1) {
                    int t = a[i];
                    a[i] = a[j];
                    a[j] = t;
                }
            }
        }

        for (int i = 0; i < n; i++) System.out.print(a[i]+" ");
    }

}


import java.util.Map;
import java.util.List;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.util.Stack;
import java.util.ArrayList;
import java.util.HashMap;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author saket
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		NewYearPermutation solver = new NewYearPermutation();
		solver.solve(1, in, out);
		out.close();
	}
}

class NewYearPermutation extends GraphDfs{
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int n=in.readInt();
        int p[]=new int[n];
        for(int i=0;i<n;i++)
            p[i]=in.readInt();
        GraphDfsSet(false,n);
        for(int i=0;i<n;i++)
        {
            String s=in.readLine();
            for(int j=0;j<s.length();j++)
                if(s.charAt(j)=='1')
                    insertEdge(i,j);
        }
        for(int i=0;i<n;i++)
        {
            Arrays.fill(visited,false);
            dfs(i);
            int max_ind=i;
            for(int j=i+1;j<n;j++)
            {
                if(visited[j]&&p[max_ind]>p[j])
                    max_ind=j;
            }
            int temp=p[max_ind];
            p[max_ind]=p[i];
            p[i]=temp;
        }
       for(int i=0;i<n;i++)
            out.print(p[i]+" ");
    }
    }

class GraphDfs {
    Map<Integer,List<Integer>> graph;
    static boolean  visited[];
    boolean biderectional=true;
    public void GraphDfsSet(boolean bi,int size)
    {
        biderectional=bi;
        graph=new HashMap<Integer, List<Integer>>();
        visited=new boolean[size+1];
    }
    public void insertEdge(int vertices,int edge) {
        List<Integer> li = graph.get(vertices);
        List<Integer> li1 = graph.get(edge);
        if(li==null)
        {
            li=new ArrayList<Integer>();
            graph.put(vertices,li);
        }
        if(biderectional)
        {
            if(li1==null)
            {
                li1=new ArrayList<Integer>();
                graph.put(edge,li1);
            }
            li.add(edge);
            li1.add(vertices);
        }else li.add(edge);
    }
    public void dfs(int start)
    {
        Stack<Integer> stack=new Stack<Integer>();
        stack.push(start);
        while(!stack.empty())
        {
            int visit=stack.pop();
            if(!visited[visit])
            {
                visited[visit]=true;
                List<Integer> li=graph.get(visit);
                if(li!=null)
                {
                    for(int i: li)
                      if(!visited[i])stack.push(i);
                }
            }
        }
    }
}

class InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    private String readLine0() {
        StringBuilder buf = new StringBuilder();
        int c = read();
        while (c != '\n' && c != -1) {
            if (c != '\r')
                buf.appendCodePoint(c);
            c = read();
        }
        return buf.toString();
    }

    public String readLine() {
        String s = readLine0();
        while (s.trim().length() == 0)
            s = readLine0();
        return s;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public void print(Object... objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }

    public void close() {
        writer.close();
    }

}


import java.util.Map;
import java.util.List;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.util.Stack;
import java.util.ArrayList;
import java.util.HashMap;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author saket
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		NewYearPermutation solver = new NewYearPermutation();
		solver.solve(1, in, out);
		out.close();
	}
}

class NewYearPermutation extends GraphDfs{
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int n=in.readInt();
        int p[]=new int[n];
        for(int i=0;i<n;i++)
            p[i]=in.readInt();
        GraphDfsSet(false,n);
        for(int i=0;i<n;i++)
        {
            String s=in.readLine();
            for(int j=0;j<s.length();j++)
                if(s.charAt(j)=='1')
                    insertEdge(i,j);
        }
        for(int i=0;i<n;i++)
        {
            Arrays.fill(visited,false);
            dfs(i);
            int max_ind=i;
            for(int j=i+1;j<n;j++)
            {
                if(visited[j]&&p[max_ind]>p[j])
                    max_ind=j;
            }
            int temp=p[max_ind];
            p[max_ind]=p[i];
            p[i]=temp;
        }
       for(int i=0;i<n;i++)
            out.print(p[i]+" ");
    }
    }

class GraphDfs {
    Map<Integer,List<Integer>> graph;
    static boolean  visited[];
    boolean biderectional=true;
    public void GraphDfsSet(boolean bi,int size)
    {
        biderectional=bi;
        graph=new HashMap<Integer, List<Integer>>();
        visited=new boolean[size+1];
    }
    public void insertEdge(int vertices,int edge) {
        List<Integer> li = graph.get(vertices);
        List<Integer> li1 = graph.get(edge);
        if(li==null)
        {
            li=new ArrayList<Integer>();
            graph.put(vertices,li);
        }
        if(biderectional)
        {
            if(li1==null)
            {
                li1=new ArrayList<Integer>();
                graph.put(edge,li1);
            }
            li.add(edge);
            li1.add(vertices);
        }else li.add(edge);
    }
    public void dfs(int start)
    {
        Stack<Integer> stack=new Stack<Integer>();
        stack.push(start);
        while(!stack.empty())
        {
            int visit=stack.pop();
            if(!visited[visit])
            {
                visited[visit]=true;
                List<Integer> li=graph.get(visit);
                if(li!=null)
                {
                    for(int i: li)
                      if(!visited[i])stack.push(i);
                }
            }
        }
    }
}

class InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    private String readLine0() {
        StringBuilder buf = new StringBuilder();
        int c = read();
        while (c != '\n' && c != -1) {
            if (c != '\r')
                buf.appendCodePoint(c);
            c = read();
        }
        return buf.toString();
    }

    public String readLine() {
        String s = readLine0();
        while (s.trim().length() == 0)
            s = readLine0();
        return s;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public void print(Object... objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }
    public void close() {
        writer.close();
    }
}


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

@SuppressWarnings("unused")
public class E {

	private static int N, M;
	private static int length=0;
//    private static int[] u, v, a, b, c;
    private static int itrt=0;
 //   private static long[][] dp;
 //    private static List<Integer> list=new ArrayList<Integer>();
//    private static List<Integer> res=new ArrayList<Integer>();
	public static void main(String[] args) {

		FastScanner sc = new FastScanner();
        N=sc.nextInt();
        List<Integer> list=new ArrayList<>();
        int A[][]=new int[310][310];
        List<List<Integer>> list2=new ArrayList<>();
        for(int i=0;i<N;i++){
        	list.add(sc.nextInt());
        }
        for(int i=0;i<N;i++){
        	Arrays.fill(A[i], 0);
        }
        for(int i=0;i<N;i++){
        	String s=sc.next();
        	for(int j=0;j<N;j++){
        		A[i][j]=s.charAt(j);
        	}
        }
        for(int k=0;k<N;k++){
        	for(int i=0;i<N;i++){
        		for(int j=0;j<N;j++){
        			if( (A[i][k]=='1' && A[k][j]=='1') || A[i][j]=='1')
        				A[i][j]='1';
        		}
        	}
        }
        while(true){
        	boolean swaped=false;
	        for(int i=0;i<N;i++){
	        	for(int j=0;j<N;j++){
	        		List<Integer> changeAbles=new ArrayList<>();
	        		if(A[i][j]=='1')
	        			changeAbles.add(list.get(j));
	        		if(!changeAbles.isEmpty()){
	        			boolean change=false;
	        			Integer minimum=Collections.min(changeAbles);
	        			if(minimum<list.get(i)){
	        				Collections.swap(list, i, j);
	        				swaped=true;
	        				break;
	        			}
	        		}
	        	}
	        }
	        if(!swaped)break;
        }
        for (int i=0;i<N-1;i++) {
			System.out.print(list.get(i)+" ");
		}
        System.out.println(list.get(N-1));

    }

	static class FastScanner {
	    private final InputStream in = System.in;
	    private final byte[] buffer = new byte[1024];
	    private int ptr = 0;
	    private int buflen = 0;
	    private boolean hasNextByte() {
	        if (ptr < buflen) {
	            return true;
	        }else{
	            ptr = 0;
	            try {
	                buflen = in.read(buffer);
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	            if (buflen <= 0) {
	                return false;
	            }
	        }
	        return true;
	    }
	    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
	    private boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
	    public String next() {
	        if (!hasNext()) throw new NoSuchElementException();
	        StringBuilder sb = new StringBuilder();
	        int b = readByte();
	        while(isPrintableChar(b)) {
	            sb.appendCodePoint(b);
	            b = readByte();
	        }
	        return sb.toString();
	    }
	    public long nextLong() {
	        if (!hasNext()) throw new NoSuchElementException();
	        long n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	    public int nextInt() {
	        if (!hasNext()) throw new NoSuchElementException();
	        int n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

@SuppressWarnings("unused")
public class E {

	private static int N, M;
	private static int min,max,now;
	private static int minIt,maxIt,startIt;
	private static int length=0;
//    private static int[] u, v, a, b, c;
    private static int itrt=0;
 //   private static long[][] dp;
    private static int vec[]=new int[100001];
//    private static List<Integer> list=new ArrayList<Integer>();
//    private static List<Integer> res=new ArrayList<Integer>();
	public static void main(String[] args) {

		FastScanner sc = new FastScanner();
        N=sc.nextInt();
        List<Integer> list=new ArrayList<>();
        int A[][]=new int[310][310];
        List<List<Integer>> list2=new ArrayList<>();
        for(int i=0;i<N;i++){
        	list.add(sc.nextInt());
        }
        for(int i=0;i<N;i++){
        	Arrays.fill(A[i], 0);
        }
        for(int i=0;i<N;i++){
        	String s=sc.next();
        	for(int j=0;j<N;j++){
        		A[i][j]=s.charAt(j);
        	}
        }
        for(int i=0;i<N;i++){
        	list2.add(new ArrayList<>());
        }
        for(int i=0;i<N;i++){
        	for(int j=0;j<N;j++){
        		if(A[i][j]=='1'){
        			if(i<j) list2.get(i).add(j);
        			else list2.get(j).add(i);
        		}
        	}
        }
        while(true){
        	boolean swaped=false;
	        for(int i=0;i<N;i++){
	        	for (Integer j : list2.get(i)) {
					if(list.get(i)>list.get(j)){
						Collections.swap(list, i, j);
						swaped=true;
					}
				}
	        }
	        if(!swaped)break;
        }
        for (int i=0;i<N-1;i++) {
			System.out.print(list.get(i)+" ");
		}
        System.out.println(list.get(N-1));

    }

	static class FastScanner {
	    private final InputStream in = System.in;
	    private final byte[] buffer = new byte[1024];
	    private int ptr = 0;
	    private int buflen = 0;
	    private boolean hasNextByte() {
	        if (ptr < buflen) {
	            return true;
	        }else{
	            ptr = 0;
	            try {
	                buflen = in.read(buffer);
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	            if (buflen <= 0) {
	                return false;
	            }
	        }
	        return true;
	    }
	    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
	    private boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
	    public String next() {
	        if (!hasNext()) throw new NoSuchElementException();
	        StringBuilder sb = new StringBuilder();
	        int b = readByte();
	        while(isPrintableChar(b)) {
	            sb.appendCodePoint(b);
	            b = readByte();
	        }
	        return sb.toString();
	    }
	    public long nextLong() {
	        if (!hasNext()) throw new NoSuchElementException();
	        long n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	    public int nextInt() {
	        if (!hasNext()) throw new NoSuchElementException();
	        int n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

@SuppressWarnings("unused")
public class E {

	private static int N, M;
	private static int length=0;
//    private static int[] u, v, a, b, c;
    private static int itrt=0;
 //   private static long[][] dp;
 //    private static List<Integer> list=new ArrayList<Integer>();
//    private static List<Integer> res=new ArrayList<Integer>();
	public static void main(String[] args) {

		FastScanner sc = new FastScanner();
        N=sc.nextInt();
        List<Integer> list=new ArrayList<>();
        int A[][]=new int[310][310];
        List<List<Integer>> list2=new ArrayList<>();
        for(int i=0;i<N;i++){
        	list.add(sc.nextInt());
        }
        for(int i=0;i<N;i++){
        	Arrays.fill(A[i], 0);
        }
        for(int i=0;i<N;i++){
        	String s=sc.next();
        	for(int j=0;j<N;j++){
        		A[i][j]=s.charAt(j);
        	}
        }
        for(int k=0;k<N;k++){
        	for(int i=0;i<N;i++){
        		for(int j=0;j<N;j++){
        			if( (A[i][k]=='1' && A[k][j]=='1') || A[i][j]=='1')
        				A[i][j]='1';
        		}
        	}
        }
       // while(true){
        	boolean swaped=false;
	        for(int i=0;i<N;i++){
        		List<Integer> changeAbles=new ArrayList<>();
	        	for(int j=0;j<N;j++){
	        		if(A[i][j]=='1')
	        			changeAbles.add(list.get(j));
	        	}
	        	if(!changeAbles.isEmpty()){
        			//boolean change=false;
        			Integer minimum=Collections.min(changeAbles);
        			int indexOfmininum=list.indexOf(minimum);
        			if(minimum<list.get(i)){
        				Collections.swap(list, i, indexOfmininum);
        				swaped=true;
        				break;
        			}
        		}
	        }
	   //     if(!swaped)break;
      //  }
        for (int i=0;i<N-1;i++) {
			System.out.print(list.get(i)+" ");
		}
        System.out.println(list.get(N-1));

    }

	static class FastScanner {
	    private final InputStream in = System.in;
	    private final byte[] buffer = new byte[1024];
	    private int ptr = 0;
	    private int buflen = 0;
	    private boolean hasNextByte() {
	        if (ptr < buflen) {
	            return true;
	        }else{
	            ptr = 0;
	            try {
	                buflen = in.read(buffer);
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	            if (buflen <= 0) {
	                return false;
	            }
	        }
	        return true;
	    }
	    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
	    private boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
	    public String next() {
	        if (!hasNext()) throw new NoSuchElementException();
	        StringBuilder sb = new StringBuilder();
	        int b = readByte();
	        while(isPrintableChar(b)) {
	            sb.appendCodePoint(b);
	            b = readByte();
	        }
	        return sb.toString();
	    }
	    public long nextLong() {
	        if (!hasNext()) throw new NoSuchElementException();
	        long n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	    public int nextInt() {
	        if (!hasNext()) throw new NoSuchElementException();
	        int n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

@SuppressWarnings("unused")
public class E {

	private static int N, M;
	private static int min,max,now;
	private static int minIt,maxIt,startIt;
	private static int length=0;
//    private static int[] u, v, a, b, c;
    private static int itrt=0;
 //   private static long[][] dp;
    private static int vec[]=new int[100001];
//    private static List<Integer> list=new ArrayList<Integer>();
//    private static List<Integer> res=new ArrayList<Integer>();
	public static void main(String[] args) {

		FastScanner sc = new FastScanner();
        N=sc.nextInt();
        List<Integer> list=new ArrayList<>();
        int A[][]=new int[310][310];
        List<List<Integer>> list2=new ArrayList<>();
        for(int i=0;i<N;i++){
        	list.add(sc.nextInt());
        }
        for(int i=0;i<N;i++){
        	Arrays.fill(A[i], 0);
        }
        for(int i=0;i<N;i++){
        	String s=sc.next();
        	for(int j=0;j<N;j++){
        		A[i][j]=s.charAt(j);
        	}
        }
        for(int i=0;i<N;i++){
        	list2.add(new ArrayList<>());
        }
        for(int i=0;i<N;i++){
        	for(int j=0;j<N;j++){
        		if(A[i][j]=='1'){
        			if(i<j) list2.get(i).add(j);
        			else list2.get(j).add(i);
        		}
        	}
        }
        while(true){
        	boolean swaped=false;
	        for(int i=0;i<N;i++){
	        	int min=Integer.MAX_VALUE;
	        	int minIndex=-1;
	        	for(Integer j:list2.get(i)){
	        		if(min>list.get(j)){
	        			min=list.get(j);
	        			minIndex=j;
	        		}
	        	}
	        	if(minIndex!=-1){
					if(list.get(i)>list.get(minIndex)){
						Collections.swap(list, i, minIndex);
						swaped=true;
					}
	        	}
	        }
	        if(!swaped)break;
        }
        for (int i=0;i<N-1;i++) {
			System.out.print(list.get(i)+" ");
		}
        System.out.println(list.get(N-1));

    }

	static class FastScanner {
	    private final InputStream in = System.in;
	    private final byte[] buffer = new byte[1024];
	    private int ptr = 0;
	    private int buflen = 0;
	    private boolean hasNextByte() {
	        if (ptr < buflen) {
	            return true;
	        }else{
	            ptr = 0;
	            try {
	                buflen = in.read(buffer);
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	            if (buflen <= 0) {
	                return false;
	            }
	        }
	        return true;
	    }
	    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
	    private boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
	    public String next() {
	        if (!hasNext()) throw new NoSuchElementException();
	        StringBuilder sb = new StringBuilder();
	        int b = readByte();
	        while(isPrintableChar(b)) {
	            sb.appendCodePoint(b);
	            b = readByte();
	        }
	        return sb.toString();
	    }
	    public long nextLong() {
	        if (!hasNext()) throw new NoSuchElementException();
	        long n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	    public int nextInt() {
	        if (!hasNext()) throw new NoSuchElementException();
	        int n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

@SuppressWarnings("unused")
public class E {

	private static int N, M;
	private static int length=0;
//    private static int[] u, v, a, b, c;
    private static int itrt=0;
 //   private static long[][] dp;
 //    private static List<Integer> list=new ArrayList<Integer>();
//    private static List<Integer> res=new ArrayList<Integer>();
	public static void main(String[] args) {

		FastScanner sc = new FastScanner();
        N=sc.nextInt();
        List<Integer> list=new ArrayList<>();
        int A[][]=new int[310][310];
      //  List<List<Integer>> list2=new ArrayList<>();
        for(int i=0;i<N;i++){
        	list.add(sc.nextInt());
        }
        for(int i=0;i<N;i++){
        	Arrays.fill(A[i], 0);
        }
        for(int i=0;i<N;i++){
        	String s=sc.next();
        	for(int j=0;j<N;j++){
        		A[i][j]=s.charAt(j);
        	}
        }
        for(int k=0;k<N;k++){
        	for(int i=0;i<N;i++){
        		for(int j=0;j<N;j++){
        			if( (A[i][k]=='1' && A[k][j]=='1') || A[i][j]=='1')
        				A[i][j]='1';
        		}
        	}
        }
        while(true){
        	boolean swaped=false;
	        for(int i=0;i<N;i++){
	        	int minimum=Integer.MAX_VALUE;
	        	int minIndex=-1;
        		for(int j=i+1;j<N;j++){
        			if(A[i][j]=='1' && list.get(j)<minimum){
        				minimum=list.get(j);
        				minIndex=j;
        			}
        		}
        		if(minimum<list.get(i) ){
        			Collections.swap(list, i, minIndex);
        			swaped=true;
        		}
	        }
	        if(!swaped)break;
        }
        for (int i=0;i<N-1;i++) {
			System.out.print(list.get(i)+" ");
		}
        System.out.println(list.get(N-1));

    }

	static class FastScanner {
	    private final InputStream in = System.in;
	    private final byte[] buffer = new byte[1024];
	    private int ptr = 0;
	    private int buflen = 0;
	    private boolean hasNextByte() {
	        if (ptr < buflen) {
	            return true;
	        }else{
	            ptr = 0;
	            try {
	                buflen = in.read(buffer);
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	            if (buflen <= 0) {
	                return false;
	            }
	        }
	        return true;
	    }
	    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
	    private boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
	    public String next() {
	        if (!hasNext()) throw new NoSuchElementException();
	        StringBuilder sb = new StringBuilder();
	        int b = readByte();
	        while(isPrintableChar(b)) {
	            sb.appendCodePoint(b);
	            b = readByte();
	        }
	        return sb.toString();
	    }
	    public long nextLong() {
	        if (!hasNext()) throw new NoSuchElementException();
	        long n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	    public int nextInt() {
	        if (!hasNext()) throw new NoSuchElementException();
	        int n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

@SuppressWarnings("unused")
public class E {

	private static int N, M;
	private static int length=0;
//    private static int[] u, v, a, b, c;
    private static int itrt=0;
 //   private static long[][] dp;
 //    private static List<Integer> list=new ArrayList<Integer>();
//    private static List<Integer> res=new ArrayList<Integer>();
	public static void main(String[] args) {

		FastScanner sc = new FastScanner();
        N=sc.nextInt();
        List<Integer> list=new ArrayList<>();
        int A[][]=new int[310][310];
      //  List<List<Integer>> list2=new ArrayList<>();
        for(int i=0;i<N;i++){
        	list.add(sc.nextInt());
        }
        for(int i=0;i<N;i++){
        	Arrays.fill(A[i], 0);
        }
        for(int i=0;i<N;i++){
        	String s=sc.next();
        	for(int j=0;j<N;j++){
        		A[i][j]=s.charAt(j);
        	}
        }
        for(int k=0;k<N;k++){
        	for(int i=0;i<N;i++){
        		for(int j=0;j<N;j++){
        			if( (A[i][k]=='1' && A[k][j]=='1') || A[i][j]=='1')
        				A[i][j]='1';
        		}
        	}
        }
        //while(true){
        	boolean swaped=false;
	        for(int i=0;i<N;i++){
	        	int minimum=Integer.MAX_VALUE;
	        	int minIndex=-1;
        		for(int j=i+1;j<N;j++){
        			if(A[i][j]=='1' && list.get(j)<minimum){
        				minimum=list.get(j);
        				minIndex=j;
        			}
        		}
        		if(minimum<list.get(i) ){
        			Collections.swap(list, i, minIndex);
        			swaped=true;
        		}
	        }
	  //      if(!swaped)break;
      //  }
        for (int i=0;i<N-1;i++) {
			System.out.print(list.get(i)+" ");
		}
        System.out.println(list.get(N-1));

    }

	static class FastScanner {
	    private final InputStream in = System.in;
	    private final byte[] buffer = new byte[1024];
	    private int ptr = 0;
	    private int buflen = 0;
	    private boolean hasNextByte() {
	        if (ptr < buflen) {
	            return true;
	        }else{
	            ptr = 0;
	            try {
	                buflen = in.read(buffer);
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	            if (buflen <= 0) {
	                return false;
	            }
	        }
	        return true;
	    }
	    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
	    private boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
	    public String next() {
	        if (!hasNext()) throw new NoSuchElementException();
	        StringBuilder sb = new StringBuilder();
	        int b = readByte();
	        while(isPrintableChar(b)) {
	            sb.appendCodePoint(b);
	            b = readByte();
	        }
	        return sb.toString();
	    }
	    public long nextLong() {
	        if (!hasNext()) throw new NoSuchElementException();
	        long n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	    public int nextInt() {
	        if (!hasNext()) throw new NoSuchElementException();
	        int n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

@SuppressWarnings("unused")
public class E {

	private static int N, M;
	private static int min,max,now;
	private static int minIt,maxIt,startIt;
	private static int length=0;
//    private static int[] u, v, a, b, c;
    private static int itrt=0;
 //   private static long[][] dp;
    private static int vec[]=new int[100001];
//    private static List<Integer> list=new ArrayList<Integer>();
//    private static List<Integer> res=new ArrayList<Integer>();
	public static void main(String[] args) {

		FastScanner sc = new FastScanner();
        N=sc.nextInt();
        List<Integer> list=new ArrayList<>();
        int A[][]=new int[310][310];
        List<List<Integer>> list2=new ArrayList<>();
        for(int i=0;i<N;i++){
        	list.add(sc.nextInt());
        }
        for(int i=0;i<N;i++){
        	Arrays.fill(A[i], 0);
        }
        for(int i=0;i<N;i++){
        	String s=sc.next();
        	for(int j=0;j<N;j++){
        		A[i][j]=s.charAt(j);
        	}
        }
        for(int i=0;i<N;i++){
        	list2.add(new ArrayList<>());
        }
        for(int i=0;i<N;i++){
        	for(int j=0;j<N;j++){
        		if(A[i][j]=='1'){
        			if(i<j) list2.get(i).add(j);
        			else list2.get(j).add(i);
        		}
        	}
        }
        while(true){
        	boolean swaped=false;
	        for(int i=0;i<N;i++){
	        	int min=Integer.MAX_VALUE;
	        	int minIndex=-1;
	        	for(Integer j:list2.get(i)){
	        		if(min>list.get(j)){}
	        	}
	        	for (Integer j : list2.get(i)) {
					if(list.get(i)>list.get(j) && i<j){
						Collections.swap(list, i, j);
						swaped=true;
					}
				}
	        }
	        if(!swaped)break;
        }
        for (int i=0;i<N-1;i++) {
			System.out.print(list.get(i)+" ");
		}
        System.out.println(list.get(N-1));

    }

	static class FastScanner {
	    private final InputStream in = System.in;
	    private final byte[] buffer = new byte[1024];
	    private int ptr = 0;
	    private int buflen = 0;
	    private boolean hasNextByte() {
	        if (ptr < buflen) {
	            return true;
	        }else{
	            ptr = 0;
	            try {
	                buflen = in.read(buffer);
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	            if (buflen <= 0) {
	                return false;
	            }
	        }
	        return true;
	    }
	    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
	    private boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
	    public String next() {
	        if (!hasNext()) throw new NoSuchElementException();
	        StringBuilder sb = new StringBuilder();
	        int b = readByte();
	        while(isPrintableChar(b)) {
	            sb.appendCodePoint(b);
	            b = readByte();
	        }
	        return sb.toString();
	    }
	    public long nextLong() {
	        if (!hasNext()) throw new NoSuchElementException();
	        long n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	    public int nextInt() {
	        if (!hasNext()) throw new NoSuchElementException();
	        int n = 0;
	        boolean minus = false;
	        int b = readByte();
	        if (b == '-') {
	            minus = true;
	            b = readByte();
	        }
	        if (b < '0' || '9' < b) {
	            throw new NumberFormatException();
	        }
	        while(true){
	            if ('0' <= b && b <= '9') {
	                n *= 10;
	                n += b - '0';
	            }else if(b == -1 || !isPrintableChar(b)){
	                return minus ? -n : n;
	            }else{
	                throw new NumberFormatException();
	            }
	            b = readByte();
	        }
	    }
	}
}


import java.io.*;
import java.util.*;

public class Solution {

    BufferedReader br;
    PrintWriter out;
    StringTokenizer st;
    boolean eof;

    static final int Mod=1000000007;

    void solve() throws IOException {
        int n=nextInt();
        int a[]=new int[n];
        for (int i = 0; i < n; i++) {
            a[i]=nextInt()-1;
        }
        String s[]=new String[n];
        int d[][]=new int[n][n];
        for (int i = 0; i < n; i++) {
            s[i]=nextString();
            for (int j = 0; j < n; j++) {
                if(s[i].charAt(j)=='1' || i==j) d[i][j]=1;
            }

        }
        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if(d[i][k]==1 && d[k][j]==1) d[i][j]=1;
                }
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = i+1; j < n; j++) {
                if(d[i][j]==1 && a[i]>a[j]) {
                    int tmp=a[i];
                    a[i]=a[j];
                    a[j]=tmp;
                }
            }
        }
        for (int i = 0; i < n; i++) {
            out.print((a[i]+1)+" ");
        }
    }

    Solution() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Solution();
    }

    String nextToken() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                eof = true;
                return null;
            }
        }
        return st.nextToken();
    }

    String nextString() {
        try {
            return br.readLine();
        } catch (IOException e) {
            eof = true;
            return null;
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }
}


import java.io.*;
import java.util.*;

public class Solution {

    BufferedReader br;
    PrintWriter out;
    StringTokenizer st;
    boolean eof;

    static final int Mod=1000000007;

    List<Integer> pos;
    List<Integer> num;
    int n,a[],vis[],res[];
    String s[];

    void solve() throws IOException {
        n=nextInt();
        a=new int[n];
        for (int i = 0; i < n; i++) {
            a[i]=nextInt()-1;
        }
        s=new String[n];
        for (int i = 0; i < n; i++) {
            s[i]=nextString();
        }
        vis=new int[n];
        res=new int[n];
        pos=new ArrayList<Integer>();
        num=new ArrayList<Integer>();
        for (int i = 0; i < n; i++) {
            if(vis[i]==0) {
                dfs(i);
                Collections.sort(num);
                Collections.sort(pos);
                for (int j = 0; j < pos.size(); j++) {
                    res[pos.get(j)]=num.get(j);
                }
                num.clear();
                pos.clear();
            }
        }
        for (int i = 0; i < n; i++) {
            out.print(res[i]+1+" ");
        }
    }

    void dfs(int x) {
        vis[x]=1;
        pos.add(x);
        num.add(a[x]);
        for (int i = 0; i < n; i++) {
            if(s[x].charAt(i)=='1' && vis[i]==0) dfs(i);
        }
    }

    Solution() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Solution();
    }

    String nextToken() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                eof = true;
                return null;
            }
        }
        return st.nextToken();
    }

    String nextString() {
        try {
            return br.readLine();
        } catch (IOException e) {
            eof = true;
            return null;
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }
}


import java.io.*;
import java.util.*;

public class Solution {

    BufferedReader br;
    PrintWriter out;
    StringTokenizer st;
    boolean eof;

    static final int Mod=1000000007;

    int n,a[],vis[],res[],p[];
    String s[];

    void solve() throws IOException {
        n=nextInt();
        a=new int[n];
        p=new int[n];
        for (int i = 0; i < n; i++) {
            a[i]=nextInt()-1;
            p[i]=i;
        }
        s=new String[n];
        for (int i = 0; i < n; i++) {
            s[i]=nextString();
            for (int j = 0; j < n; j++) {
                if(s[i].charAt(j)=='1') {
                    int x=parent(i);
                    int y=parent(j);
                    if(x!=y) p[x]=y;
                }
            }
        }
        res=new int[n];
        vis=new int[n];
        for (int i = 0; i < n; i++) {
            if(vis[i]==0) {
                vis[i]=1;
                List<Integer> num=new ArrayList<Integer>();
                List<Integer> pos=new ArrayList<Integer>();
                num.add(a[i]);
                pos.add(i);
                for (int j = 0; j < n; j++) {
                    if (parent(i) == parent(j) && i!=j) {
                        vis[j]=0;
                        num.add(a[j]);
                        pos.add(j);
                    }
                }
                Collections.sort(num);
                Collections.sort(pos);
                for (int k = 0; k < pos.size(); k++) {
                    res[pos.get(k)]=num.get(k);
                }
            }
        }
        for(int i:res) {
            out.print((i+1)+" ");
        }
    }

    private int parent(int x) {
        while(p[x]!=x) {
            x=p[x];
        }
        return x;
    }

    Solution() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Solution();
    }

    String nextToken() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                eof = true;
                return null;
            }
        }
        return st.nextToken();
    }

    String nextString() {
        try {
            return br.readLine();
        } catch (IOException e) {
            eof = true;
            return null;
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }
}


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;

public class sol {
	static HashMap<Integer,Integer> map=new HashMap<Integer,Integer>();
	static HashMap<Integer,Integer> map1=new HashMap<Integer,Integer>();

	public static void main(String args[]){

		Scanner sc=new Scanner(System.in);
		int n=Integer.parseInt(sc.nextLine());
		String s[]=sc.nextLine().split(" ");
		for(int i=0;i<n;i++){
			map.put(Integer.parseInt(s[i]),i);
		}
		int mat[][]=new int[n][n];

		for(int i=0;i<n;i++){
			String[] si=sc.nextLine().split("");
			for(int j=0;j<n;j++){
			mat[i][j]=Integer.parseInt(si[j]);
			}
		}

		String str=graph(mat);
		System.out.println(str);
	}

	public static String graph(int[][] mat){
		int ar[]=new int[mat.length];
		int[][] reach=transitiveClosure(mat);
		int location[]=new int[mat.length];
		Arrays.fill(location,0);
		for(int i=1;i<mat.length+1;i++){
			int ans=check(reach,location,map.get(i));
			location[ans]=1;
			//System.out.println(i+" "+ans);
			map1.put(ans,i);
		}

		for(int i=0;i<mat.length;i++){
			//System.out.println(map1.get(i));
			ar[i]=map1.get(i);
		}

		String s="";
		s=s+ar[0];
		for(int i=1;i<ar.length;i++){
			s=s+" "+ar[i];
		}

		return s;
	}

public static int check(int[][] mat,int[] location,int index){
	for(int i=0;i<mat.length;i++){
		if(location[i]==0  && mat[index][i]>0){
			//location[i]=1;
			return i;
		}
	}
	return index;

}
	public static int[][] transitiveClosure(int graph[][])
    {
        /* reach[][] will be the output matrix that will finally
           have the shortest  distances between every pair of
           vertices */
		int V=graph.length;
        int reach[][] = new int[V][V];
        int  i, j, k;

        /*
	tion matrix same as input graph
    matrix. Or  we can say the initial values of shortest
    distances are based  on shortest paths considering
    no intermediate vertex. */
 for (i = 0; i < V; i++)
     for (j = 0; j < V; j++)
         reach[i][j] = graph[i][j];

 /* Add all vertices one by one to the set of intermediate
    vertices.
   ---> Before start of a iteration, we have reachability
        values for all  pairs of vertices such that the
        reachability values consider only the vertices in
        set {0, 1, 2, .. k-1} as intermediate vertices.
   ----> After the end of a iteration, vertex no. k is
         added to the set of intermediate vertices and the
         set becomes {0, 1, 2, .. k} */
 for (k = 0; k < V; k++)
 {
     // Pick all vertices as source one by one
     for (i = 0; i < V; i++)
     {
         // Pick all vertices as destination for the
         // above picked source
         for (j = 0; j < V; j++)
         {
             // If vertex k is on a path from i to j,
             // then make sure that the value of reach[i][j] is 1
             reach[i][j] = (reach[i][j]!=0) ||
                      ((reach[i][k]!=0) && (reach[k][j]!=0))?1:0;
         }
     }
 }

 return reach;
}

}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.Set;

public class Main
{
	public void foo()
	{
		MyScanner scan = new MyScanner();
		int n = scan.nextInt();
		int[] p = new int[n];
		for(int i = 0;i < n;++i)
		{
			p[i] = scan.nextInt();
		}
		ArrayList<Swap> arr = new ArrayList<Swap>();
		for(int i = 0;i < n;++i)
		{
			String s = scan.next();
			for(int j = i + 1;j < n;++j)
			{
				if('1' == s.charAt(j))
				{
					arr.add(new Swap(i, j));
				}
			}
		}
		while(true)
		{
			boolean hasSwap = false;
			for(Swap sp : arr)
			{
				if(p[sp.u] > p[sp.v])
				{
					hasSwap = true;
					int tmp = p[sp.u];
					p[sp.u] = p[sp.v];
					p[sp.v] = tmp;
				}
			}
			if(!hasSwap)
			{
				break;
			}
		}
		PrintWriter out = new PrintWriter(System.out);
		for(int i = 0;i < n;++i)
		{
			out.print(p[i] + " ");
		}
		out.close();
	}

	public static void main(String[] args)
	{
		new Main().foo();
	}

	class Swap
	{
		private int u;
		private int v;
		public Swap(int aU, int aV)
		{
			u = aU;
			v = aV;
		}
	}

	class MyScanner
	{
	    private byte[] buf = new byte[1024];
	    private int curChar;
	    private int numChars;
	    BufferedInputStream bis = new BufferedInputStream(System.in);

	    public int read()
	    {
	        if (-1 == numChars)
	        {
	        	throw new InputMismatchException();
	        }
	        if (curChar >= numChars)
	        {
	            curChar = 0;
	            try
	            {
	                numChars = bis.read(buf);
	            }
	            catch (IOException e)
	            {
	                throw new InputMismatchException();
	            }
	            if (numChars <= 0)
	            {
	            	return -1;
	            }
	        }
	        return buf[curChar++];
	    }

	    public int nextInt()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        int sgn = 1;
	        if (c == '-')
	        {
	            sgn = -1;
	            c = read();
	        }
	        int res = 0;
	        do
	        {
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c - '0';
	            c = read();
	        } while (!isSpaceChar(c));
	        return res * sgn;
	    }

	    public String next()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        StringBuilder res = new StringBuilder();
	        do
	        {
	            res.appendCodePoint(c);
	            c = read();
	        } while (!isSpaceChar(c));
	        return res.toString();
	    }

	    private boolean isSpaceChar(int c)
	    {
	        return ' ' == c || '\n' == c || '\r' == c || '\t' == c || -1 == c;
	    }
	}
}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.Set;

public class Main
{
	private ArrayList<Integer>[] edge;
	private boolean[] vis;
	private int[] mark;
	private int cnt;

	public void dfs(int u, int pre)
	{
		mark[u] = cnt;
		vis[u] = true;
		for(Integer v : edge[u])
		{
			if(v != pre && !vis[v])
			{
				dfs(v, u);
			}
		}
	}

	public void foo()
	{
		MyScanner scan = new MyScanner();
		int n = scan.nextInt();
		int[] a = new int[n];
		for(int i = 0;i < n;++i)
		{
			a[i] = scan.nextInt();
		}
		edge = new ArrayList[n];
		for(int i = 0;i < n;++i)
		{
			edge[i] = new ArrayList<Integer>();
			String s = scan.next();
			for(int j = 0;j < n;++j)
			{
				if('1' == s.charAt(j))
				{
					edge[i].add(j);
				}
			}
		}
		mark = new int[n];
		cnt = 1;
		vis = new boolean[n];
		for(int i = 0;i < n;++i)
		{
			if(0 == mark[i])
			{
				dfs(i, -1);
				++cnt;
			}
		}
		PrintWriter out = new PrintWriter(System.out);
		Arrays.fill(vis, false);
		for(int i = 0;i < n;++i)
		{
			int minValue = Integer.MAX_VALUE;
			int k = -1;
			for(int j = 0;j < n;++j)
			{
				if(mark[j] == mark[i] && !vis[j] && a[j] < minValue)
				{
					k = j;
					minValue = a[j];
				}
			}
			vis[k] = true;
			out.print(minValue + " ");
		}
		out.close();
	}

	public static void main(String[] args)
	{
		new Main().foo();
	}

	class MyScanner
	{
	    private byte[] buf = new byte[1024];
	    private int curChar;
	    private int numChars;
	    BufferedInputStream bis = new BufferedInputStream(System.in);

	    public int read()
	    {
	        if (-1 == numChars)
	        {
	        	throw new InputMismatchException();
	        }
	        if (curChar >= numChars)
	        {
	            curChar = 0;
	            try
	            {
	                numChars = bis.read(buf);
	            }
	            catch (IOException e)
	            {
	                throw new InputMismatchException();
	            }
	            if (numChars <= 0)
	            {
	            	return -1;
	            }
	        }
	        return buf[curChar++];
	    }

	    public int nextInt()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        int sgn = 1;
	        if (c == '-')
	        {
	            sgn = -1;
	            c = read();
	        }
	        int res = 0;
	        do
	        {
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c - '0';
	            c = read();
	        } while (!isSpaceChar(c));
	        return res * sgn;
	    }

	    public String next()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        StringBuilder res = new StringBuilder();
	        do
	        {
	            res.appendCodePoint(c);
	            c = read();
	        } while (!isSpaceChar(c));
	        return res.toString();
	    }

	    private boolean isSpaceChar(int c)
	    {
	        return ' ' == c || '\n' == c || '\r' == c || '\t' == c || -1 == c;
	    }
	}
}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.Set;

public class Main
{
	private int[] p;
	private ArrayList<Integer>[] edge;
	private boolean[] vis;
	private int minPos;

	public void dfs(int u)
	{
		vis[u] = true;
		for(Integer v : edge[u])
		{
			if(!vis[v])
			{
				if(p[v] < p[minPos])
				{
					minPos = v;
				}
				dfs(v);
			}
		}
	}

	public void foo()
	{
		MyScanner scan = new MyScanner();
		int n = scan.nextInt();
		p = new int[n];
		for(int i = 0;i < n;++i)
		{
			p[i] = scan.nextInt();
		}
		edge = new ArrayList[n];
		for(int i = 0;i < n;++i)
		{
			edge[i] = new ArrayList<Integer>();
			String s = scan.next();
			for(int j = i + 1;j < n;++j)
			{
				if('1' == s.charAt(j))
				{
					edge[i].add(j);
				}
			}
		}
		vis = new boolean[n];
		for(int i = 0;i < n;++i)
		{
			Arrays.fill(vis, false);
			minPos = i;
			dfs(i);
			if(minPos != i)
			{
				int tmp = p[i];
				p[i] = p[minPos];
				p[minPos] = tmp;
			}
		}
		PrintWriter out = new PrintWriter(System.out);
		for(int i = 0;i < n;++i)
		{
			out.print(p[i] + " ");
		}
		out.close();
	}

	public static void main(String[] args)
	{
		new Main().foo();
	}

	class MyScanner
	{
	    private byte[] buf = new byte[1024];
	    private int curChar;
	    private int numChars;
	    BufferedInputStream bis = new BufferedInputStream(System.in);

	    public int read()
	    {
	        if (-1 == numChars)
	        {
	        	throw new InputMismatchException();
	        }
	        if (curChar >= numChars)
	        {
	            curChar = 0;
	            try
	            {
	                numChars = bis.read(buf);
	            }
	            catch (IOException e)
	            {
	                throw new InputMismatchException();
	            }
	            if (numChars <= 0)
	            {
	            	return -1;
	            }
	        }
	        return buf[curChar++];
	    }

	    public int nextInt()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        int sgn = 1;
	        if (c == '-')
	        {
	            sgn = -1;
	            c = read();
	        }
	        int res = 0;
	        do
	        {
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c - '0';
	            c = read();
	        } while (!isSpaceChar(c));
	        return res * sgn;
	    }

	    public String next()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        StringBuilder res = new StringBuilder();
	        do
	        {
	            res.appendCodePoint(c);
	            c = read();
	        } while (!isSpaceChar(c));
	        return res.toString();
	    }

	    private boolean isSpaceChar(int c)
	    {
	        return ' ' == c || '\n' == c || '\r' == c || '\t' == c || -1 == c;
	    }
	}
}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.Set;

public class Main
{
	private ArrayList<Integer>[] edge;
	private boolean[] vis;
	private int[] mark;
	private int cnt;

	public void dfs(int u, int pre)
	{
		mark[u] = cnt;
		vis[u] = true;
		for(Integer v : edge[u])
		{
			if(v != pre && !vis[v])
			{
				dfs(v, u);
			}
		}
	}

	public void foo()
	{
		MyScanner scan = new MyScanner();
		int n = scan.nextInt();
		int[] a = new int[n];
		for(int i = 0;i < n;++i)
		{
			a[i] = scan.nextInt();
		}
		edge = new ArrayList[n];
		for(int i = 0;i < n;++i)
		{
			edge[i] = new ArrayList<Integer>();
			String s = scan.next();
			for(int j = 0;j < n;++j)
			{
				if('1' == s.charAt(j))
				{
					edge[i].add(j);
				}
			}
		}
		mark = new int[n];
		cnt = 1;
		vis = new boolean[n];
		for(int i = 0;i < n;++i)
		{
			if(0 == mark[i])
			{
				dfs(i, -1);
				++cnt;
			}
		}
		StringBuilder str = new StringBuilder();
		Arrays.fill(vis, false);
		for(int i = 0;i < n;++i)
		{
			int minValue = Integer.MAX_VALUE;
			int k = -1;
			for(int j = 0;j < n;++j)
			{
				if(mark[j] == mark[i] && !vis[j] && a[j] < minValue)
				{
					k = j;
					minValue = a[j];
				}
			}
			vis[k] = true;
			str.append(minValue + " ");
		}
		System.out.println(str);
	}

	public static void main(String[] args)
	{
		new Main().foo();
	}

	class MyScanner
	{
	    private byte[] buf = new byte[1024];
	    private int curChar;
	    private int numChars;
	    BufferedInputStream bis = new BufferedInputStream(System.in);

	    public int read()
	    {
	        if (-1 == numChars)
	        {
	        	throw new InputMismatchException();
	        }
	        if (curChar >= numChars)
	        {
	            curChar = 0;
	            try
	            {
	                numChars = bis.read(buf);
	            }
	            catch (IOException e)
	            {
	                throw new InputMismatchException();
	            }
	            if (numChars <= 0)
	            {
	            	return -1;
	            }
	        }
	        return buf[curChar++];
	    }

	    public int nextInt()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        int sgn = 1;
	        if (c == '-')
	        {
	            sgn = -1;
	            c = read();
	        }
	        int res = 0;
	        do
	        {
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c - '0';
	            c = read();
	        } while (!isSpaceChar(c));
	        return res * sgn;
	    }

	    public String next()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        StringBuilder res = new StringBuilder();
	        do
	        {
	            res.appendCodePoint(c);
	            c = read();
	        } while (!isSpaceChar(c));
	        return res.toString();
	    }

	    private boolean isSpaceChar(int c)
	    {
	        return ' ' == c || '\n' == c || '\r' == c || '\t' == c || -1 == c;
	    }
	}
}


import java.util.ArrayList;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.PriorityQueue;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskB solver = new TaskB();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskB {
    boolean[] visited;
    int[] p;
    List<Integer>[] graph;
    PriorityQueue<Integer>[] queue;
    int[] com;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        p = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = in.nextInt();
        }
        graph = new List[n];
        for (int i = 0; i < n; i++) {
            graph[i] = new ArrayList<Integer>();
        }
        for (int i = 0; i < n; i++) {
            char[] a =in.next().toCharArray();
            for (int j = 0; j < n; j++) {
                if(a[j] == '1'){
                    graph[j].add(i);
                }
            }
        }
        visited = new boolean[n];
        com = new int[n];
        queue = new PriorityQueue[n];
        for (int i = 0; i < n; i++) {
            queue[i] = new PriorityQueue<Integer>();
        }
        int id = 0;
        for (int i = 0; i < n; i++) {
            if(!visited[i]){
                dfs(i,id);
                ++id;
            }
        }
        for (int i = 0; i < n; i++) {
            out.printf("%d ", queue[com[i]].poll());
        }
    }

    void dfs(int v,int id){
        visited[v] = true;
        com[v] = id;
        queue[id].add(p[v]);
        for(int u : graph[v]){
            if(!visited[u]){
                dfs(u,id);
            }
        }
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt(){
        return Integer.parseInt(next());
    }

}


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;

public class MainB {
	MyScanner sc = new MyScanner();
	Scanner sc2 = new Scanner(System.in);
	final int MOD = 1000000007;
	int[] dx = { 1, 0, 0, -1 };
	int[] dy = { 0, 1, -1, 0 };

	void run() {
		int n = sc.nextInt();
		int[] p = sc.nextIntArray(n);
		char[][] f = new char[n][n];
		for (int i = 0; i < n; i++) {
			String in = sc.next();
			for (int j = 0; j < n; j++) {
				f[i][j] = in.charAt(j);
			}
		}
		for (int t = 0; t < 300; t++) {
			for (int i = 0; i < n; i++) {
				for (int j = i; j < n; j++) {
					if (p[i] > p[j] && f[i][j] == '1') {
						swap(p, i, j);
					}
				}
			}
		}

	}

	public static void main(String[] args) {
		new MainB().run();
	}

	void debug(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}

	void debug2(int[][] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j]);
			}
			System.out.println();
		}
	}

	boolean inner(int h, int w, int limH, int limW) {
		return 0 <= h && h < limH && 0 <= w && w < limW;
	}

	void swap(int[] x, int a, int b) {
		int tmp = x[a];
		x[a] = x[b];
		x[b] = tmp;
	}

	// find minimum i (a[i] >= border)
	int lower_bound(int a[], int border) {
		int l = -1;
		int r = a.length;

		while (r - l > 1) {
			int mid = (l + r) / 2;
			if (border <= a[mid]) {
				r = mid;
			} else {
				l = mid;
			}
		}
		// r = l + 1
		return r;
	}

	class MyScanner {
		int nextInt() {
			try {
				int c = System.in.read();
				while (c != '-' && (c < '0' || '9' < c))
					c = System.in.read();
				if (c == '-')
					return -nextInt();
				int res = 0;
				do {
					res *= 10;
					res += c - '0';
					c = System.in.read();
				} while ('0' <= c && c <= '9');
				return res;
			} catch (Exception e) {
				return -1;
			}
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		String next() {
			try {
				StringBuilder res = new StringBuilder("");
				int c = System.in.read();
				while (Character.isWhitespace(c))
					c = System.in.read();
				do {
					res.append((char) c);
				} while (!Character.isWhitespace(c = System.in.read()));
				return res.toString();
			} catch (Exception e) {
				return null;
			}
		}

		int[] nextIntArray(int n) {
			int[] in = new int[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextInt();
			}
			return in;
		}

		int[][] nextInt2dArray(int n, int m) {
			int[][] in = new int[n][m];
			for (int i = 0; i < n; i++) {
				in[i] = nextIntArray(m);
			}
			return in;
		}

		double[] nextDoubleArray(int n) {
			double[] in = new double[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextDouble();
			}
			return in;
		}

		long[] nextLongArray(int n) {
			long[] in = new long[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextLong();
			}
			return in;
		}
	}
}


import java.util.Arrays;
import java.util.Scanner;

public class MainB {
	MyScanner sc = new MyScanner();
	Scanner sc2 = new Scanner(System.in);
	final int MOD = 1000000007;
	int[] dx = { 1, 0, 0, -1 };
	int[] dy = { 0, 1, -1, 0 };

	void run() {
		int n = sc.nextInt();
		int[] p = sc.nextIntArray(n);
		par = new int[n + 1];
		rank = new int[n + 1];
		init(n + 1);
		for (int i = 0; i < n; i++) {
			String in = sc.next();
			for (int j = 0; j < n; j++) {
				if (in.charAt(j) == '1') {
					unite(i, j);
				}
			}
		}
		for (int i = 0; i < n; i++) {
			for (int j = i; j < n; j++) {
				if (p[i] > p[j] && same(i, j)) {
					swap(p, i, j);
				}
			}
		}
		for (int i = 0; i < n; i++) {
			System.out.print(i == 0 ? p[i] : " " + p[i]);
		}
		System.out.println();
	}

	int[] par;
	int[] rank;

	void init(int n) {
		for (int i = 0; i < n; i++) {
			par[i] = i;
			rank[i] = 0;
		}
	}

	int find(int x) {
		if (par[x] == x) {
			return x;
		} else {
			return par[x] = find(par[x]);
		}
	}

	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y) {
			return;
		}
		if (rank[x] < rank[y]) {
			par[x] = y;
		} else {
			par[y] = x;
			if (rank[x] == rank[y]) {
				rank[x]++;
			}
		}
	}

	boolean same(int x, int y) {
		return find(x) == find(y);
	}

	public static void main(String[] args) {
		new MainB().run();
	}

	void debug(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}

	void debug2(int[][] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j]);
			}
			System.out.println();
		}
	}

	boolean inner(int h, int w, int limH, int limW) {
		return 0 <= h && h < limH && 0 <= w && w < limW;
	}

	void swap(int[] x, int a, int b) {
		int tmp = x[a];
		x[a] = x[b];
		x[b] = tmp;
	}

	// find minimum i (a[i] >= border)
	int lower_bound(int a[], int border) {
		int l = -1;
		int r = a.length;

		while (r - l > 1) {
			int mid = (l + r) / 2;
			if (border <= a[mid]) {
				r = mid;
			} else {
				l = mid;
			}
		}
		// r = l + 1
		return r;
	}

	class MyScanner {
		int nextInt() {
			try {
				int c = System.in.read();
				while (c != '-' && (c < '0' || '9' < c))
					c = System.in.read();
				if (c == '-')
					return -nextInt();
				int res = 0;
				do {
					res *= 10;
					res += c - '0';
					c = System.in.read();
				} while ('0' <= c && c <= '9');
				return res;
			} catch (Exception e) {
				return -1;
			}
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		String next() {
			try {
				StringBuilder res = new StringBuilder("");
				int c = System.in.read();
				while (Character.isWhitespace(c))
					c = System.in.read();
				do {
					res.append((char) c);
				} while (!Character.isWhitespace(c = System.in.read()));
				return res.toString();
			} catch (Exception e) {
				return null;
			}
		}

		int[] nextIntArray(int n) {
			int[] in = new int[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextInt();
			}
			return in;
		}

		int[][] nextInt2dArray(int n, int m) {
			int[][] in = new int[n][m];
			for (int i = 0; i < n; i++) {
				in[i] = nextIntArray(m);
			}
			return in;
		}

		double[] nextDoubleArray(int n) {
			double[] in = new double[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextDouble();
			}
			return in;
		}

		long[] nextLongArray(int n) {
			long[] in = new long[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextLong();
			}
			return in;
		}
	}
}


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;

public class MainB {
	MyScanner sc = new MyScanner();
	Scanner sc2 = new Scanner(System.in);
	final int MOD = 1000000007;
	int[] dx = { 1, 0, 0, -1 };
	int[] dy = { 0, 1, -1, 0 };

	void run() {
		int n = sc.nextInt();
		int[] p = sc.nextIntArray(n);
		char[][] f = new char[n][n];
		for (int i = 0; i < n; i++) {
			String in = sc.next();
			for (int j = 0; j < n; j++) {
				f[i][j] = in.charAt(j);
			}
		}
		for (int t = 0; t < 300; t++) {
			for (int i = 0; i < n; i++) {
				for (int j = i; j < n; j++) {
					if (p[i] > p[j] && f[i][j] == '1') {
						swap(p, i, j);
					}
				}
			}
		}
		for (int i = 0; i < n; i++) {
			System.out.print(i == 0 ? p[i] : " " + p[i]);
		}
		System.out.println();
	}

	public static void main(String[] args) {
		new MainB().run();
	}

	void debug(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}

	void debug2(int[][] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j]);
			}
			System.out.println();
		}
	}

	boolean inner(int h, int w, int limH, int limW) {
		return 0 <= h && h < limH && 0 <= w && w < limW;
	}

	void swap(int[] x, int a, int b) {
		int tmp = x[a];
		x[a] = x[b];
		x[b] = tmp;
	}

	// find minimum i (a[i] >= border)
	int lower_bound(int a[], int border) {
		int l = -1;
		int r = a.length;

		while (r - l > 1) {
			int mid = (l + r) / 2;
			if (border <= a[mid]) {
				r = mid;
			} else {
				l = mid;
			}
		}
		// r = l + 1
		return r;
	}

	class MyScanner {
		int nextInt() {
			try {
				int c = System.in.read();
				while (c != '-' && (c < '0' || '9' < c))
					c = System.in.read();
				if (c == '-')
					return -nextInt();
				int res = 0;
				do {
					res *= 10;
					res += c - '0';
					c = System.in.read();
				} while ('0' <= c && c <= '9');
				return res;
			} catch (Exception e) {
				return -1;
			}
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		String next() {
			try {
				StringBuilder res = new StringBuilder("");
				int c = System.in.read();
				while (Character.isWhitespace(c))
					c = System.in.read();
				do {
					res.append((char) c);
				} while (!Character.isWhitespace(c = System.in.read()));
				return res.toString();
			} catch (Exception e) {
				return null;
			}
		}

		int[] nextIntArray(int n) {
			int[] in = new int[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextInt();
			}
			return in;
		}

		int[][] nextInt2dArray(int n, int m) {
			int[][] in = new int[n][m];
			for (int i = 0; i < n; i++) {
				in[i] = nextIntArray(m);
			}
			return in;
		}

		double[] nextDoubleArray(int n) {
			double[] in = new double[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextDouble();
			}
			return in;
		}

		long[] nextLongArray(int n) {
			long[] in = new long[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextLong();
			}
			return in;
		}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class Main {

    final static long MOD = 1000000007;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = br.readLine();
        String[] values = line.split(" ");
        int n = Integer.parseInt(values[0]);
        int[] A = new int[n];
        line = br.readLine();
        values = line.split(" ");
        for (int i = 0; i < n; i++) {
            A[i] = Integer.parseInt(values[i]);
        }
        int a = 1;
        int[] B = new int[n];
        for (int i = 0; i < n; i++) {
            line = br.readLine();
            for (int j = 0; j < i; j++) {
                if (line.charAt(j) == '1')
                    B[i] = B[j];
            }
            if (B[i] == 0) {
                B[i] = a; a++;
            }
        }
        HashMap<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>();
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> list = new ArrayList<Integer>();
            if (map.containsKey(B[i])) list = map.get(B[i]);
            list.add(A[i]);
            map.put(B[i], list);
//          System.out.println(B[i] + " " + list.toString());
        }
        for (Map.Entry<Integer, ArrayList<Integer>> me : map.entrySet()) {
            a = me.getKey();  ArrayList<Integer> list = me.getValue();
            Collections.sort(list);
//          System.out.println(a + " " + list.toString());
            int index = 0;
            for (int i = 0; i < n; i++) {
                if (B[i] == a) {
                    A[i] = list.get(index); index++;
                }
            }
        }
        for (int i = 0; i < n; i++)
            System.out.print(A[i] + " ");
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class Main {

    public static void dfs(int index, int[] B, boolean[][] P, int a) {
        if (B[index] != 0) return;
        B[index] = a;
        for (int i = 0; i < P.length; i++) {
            if (P[index][i]) dfs(i, B, P, a);
        }
//      System.out.println(Arrays.toString(B));
    }

    final static long MOD = 1000000007;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = br.readLine();
        String[] values = line.split(" ");
        int n = Integer.parseInt(values[0]);
        int[] A = new int[n];
        int[] B = new int[n];
        line = br.readLine();
        values = line.split(" ");
        for (int i = 0; i < n; i++) {
            A[i] = Integer.parseInt(values[i]);
        }
        boolean[][] P = new boolean[n][n];
        for (int i = 0; i < n; i++) {
            line = br.readLine();
            for (int j = 0; j < n; j++) P[i][j] = (line.charAt(j) == '1');
        }
        for (int i = 0; i < n; i++) {
            dfs(i, B, P, i+1);
        }
//      System.out.println(Arrays.toString(B));
        HashMap<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>();
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> list = new ArrayList<Integer>();
            if (map.containsKey(B[i])) list = map.get(B[i]);
            list.add(A[i]);
            map.put(B[i], list);
//          System.out.println(B[i] + " " + list.toString());
        }
        for (Map.Entry<Integer, ArrayList<Integer>> me : map.entrySet()) {
            int a = me.getKey();  ArrayList<Integer> list = me.getValue();
            Collections.sort(list);
//          System.out.println(a + " " + list.toString());
            int index = 0;
            for (int i = 0; i < n; i++) {
                if (B[i] == a) {
                    A[i] = list.get(index); index++;
                }
            }
        }
        for (int i = 0; i < n; i++)
            System.out.print(A[i] + " ");
    }
}


#include <stdio.h>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k,d=1;
        cin>>n>>k;
        if(2*k==n)
        {
            cout<<"2"<<"\n";
            continue;
        }
        int h=n/2;
        if(k>=n)
        {
            cout<<"1"<<"\n";
            continue;
        }
        if(n%2==0)
        {
            for(int i=k;i>0;i--)
            {
                if(n%i==0)
                {
                    d=i;
                    break;
                }
            }
            cout<<n/d<<"\n";
            continue;
        }
        if(n%2!=0)
        {
            cout<<n<<"\n";
            continue;
        }
    }

    return 0;
}


#include <stdio.h>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
bool isPrime(int n) {
   int i, flag = 0;
   for(i=2; i<=n/2; ++i) {
      if(n%i==0) {
         flag=1;
         break;
      }
   }
   if (flag==0)
      return 1;
   else
      return 0;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k,d=1,ans=1,p=0;
        cin>>n>>k;
        if(2*k==n)
        {
            cout<<"2"<<"\n";
            continue;
        }
        int h=n/2;
        if(k==1)
        {
            cout<<n<<"\n";
            continue;
        }
        if(k>=n)
        {
            cout<<"1"<<"\n";
            continue;
        }
        for(int i=2;i*i<=n;i++)
        {
            if(n%i==0&&i<=k)
            {
                d=0;
                if(n/i<=k)
                {
                    p=1;
                    cout<<i<<"\n";
                    break;
                }
                else
                {
                    ans=i;
                }
            }
        }
        if(d==1&&ans==1&&p==0)
        {
            cout<<n<<"\n";
        }
        else if(p==0)
        cout<<n/ans<<<<"\n";
    }

    return 0;
}


#include <stdio.h>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
bool isPrime(int n) {
   int i, flag = 0;
   for(i=2; i<=n/2; ++i) {
      if(n%i==0) {
         flag=1;
         break;
      }
   }
   if (flag==0)
      return 1;
   else
      return 0;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k,d=1,ans=1;
        cin>>n>>k;
        if(2*k==n)
        {
            cout<<"2"<<"\n";
            continue;
        }
        int h=n/2;
        if(k>=n)
        {
            cout<<"1"<<"\n";
            continue;
        }
        for(int i=2;i*i<=n;i++)
        {
            if(n%i==0&&i<=k)
            {
                if(n/i<=k)
                {
                    d=0;
                    cout<<i<<"\n";
                    break;
                }
                else
                {
                    d=0;
                    ans=i;
                }
            }
        }
        if(d==1&&ans==1)
        {
            cout<<n<<"\n";
        }
        else
        cout<<ans<<"\n";
    }

    return 0;
}


#include <stdio.h>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
bool isPrime(int n) {
   int i, flag = 0;
   for(i=2; i<=n/2; ++i) {
      if(n%i==0) {
         flag=1;
         break;
      }
   }
   if (flag==0)
      return 1;
   else
      return 0;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k,d=1;
        cin>>n>>k;
        if(2*k==n)
        {
            cout<<"2"<<"\n";
            continue;
        }
        int h=n/2;
        if(k>=n)
        {
            cout<<"1"<<"\n";
            continue;
        }
        if(isPrime(n)==1||k==1)
        {
            cout<<n<<"\n";
            continue;
        }
        //if(n%2==0)
        //{
            int l=2,i=n;
            while(1)
            {
                if(n/l<=k)
                {
                    break;
                }
                l++;
            }
            while(1)
            {
                if(n%(i/l)==0&&(i/l)<=k)
                {
                    d=(i/l);
                    break;
                }
                l++;
            }
            cout<<n/d<<"\n";
            continue;
        //}
    }

    return 0;
}


#include <stdio.h>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
bool isPrime(int n) {
   int i, flag = 0;
   for(i=2; i<=n/2; ++i) {
      if(n%i==0) {
         flag=1;
         break;
      }
   }
   if (flag==0)
      return 1;
   else
      return 0;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k,d=1;
        cin>>n>>k;
        if(2*k==n)
        {
            cout<<"2"<<"\n";
            continue;
        }
        int h=n/2;
        if(k>=n)
        {
            cout<<"1"<<"\n";
            continue;
        }
        if(n%2!=0&&isPrime(n)==1)
        {
            cout<<n<<"\n";
            continue;
        }
        //if(n%2==0)
        //{
            for(int i=k;i>0;i--)
            {
                if(n%i==0)
                {
                    d=i;
                    break;
                }
            }
            cout<<n/d<<"\n";
            continue;
        //}
    }

    return 0;
}


#include <stdio.h>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
bool isPrime(int n) {
   int i, flag = 0;
   for(i=2; i<=n/2; ++i) {
      if(n%i==0) {
         flag=1;
         break;
      }
   }
   if (flag==0)
      return 1;
   else
      return 0;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k,d=1;
        cin>>n>>k;
        if(2*k==n)
        {
            cout<<"2"<<"\n";
            continue;
        }
        int h=n/2;
        if(k>=n)
        {
            cout<<"1"<<"\n";
            continue;
        }
        if(isPrime(n)==1)
        {
            cout<<n<<"\n";
            continue;
        }
        //if(n%2==0)
        //{
            int l=2,i=n;
            while(1)
            {
                if(n%(i/l)==0&&(i/l)<=k)
                {
                    d=(i/l);
                    break;
                }
                l++;
            }
            cout<<n/d<<"\n";
            continue;
        //}
    }

    return 0;
}


#include <stdio.h>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k,d=1;
        cin>>n>>k;
        if(2*k==n)
        {
            cout<<"2"<<"\n";
            continue;
        }
        int h=n/2;
        if(k>=n)
        {
            cout<<"1"<<"\n";
            continue;
        }
        //if(n%2==0)
        //{
            for(int i=k;i>0;i--)
            {
                if(n%i==0)
                {
                    d=i;
                    break;
                }
            }
            cout<<n/d<<"\n";
            continue;
        //}
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main() {
    int t;
    cin>> t;
    start:
    while(t --) {
        int n, k;
        cin>> n >> k;
        if(k >= n) {
            cout<< 1 << "\n";
        } else {
            for(int i = 1; i * i <= n && i <= k; i ++) {
                if(n % i == 0 && n / i <= k) {
                    cout<< i << "\n";
                    goto start;
                }
            }
            cout<< n << "\n";
        }
    }
    return 0;
}