//#include <bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <bitset>
#include <string>
#include <time.h>
using namespace std;
long double esp=1e-11;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define fi first
#define se second
#define all(a) (a).begin(),(a).end()
#define cle(a) while(!a.empty())a.pop()
#define mem(p) memset(p,0,sizeof(p))
#define memf(p) memset(p,0x3f,sizeof(p))
#define memn(p) memset(p,-1,sizeof(p))
#define mp(A, B) make_pair(A, B)
#define pb push_back
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
typedef long long int LL;
const long double PI = acos((long double)-1);
const LL INF=0x3f3f3f3fll;
const int MOD = 1000000007;
const int maxn=110000;
#define V 110
#define E 15100
struct bigint{
    int k[55];
}ept;
bigint binf;
bigint operator+(bigint const &a,bigint const &b){
        bigint tem;
        for(int x=0;x<55;x++)
            tem.k[x]=a.k[x]+b.k[x];
        return tem;}
bool operator>(bigint const &a,bigint const &b){
        for(int x=0;x<55;x++)
            if(a.k[x]>b.k[x])return 1;
            else if(a.k[x]==b.k[x])continue;
            else return 0;
            return 0;}
bool operator!=(bigint const &a,bigint const &b){
        for(int x=0;x<55;x++)
            if(a.k[x]!=b.k[x])return 1;
        return 0;}
int vis[V];
bigint dist[V];
int pre[V];

struct Edge{
    int u,v,c,next;
    bigint cost;
}edge[E];
int head[V],cnt;

void init(){
    cnt=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int c,bigint cost)
{
    edge[cnt].u=u;edge[cnt].v=v;edge[cnt].cost=cost;
    edge[cnt].c=c;edge[cnt].next=head[u];head[u]=cnt++;

    for(int x=0;x<55;x++)cost.k[x]*=-1;
    edge[cnt].u=v;edge[cnt].v=u;edge[cnt].cost=cost;
    edge[cnt].c=0;edge[cnt].next=head[v];head[v]=cnt++;
}

bool spfa(int begin,int end){
    int u,v;
    queue<int> q;
    for(int i=0;i<=end+2;i++){
        pre[i]=-1;
        vis[i]=0;
        dist[i]=binf;
    }
    vis[begin]=1;
    dist[begin]=ept;
    q.push(begin);
    while(!q.empty()){
        u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next){
            if(edge[i].c>0){
                v=edge[i].v;
                if(dist[v]>dist[u]+edge[i].cost){
                    dist[v]=dist[u]+edge[i].cost;
                    pre[v]=i;
                    if(!vis[v]){
                        vis[v]=true;
                        q.push(v);
                    }
                }
            }
        }
    }                   //cout << "spfa" << endl;
    return dist[end]!=binf;
}

bigint MCMF(int begin,int end){
    bigint ans=ept;
    int flow;
    int flow_sum=0;
    while(spfa(begin,end)){
        flow=INF;
        for(int i=pre[end];i!=-1;i=pre[edge[i].u])
            if(edge[i].c<flow)
                flow=edge[i].c;
        for(int i=pre[end];i!=-1;i=pre[edge[i].u]){
            edge[i].c-=flow;
            edge[i^1].c+=flow;
        }
        ans=ans+dist[end];
        flow_sum += flow;
    }
    //cout << flow_sum << endl;
    return ans;
}
char s[110];
char h[66][66];
int cal(char c)
{
    if(c<='Z')return c-'A';
    return 26+c-'a';
}
char fcal(int x)
{
    if(x<=25)return 'A'+x;
    return x-26+'a';
}
int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("inlay.in", "r", stdin);
    //freopen("out.txt", "w", stdout);
    //map<long long int,int>ma;                 %I64d
    //vector<int>::iterator iter;
    //memset(m,0,sizeof(int));
    //for(int x=1;x<=n;x++)
    //for(int y=1;y<=n;y++)
    //scanf("%d%d",&a,&b);
    //scanf("%d",&a);
    //printf("%d\n",ans);
    mem(ept.k);
    memf(binf.k);
    int n;
    scanf("%d",&n);
    init();
    int st=105,ed=106;
    for(int x=0;x<n;x++)
        addedge(st,x,1,ept),addedge(n+x,ed,1,ept);
    bigint tem;
    for(int x=0;x<n;x++)
    {
        scanf("%s",s);
        for(int y=0;y<n;y++)
        {
            h[x][y]=s[y];
            mem(tem.k);
            tem.k[cal(s[y])]=-1;
            addedge(x,n+y,1,tem);
        }
    }           //printf("%d\n",1111);
    bigint ans=MCMF(st,ed);
    for(int x=0;x<55;x++)
        while(ans.k[x]++)
        putchar(fcal(x));
    puts("");
    //printf("%d\n",spfa(st,ed));
    /*for(int x=0;x<cnt;x++)
    {
        printf("%d %d %d\n",edge[x].u,edge[x].v,edge[x].c);
        for(int y=0;y<55;y++)
            if(edge[x].cost.k[y])
                printf("%d ",edge[x].cost.k[y]);
            //printf("%d ",edge[x].cost.k[y]);
        putchar('\n');
    }*/
    return 0;
}

Measured memory_bytes: 4352