Go: package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

func configure(scanner *bufio.Scanner) {
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1000005), 1000005)
}
func getNextString(scanner *bufio.Scanner) string {
	scanned := scanner.Scan()
	if !scanned {
		panic("scan failed")
	}
	return scanner.Text()
}
func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}
func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}
func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}
func main() {
	fp := os.Stdin
	wfp := os.Stdout
	extra := 0
	if os.Getenv("I") == "IronMan" {
		fp, _ = os.Open(os.Getenv("END_GAME"))
		extra = 100
	}
	scanner := bufio.NewScanner(fp)
	configure(scanner)
	writer := bufio.NewWriter(wfp)
	defer func() {
		r := recover()
		if r != nil {
			fmt.Fprintln(writer, r)
		}
		writer.Flush()
	}()
	solve(scanner, writer)
	for i := 0; i < extra; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
}
func solve(scanner *bufio.Scanner, writer *bufio.Writer) {
	n := getNextInt(scanner)
	s := getNextString(scanner)
	cc := makeGrid(9, 9)
	for i := 0; i < n-1; i++ {
		cc[s[i]-'0'-1][s[i+1]-'0'-1]++
	}
	p := make(permutation, 9)
	ans := make([]int, 9)
	p.dfs(0, 9, 0, ans, cc)
	for i := 0; i < 9; i++ {
		fmt.Fprint(writer, ans[i]+1)
		if i%3 == 2 {
			fmt.Fprintln(writer, "")
		}
	}
}
func makeGrid(h, w int) [][]int {
	index := make([][]int, h, h)
	data := make([]int, h*w, h*w)
	for i := 0; i < h; i++ {
		index[i] = data[i*w : (i+1)*w]
	}
	return index
}

var min int = math.MaxInt32

type permutation []int

func (p permutation) dfs(i, n int, used uint32, ans []int, cc [][]int) {
	if i == n {
		sum := getsum(p, cc)
		if min > sum {
			for i := 0; i < 9; i++ {
				ans[i] = p[i]
			}
			min = sum
		}
		return
	}
	for b := 0; b < 9; b++ {
		if used&(1<<uint(b)) != 0 {
			continue
		}
		p[i] = b
		p.dfs(i+1, n, used|(1<<uint(b)), ans, cc)
	}
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}
func getsum(p permutation, cc [][]int) int {
	sum := 0
	for i := 0; i < 9; i++ {
		for j := 0; j < 9; j++ {
			if i == j {
				continue
			}
			sum += (abs(i/3-j/3) + abs(i%3-j%3)) * cc[p[i]][p[j]]
		}
	}
	return sum
}

C++: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

void dump_vec(vector<int> vec) {
    for(int i=0; i<3; i++) {
        for(int j=0; j<3; j++) {
            fprintf(stderr, "%lld ", vec[i * 3 + j]);
        }
        fprintf(stderr, "\n");
    }
}

int move_num[15][15], wf[15][15];
signed main() {
    int N; cin >> N;
    string s; cin >> s;

    fill(wf[0], wf[10], INF);
    for(int i=0; i<9; i++) wf[i][i] = 0;
    for(int i=0; i<3; i++) {
        for(int j=0; j<3; j++) {
            int u = i * 3 + j;
            for(int k=0; k<4; k++) {
                int ni = i + dx[k], nj = j + dy[k];
                if(ni < 0 or ni >= 3 or nj < 0 or nj >= 3) continue;
                int v = ni * 3 + nj;
                wf[u][v] = wf[v][u] = 1;
            }
        }
    }

    const int S = 9;
    for(int k=0; k<S; k++) {
        for(int i=0; i<S; i++) {
            for(int j=0; j<S; j++) {
                wf[i][j] = min(wf[i][j], wf[i][k] + wf[k][j]);
            }
        }
    }
    
    /*
    for(int i=0; i<S; i++) {
        for(int j=0; j<S; j++) {
            fprintf(stderr, "wf[%lld][%lld] = %lld\n", i, j, wf[i][j]);
        }
    }
    */

    vector<int> nums;
    for(int i=0; i<N; i++) {
        int num = s[i] - '1';
        nums.push_back(num);
    }

    for(int i=1; i<N; i++) {
        int u = nums[i-1], v = nums[i];
        move_num[u][v]++;
    }

    vector<int> perm(9);
    vector<int> ans(9, INF);
    int mi = INF;
    iota(perm.begin(), perm.end(), 0);
    do {
        vector<int> val2idx(S);
        for(int i=0; i<S; i++) {
            val2idx[ perm[i] ] = i;
        }

        int sum = 0;
        for(int i=0; i<S; i++) {
            for(int j=0; j<S; j++) {
                sum += move_num[i][j] * wf[ val2idx[i] ][ val2idx[j] ];
                if(sum > mi) i = S, j = S;
            }
        }

        if(mi > sum) {
            // fprintf(stderr, "sum = %lld\n", sum);
            // dump_vec(perm);
            mi = sum;
            ans = perm;
        }
        else if(mi == sum) {
            ans = min(ans, perm);
        }
        
    }while(next_permutation(perm.begin(), perm.end()));

    for(int i=0; i<3; i++) {
        for(int j=0; j<3; j++) {
            cout << ans[i * 3 + j] + 1;
        }
        cout << endl;
    }
    return 0;
}

C++: #include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using ll=long long;
using R=long double;
const R EPS=1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R& r){return(r > EPS)-(r < -EPS);}
inline R sq(R x){return sqrt(max(x,0.0L));}

const int dx[8]={1,0,-1,0,1,-1,-1,1};
const int dy[8]={0,1,0,-1,1,1,-1,-1};

const pid_t pid = getpid();
// Problem Specific Parameter:

int dist[9][9];
int cnt[9][9];



int main(void){
	int n;
	cin >> n;
	string s;
	cin >> s;

	rep(i, 9) rep(j, 9){
		dist[i][j] = 0;
		dist[i][j] += abs(i / 3 - j / 3);
		dist[i][j] += abs(i % 3 - j % 3);
	}

	rep(i, n - 1){
		const int a = s[i] - '1';
		const int b = s[i + 1] - '1';
		cnt[a][b]++;
	}

	vector<int> ary(9);
	iota(begin(ary), end(ary), 0);

	int cmin = 1 << 28;
	string ans = "";

	do {
		int cur = 0;
		rep(i, 9)rep(j, 9){
			cur += cnt[ary[i]][ary[j]] * dist[i][j];
		}

		if(chmin(cmin, cur)){
			string tmp = "";
			rep(i, 9) tmp += char(ary[i] + '1');
			ans = tmp;
		}

	} while(next_permutation(begin(ary), end(ary)));

	rep(i, 3) cout << ans.substr(3 * i , 3) << endl;

	return 0;
}