#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T checkmin(T &a, T b) {
  return (a < b) ? a : a = b;
}
template <class T>
inline T checkmax(T &a, T b) {
  return (a > b) ? a : a = b;
}
template <class T>
T GCD(T a, T b) {
  if (a < 0) return GCD(-a, b);
  if (b < 0) return GCD(a, -b);
  return (a == 0) ? b : GCD(b % a, a);
}
template <class T>
T LCM(T a, T b) {
  if (a < 0) return LCM(-a, b);
  if (b < 0) return LCM(a, -b);
  return (a == 0 || b == 0) ? 0 : a / GCD(a, b) * b;
}
namespace Poor {
const int MaxiN = 4;
int N, S;
int A[MaxiN * MaxiN];
int Matrix[MaxiN][MaxiN];
pair<int, int> Seq[MaxiN * MaxiN];
bool Vis[MaxiN][MaxiN];
bool Used[MaxiN * MaxiN];
int RestH[MaxiN], RestV[MaxiN], RestN, RestP;
int NeedH[MaxiN], NeedV[MaxiN], NeedN, NeedP;
void Determine() {
  vector<pair<int, pair<int, int> > > List;
  for (int i = 0; i < N; ++i)
    for (int j = 0; j < N; ++j) {
      if (i == j)
        List.push_back(make_pair(3, make_pair(i, j)));
      else {
        if (i + j == N - 1)
          List.push_back(make_pair(2, make_pair(i, j)));
        else
          List.push_back(make_pair(1, make_pair(i, j)));
      }
    }
  sort(List.begin(), List.end());
  reverse(List.begin(), List.end());
  for (typeof(List.begin()) it = List.begin(); it != List.end(); ++it)
    Seq[it - List.begin()] = it->second;
}
inline void Draw(int X, int Y, int I) {
  Used[I] = 1;
  Matrix[X][Y] = A[I];
  Vis[X][Y] = 1;
  if (X == Y) --RestN, NeedN -= A[I];
  if (X + Y == N - 1) --RestP, NeedP -= A[I];
  --RestH[X], NeedH[X] -= A[I];
  --RestV[Y], NeedV[Y] -= A[I];
}
inline void Undraw(int X, int Y, int I) {
  Vis[X][Y] = 0;
  Used[I] = 0;
  if (X == Y) ++RestN, NeedN += A[I];
  if (X + Y == N - 1) ++RestP, NeedP += A[I];
  ++RestH[X], NeedH[X] += A[I];
  ++RestV[Y], NeedV[Y] += A[I];
}
bool DFS(int Step) {
  if (Step == N * N) {
    if (NeedN != 0 || NeedP != 0) return 0;
    for (int i = 0; i < N; ++i)
      if (NeedH[i] != 0 || NeedV[i] != 0) return 0;
    return 1;
  }
  int X = Seq[Step].first, Y = Seq[Step].second;
  int NCandidate = 0;
  for (int i = 0; i < N * N; ++i)
    if (!Used[i]) ++NCandidate;
  int *Candidate = new int[NCandidate];
  NCandidate = 0;
  for (int i = 0; i < N * N; ++i)
    if (!Used[i]) Candidate[NCandidate++] = i;
  if (X == Y) {
    if (RestN == 1) {
      for (int i = 0; i < NCandidate; ++i)
        if (NeedN == A[Candidate[i]]) {
          Draw(X, Y, Candidate[i]);
          if (DFS(Step + 1)) return 1;
          Undraw(X, Y, Candidate[i]);
          break;
        }
    }
    if (RestN == 2) {
      int j = NCandidate - 1;
      for (int i = 0; i < NCandidate; ++i)
        if (i == 0 || A[Candidate[i]] != A[Candidate[i - 1]]) {
          while (j > 0 && A[Candidate[j]] > NeedN - A[Candidate[i]]) --j;
          if (i == j || A[Candidate[i]] + A[Candidate[j]] != NeedN) continue;
          Draw(X, Y, Candidate[i]);
          if (DFS(Step + 1)) return 1;
          Undraw(X, Y, Candidate[i]);
        }
    }
    if (RestN == 3) {
      set<int> Set;
      for (int i = 0; i < NCandidate; ++i)
        for (int j = 0; j < i; ++j)
          Set.insert(A[Candidate[i]] + A[Candidate[j]]);
      for (int i = 0; i < NCandidate; ++i)
        if ((i == 0 || A[Candidate[i]] != A[Candidate[i - 1]]) &&
            Set.count(NeedN - A[Candidate[i]])) {
          Draw(X, Y, Candidate[i]);
          if (DFS(Step + 1)) return 1;
          Undraw(X, Y, Candidate[i]);
        }
    }
    if (RestN == 4) {
      set<int> Set;
      for (int i = 0; i < NCandidate; ++i)
        for (int j = 0; j < i; ++j)
          for (int k = 0; k < j; ++k)
            Set.insert(A[Candidate[i]] + A[Candidate[j]] + A[Candidate[k]]);
      for (int i = 0; i < NCandidate; ++i)
        if ((i == 0 || A[Candidate[i]] != A[Candidate[i - 1]]) &&
            Set.count(NeedN - A[Candidate[i]])) {
          Draw(X, Y, Candidate[i]);
          if (DFS(Step + 1)) return 1;
          Undraw(X, Y, Candidate[i]);
        }
    }
  } else {
    if (X + Y == N - 1) {
      if (RestP == 1) {
        for (int i = 0; i < NCandidate; ++i)
          if (NeedP == A[Candidate[i]]) {
            Draw(X, Y, Candidate[i]);
            if (DFS(Step + 1)) return 1;
            Undraw(X, Y, Candidate[i]);
            break;
          }
      }
      if (RestP == 2) {
        int j = NCandidate - 1;
        for (int i = 0; i < NCandidate; ++i)
          if (i == 0 || A[Candidate[i]] != A[Candidate[i - 1]]) {
            while (j > 0 && A[Candidate[j]] > NeedP - A[Candidate[i]]) --j;
            if (i == j || A[Candidate[i]] + A[Candidate[j]] != NeedP) continue;
            Draw(X, Y, Candidate[i]);
            if (DFS(Step + 1)) return 1;
            Undraw(X, Y, Candidate[i]);
          }
      }
      if (RestP == 3) {
        set<int> Set;
        for (int i = 0; i < NCandidate; ++i)
          for (int j = 0; j < i; ++j)
            Set.insert(A[Candidate[i]] + A[Candidate[j]]);
        for (int i = 0; i < NCandidate; ++i)
          if ((i == 0 || A[Candidate[i]] != A[Candidate[i - 1]]) &&
              Set.count(NeedP - A[Candidate[i]])) {
            Draw(X, Y, Candidate[i]);
            if (DFS(Step + 1)) return 1;
            Undraw(X, Y, Candidate[i]);
          }
      }
      if (RestP == 4) {
        set<int> Set;
        for (int i = 0; i < NCandidate; ++i)
          for (int j = 0; j < i; ++j)
            for (int k = 0; k < j; ++k)
              Set.insert(A[Candidate[i]] + A[Candidate[j]] + A[Candidate[k]]);
        for (int i = 0; i < NCandidate; ++i)
          if ((i == 0 || A[Candidate[i]] != A[Candidate[i - 1]]) &&
              Set.count(NeedP - A[Candidate[i]])) {
            Draw(X, Y, Candidate[i]);
            if (DFS(Step + 1)) return 1;
            Undraw(X, Y, Candidate[i]);
          }
      }
    } else {
      if (RestH[X] == 1) {
        for (int i = 0; i < NCandidate; ++i)
          if (NeedH[X] == A[Candidate[i]]) {
            Draw(X, Y, Candidate[i]);
            if (DFS(Step + 1)) return 1;
            Undraw(X, Y, Candidate[i]);
            break;
          }
      } else {
        if (RestV[Y] == 1) {
          for (int i = 0; i < NCandidate; ++i)
            if (NeedV[Y] == A[Candidate[i]]) {
              Draw(X, Y, Candidate[i]);
              if (DFS(Step + 1)) return 1;
              Undraw(X, Y, Candidate[i]);
              break;
            }
        } else {
          if (RestH[X] == 2) {
            int j = NCandidate - 1;
            for (int i = 0; i < NCandidate; ++i)
              if (i == 0 || A[Candidate[i]] != A[Candidate[i - 1]]) {
                while (j > 0 && A[Candidate[j]] > NeedH[X] - A[Candidate[i]])
                  --j;
                if (i == j || A[Candidate[i]] + A[Candidate[j]] != NeedH[X])
                  continue;
                Draw(X, Y, Candidate[i]);
                if (DFS(Step + 1)) return 1;
                Undraw(X, Y, Candidate[i]);
              }
          } else {
            if (RestV[Y] == 2) {
              int j = NCandidate - 1;
              for (int i = 0; i < NCandidate; ++i)
                if (i == 0 || A[Candidate[i]] != A[Candidate[i - 1]]) {
                  while (j > 0 && A[Candidate[j]] > NeedV[Y] - A[Candidate[i]])
                    --j;
                  if (i == j || A[Candidate[i]] + A[Candidate[j]] != NeedV[Y])
                    continue;
                  Draw(X, Y, Candidate[i]);
                  if (DFS(Step + 1)) return 1;
                  Undraw(X, Y, Candidate[i]);
                }
            } else
              cerr << "error!" << endl;
          }
        }
      }
    }
  }
  delete[] Candidate;
  return 0;
}
void Run() {
  scanf("%d", &N);
  for (int i = 0; i < N * N; ++i) scanf("%d", A + i);
  sort(A, A + N * N);
  for (int i = 0; i < N * N; ++i) S += A[i];
  S /= N;
  Determine();
  for (int i = 0; i < N; ++i) {
    RestH[i] = RestV[i] = N;
    NeedH[i] = NeedV[i] = S;
  }
  RestP = RestN = N;
  NeedP = NeedN = S;
  DFS(0);
  printf("%d\n", S);
  for (int i = 0; i < N; ++i)
    for (int j = 0; j < N; ++j)
      printf("%d%c", Matrix[i][j], (j == N - 1) ? '\n' : ' ');
}
}  // namespace Poor
int main() {
  Poor::Run();
  return 0;
}
