#include <iostream>
#include <string>
#include <vector>
#include <tuple>
#define NONE 0
#define RIGHT 1
#define DOWN 2
#define BOTH 3
using namespace std;
bool isOK(long x, long y, vector<auto> dgs) {
for (long i = 0; i < dgs.size(); i++) {
if (get<0>(dgs[i]) == x && get<1>(dgs[i]) == y) {
return false;
}
}
return true;
}
int getB(string t[], long x, long y, long mi, vector<auto> dgs) {
int o1 = t[y][x + 1]; // Right
int o2 = t[y + 1][x]; // Down
if (o1 == o2 && x < mi && y < mi && isOK(x + 1, y, dgs) && isOK(x, y + 1, dgs)) {
return BOTH;
} else if ((o1 < o2 && x < mi) || (o1 > o2 && y >= mi) && isOK(x + 1, y, dgs)) {
return RIGHT;
} else if ((o1 > o2 && y < mi) || (o1 < o2 && x >= mi) && isOK(x, y + 1, dgs)) {
return DOWN;
}
return NONE;
}
long getSum(string s) {
long sum = 0;
for (int i = 0; i < s.size(); i++) {
sum += s[i];
}
return sum;
}
int main() {
long n;
cin >> n;
vector<string> t;
string tmp;
for (long i = 0; i < n; i++) {
cin >> tmp;
t.push_back(tmp);
}
string smallest = "";
long smallestNum = 4294967295;
string p = "";
long x = 0;
long y = 0;
p += t[x][y];
vector<auto> dgs;
while (1) {
switch (getB(t, x, y, n - 1, dgs)) {
case RIGHT:
x++;
break;
case DOWN:
y++;
break;
case BOTH:
x++;
dgs.push_back(make_tuple(x, y));
break;
}
p += t[x][y];
if (x == n - 1 && y = n - 1) {
x = 0;
y = 0;
if (getSum(p) < smallestNum) {
smallestNum = getSum(p);
smallest = p;
}
}
}
cout << p;
//while (1);
}