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++: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef int _loop_int;
#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)
#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)
#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define CHMIN(a,b) a=min((a),(b))
#define CHMAX(a,b) a=max((a),(b))

// mod
const ll MOD = 1000000007ll;
#define FIX(a) ((a)%MOD+MOD)%MOD

// floating
typedef double Real;
const Real EPS = 1e-11;
#define EQ0(x) (abs(x)<EPS)
#define EQ(a,b) (abs(a-b)<EPS)
typedef complex<Real> P;

int n;
char s[125252];
int g[9][9];

int main(){
  scanf("%d",&n);
  scanf("%s",s);
  REP(i,n-1){
    int bef = s[i]-'1';
    int nxt = s[i+1]-'1';
    if(bef>nxt)swap(bef,nxt);
    g[bef][nxt]++;
  }
  vi p(9);REP(i,9)p[i]=i;
  vi best = p;
  int bestscore = 252521830;
  do{
    int tmp = 0;
    REP(to,9)REP(from,to){
      int mul = g[from][to];
      int fx = p[from]/3, fy = p[from]%3;
      int tx = p[to]/3, ty = p[to]%3;
      tmp += mul * (abs(fx-tx) + abs(fy-ty));
    }
    if(tmp < bestscore){
      bestscore = tmp;
      vi ans(9);
      REP(i,9)ans[p[i]] = i;
      best = ans;
    }else if(tmp == bestscore){
      vi ans(9);
      REP(i,9)ans[p[i]] = i;
      if(ans < best){
        best = ans;
      }
    }
  }while(next_permutation(ALL(p)));
  REP(i,3){
    REP(j,3)printf("%d",best[3*i+j]+1);puts("");
  }
  return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#define MOD 1000000007
typedef long long ll;
using namespace std;

int num[10][10];
bool used[10];
int mi;
string ans;

void solve(string now){
  if(now.size()==9){
    int cost=0;
    int arr[3][3]={};
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
        arr[i][j]=now[i*3+j]-'0';
      }
    }
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
        for(int nx=0;nx<3;nx++){
          for(int ny=0;ny<3;ny++){
            if(nx==i&&ny==j) continue;
            cost+=(num[arr[i][j]][arr[nx][ny]])*(abs(i-nx)+abs(j-ny));
            if(cost>mi) return;
          }
        }
      }
    }

    if(cost<mi){
      mi=cost;
      ans=now;
    }else if(cost==mi){
      if(ans>now) ans=now;
    }
    return;
  }

  for(int i=1;i<=9;i++){
    if(used[i]) continue;
    used[i]=true;
    string next=now;
    next+=(char)('0'+i);
    solve(next);
    used[i]=false;
  }
  return;
}

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

  for(int i=1;i<n;i++){
    num[s[i-1]-'0'][s[i]-'0']++;
  }

  mi=1e9;

  solve("");
  //cout<<mi<<" "<<ans<<endl;
  for(int i=0;i<3;i++){
    for(int j=0;j<3;j++){
      cout<<ans[i*3+j];
    }
    cout<<endl;
  }

  return 0;
}