#include <bits/stdc++.h>
#define INF 99
#define QLEN 107
using namespace std;

struct dic
{
    int cnt[60];
    dic() { memset(cnt,0,sizeof(cnt));}
    
    void print()
    {
        int i,j;
        for(i=0;i<26;i++) for(j=1;j<=cnt[i];j++) printf("%c",i+'A');
        for(i=26;i<52;i++) for(j=1;j<=cnt[i];j++) printf("%c",i-26+'a');
    }
};

bool operator >= (const dic &a,const dic &b)
{
    int i;
    for(i=0;i<52;i++)
    {
        if(a.cnt[i] > b.cnt[i]) return true;
        if(a.cnt[i] < b.cnt[i]) return false;
    }
    return true;
}

dic operator + (const dic &a,const dic &b)
{
    int i;
    dic ret;
    for(i=0;i<52;i++) ret.cnt[i] = a.cnt[i] + b.cnt[i];
    return ret;
}

dic operator * (int a,const dic &b)
{
    int i;
    dic ret;
    for(i=0;i<52;i++) ret.cnt[i] = a*b.cnt[i];
    return ret;
}

int n;
dic ans;
char MAP[55][55];

int S,T;
int tot = 1,e[10010][2],siz[10010],p[110];
dic v[10010];

int q[110],flow[110],from[110];
dic dis[110];
bool vis[110];

void adde(int sn,int fn,int sz,const dic &val)
{
    e[++tot][0] = fn; siz[tot] = sz; v[tot] = val; e[tot][1] = p[sn]; p[sn] = tot;
    e[++tot][0] = sn; siz[tot] = 0; v[tot] = -1*val; e[tot][1] = p[fn]; p[fn] = tot;
}

void build()
{
    int i,j;
    S = 0; T = n*2+1;
    
    for(i=1;i<=n;i++)
    {
        dic val;
        adde(S,i,1,val); adde(i+n,T,1,val);
    }
    for(i=1;i<=n;i++) for(j=1;j<=n;j++)
    {
        dic val;
        if(MAP[i][j] <= 'Z') val.cnt[MAP[i][j]-'A'] = 1;
        else val.cnt[MAP[i][j]-'a'+26] = 1;
        adde(i,j+n,1,val);
    }
}

dic maxCostFlow()
{
    int head = 1,tail = 2;
    int i,sn,fn;
    dic val;
    
    for(i=1;i<=T;i++) dis[i].cnt[0] = -INF;
    memset(flow,0,sizeof(flow));
    q[1] = S; vis[S] = 1; flow[S] = INF;
    
    while(head != tail)
    {
        sn = q[head++];
        for(i=p[sn];i;i=e[i][1])
        {
            fn = e[i][0]; val = v[i];
            if(!siz[i] || dis[fn]>=dis[sn]+val) continue;
            dis[fn] = dis[sn]+val; flow[fn] = min(flow[sn],siz[i]);
            from[fn] = i;
            if(vis[fn]) continue;
            vis[fn] = 1; q[tail++] = fn;
            if(tail>QLEN) tail = 1;
        }
        vis[sn] = 0;
        if(head>QLEN) head = 1;
    }
    
    for(sn=T;sn!=S;sn=e[from[sn]^1][0])
    {
        siz[from[sn]] -= flow[T];
        siz[from[sn]^1] += flow[T];
    }
    return flow[T]*dis[T];
}

int main()
{
    int i;
    scanf("%d",&n);
    for(i=1;i<=n;i++) scanf("%s",MAP[i]+1);
    
    build();
    do{ ans = ans + maxCostFlow();} while(flow[T]>0);
    ans.print();
    return 0;
}
