#include<bits/stdc++.h>
using namespace std;
#define MAX_V 500
#define INF 1<<28

class bigint {
private:
  static const int BASE = 100000000, LEN = 40;
  bool negative;
  std::vector<int> a;
  bigint& normalize();
public:
  bigint(int x = 0);
  bigint(const std::string& s);
  bigint& operator = (const bigint& x);
  bigint& operator = (int x);
  bigint& operator = (const std::string& s);
  const bool operator < (const bigint& x) const;
  const bool operator > (const bigint& x) const;
  const bool operator <= (const bigint& x) const;
  const bool operator >= (const bigint& x) const;
  const bool operator != (const bigint& x) const;
  const bool operator == (const bigint& x) const;
  bigint operator -() const;
  bigint& operator += (const bigint& x);
  bigint& operator -= (const bigint& x);
  bigint& operator *= (const bigint& x);
  bigint& operator /= (const bigint& x);
  bigint& operator %= (const bigint& x);
  const bigint operator + (const bigint& x) const;
  const bigint operator - (const bigint& x) const;
  const bigint operator * (const bigint& x) const;
  const bigint operator / (const bigint& x) const;
  const bigint operator % (const bigint& x) const;
  friend std::pair<bigint,bigint> divmod(const bigint& lhs, const bigint& rhs);
  friend std::istream& operator >> (std::ostream& is, bigint& x); //??????????£?
  friend std::ostream& operator << (std::ostream& os, const bigint& x);
  friend const bigint abs(bigint x);
};
bigint& bigint::normalize() {
  int i = a.size()-1;
  while (i >= 0 && a[i] == 0) --i;
  a.resize(i+1);
  if (a.size() == 0) negative = false;
  return *this;
}
bigint::bigint(int x) : negative(x<0) {
  x = abs(x);
  for (; x > 0; x /= BASE) a.push_back(x % BASE);
}
bigint::bigint(const std::string& s): negative(false) {
  int p = 0;
  if (s[p] == '-') { ++p; negative = true; }
  else if (s[p] == '+') { ++p; }
  for (int i = s.size()-1, v = BASE; i >= p; --i, v*=10) {
    int x = s[i]-'0';
    if (x < 0 || 9 < x) {
      std::cerr<<"error: parse error:"<<s<<std::endl;
      exit(1);
    } 
    if (v == BASE) {
      v = 1;
      a.push_back(x);
    } else a.back() += (x)*v;
  }
  normalize();
}
bigint& bigint::operator = (const bigint& x) {
  negative = x.negative;
  a = x.a;
  return *this;
}
bigint& bigint::operator = (int x) { return *this = bigint(x); }
bigint& bigint::operator = (const std::string& s) { return *this = bigint(s); }
const bool bigint::operator < (const bigint& x) const {
  if (negative != x.negative) return negative < x.negative;
  if (a.size() != x.a.size()) return (a.size() < x.a.size())^negative;
  for(int i = a.size()-1; i >= 0; --i)
    if (a[i] != x.a[i]) return (a[i] < x.a[i])^negative;
  return false;
}
const bool bigint::operator > (const bigint& x) const { return x<(*this); }
const bool bigint::operator <= (const bigint& x) const { return !(x<(*this)); }
const bool bigint::operator >= (const bigint& x) const { return !((*this)<x); }
const bool bigint::operator != (const bigint& x) const { return (*this)<x || x<(*this); }
const bool bigint::operator == (const bigint& x) const { return !((*this)<x || x<(*this)); }
bigint bigint::operator -() const {
  bigint ret(*this);
  if (a.size()) ret.negative = !ret.negative;
  return ret;
}
bigint& bigint::operator += (const bigint& x) {
  if (negative != x.negative) return *this -= -x;
  if (a.size() < x.a.size()) a.resize(x.a.size());
  int tmp = 0;
  for (int i = 0; i < a.size(); ++i) {
    a[i] += (i<x.a.size()?x.a[i]:0) + tmp;
    tmp = a[i] / BASE;
    a[i] %= BASE;
  }
  if (tmp) a.push_back(1);
  return *this;
}
bigint& bigint::operator -= (const bigint& x) {
  if (negative != x.negative) return *this += -x;
  std::vector<int> b(x.a);
  if ((*this < x) ^ negative) {
    a.swap(b);
    negative = !negative;
  }
  for (int i = 0, tmp = 0; i < a.size(); ++i) {
    a[i] += BASE - (i<b.size()?b[i]:0) + tmp;
    tmp = a[i] / BASE - 1;
    a[i] %= BASE;
  }
  return this->normalize();
}
bigint& bigint::operator *= (const bigint& x) {
  negative ^= x.negative;
  std::vector<int> c(a.size()*x.a.size()+1);
  for (int i = 0; i < a.size(); ++i) {
    long long tmp = 0;
    for (int j = 0; j < x.a.size(); ++j) {
      long long v = (long long)a[i] * x.a[j] + c[i+j] + tmp;
      tmp = v / BASE;
      c[i+j] = (int)(v % BASE);
    }
    if (tmp) c[i+x.a.size()] += (int)tmp;
  }
  a.swap(c);
  return this->normalize();
}
bigint& bigint::operator /= (const bigint& x) {
  return *this = divmod(*this,x).first;
}
bigint& bigint::operator %= (const bigint& x) {
  return *this = divmod(*this,x).second;
}
const bigint bigint::operator + (const bigint& x) const {
  bigint res(*this); return res += x;
}
const bigint bigint::operator - (const bigint& x) const {
  bigint res(*this); return res -= x;
}
const bigint bigint::operator * (const bigint& x) const {
  bigint res(*this); return res *= x;
}
const bigint bigint::operator / (const bigint& x) const {
  bigint res(*this); return res /= x;
}
const bigint bigint::operator % (const bigint& x) const {
  bigint res(*this); return res %= x;
}
std::pair<bigint,bigint> divmod(const bigint& lhs, const bigint& rhs) {
  if (!rhs.a.size()) {
    std::cerr<<"error: division by zero"<<std::endl;
    exit(1);
  }
  bigint x(abs(rhs)), q, r;
  for (int i = lhs.a.size()-1; i >= 0; --i) {
    r = r * bigint::BASE + lhs.a[i];
    int head = 0, tail = bigint::BASE;
    if (r >= x) {
      while (head + 1 < tail) {
        int mid = (head + tail) / 2;
        if (x * bigint(mid) > r) tail = mid;
        else head = mid;
      }
      r -= x * head;
    }
    q.a.push_back(head);
  }
  reverse(q.a.begin(), q.a.end());
  bool neg = lhs.negative ^ lhs.negative;
  q.negative = neg; r.negative = neg;
  return std::make_pair(q.normalize(), r.normalize());
}
std::istream& operator >> (std::istream& is, bigint& x) {
  std::string tmp; is >> tmp;
  x = bigint(tmp);
  return is;
}
std::ostream& operator << (std::ostream& os, const bigint& x) {
  if (x.negative) os << '-';
  if (!x.a.size()) os << 0;
  else os << x.a.back();
  for (int i = x.a.size()-2; i >= 0; --i) {
    os.width(bigint::LEN);
    os.fill('0');
    os << x.a[i];
  }
  return os;
}
const bigint abs(bigint x) {
  x.negative = false;
  return x;
}

bigint base=bigint("100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
bigint inf=bigint("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");

typedef pair<bigint,int> P;

struct edge{
  int to,rev;
  bigint cap,cost;
  edge(){}
  edge(int to,bigint cap,int rev,bigint cost):to(to),cap(cap),rev(rev),cost(cost){}
};

int V;
vector<edge> G[MAX_V];
bigint h[MAX_V];
bigint dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];

void add_edge(int from,int to,bigint cap,bigint cost){
  G[from].push_back(edge(to,cap,G[to].size(),cost));
  G[to].push_back(edge(from,0,G[from].size()-1,-cost));
}

bigint min_cost_flow(int s,int t,bigint f){
  bigint res=0;
  for(int i=0;i<V;i++) h[i]=0;
  while(f>0){
    priority_queue<P,vector<P>,greater<P> > que;
    for(int i=0;bigint(i)<V;i++) dist[i]=inf;
    dist[s]=bigint(0);
    que.push(P(0,s));
    while(!que.empty()){
      P p=que.top();que.pop();
      int v=p.second;
      if(dist[v]<p.first) continue;
      for(int i=0;i<(int)G[v].size();i++){
	edge &e=G[v][i];
	if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
	  dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
	  prevv[e.to]=v;
	  preve[e.to]=i;
	  que.push(P(dist[e.to],e.to));
	}
      }
    }
    if(dist[t]==INF){
      return -1;
    }
    for(int v=0;bigint(v)<V;v++) h[v]+=dist[v];

    bigint d=f;
    for(int v=t;v!=s;v=prevv[v]){
      d=min(d,G[prevv[v]][preve[v]].cap);
    }
    f-=d;
    res+=d*h[t];
    for(int v=t;v!=s;v=prevv[v]){
      edge &e=G[prevv[v]][preve[v]];
      e.cap-=d;
      G[v][e.rev].cap+=d;
    }
  }
  return res;
}

signed main(){
  int n;
  cin>>n;
  string str[n],ans;
  for(int i=0;i<n;i++) cin>>str[i];
  V=n*2+2;
  int s=n*2,t=n*2+1;
  
  for(int i=0;i<n;i++){
    add_edge(s,i,1,0);
    add_edge(n+i,t,1,0);
  }
  bigint cost[52];
  for(int i=0;i<52;i++){
    cost[i]=1;
    for(int j=0;j<52-i;j++){
      cost[i]*=52;
    }
  }
  map<char,int> c;
  for(char i='A';i<='Z';i++) c[i]=i-'A';
  for(char i='a';i<='z';i++) c[i]=i-'a'+26;
  
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      add_edge(i,n+j,1,base-cost[c[str[i][j]]]);

  min_cost_flow(s,t,bigint(n));
  

  for(int i=0;i<n;i++){
    for(int j=0;j<(int)G[i].size();j++){
      if(G[i][j].cap>bigint(0)) continue;
      ans+=str[i][G[i][j].to-n];
    }
  }
  sort(ans.begin(),ans.end());
  cout<<ans<<endl;
  return 0;
}
### Prompt

In cpp, your task is to solve the following problem:

Example

Input

3
aab
czc
baa


Output

aac

### Response

```cpp
#include<bits/stdc++.h>
using namespace std;
#define MAX_V 500
#define INF 1<<28

class bigint {
private:
  static const int BASE = 100000000, LEN = 40;
  bool negative;
  std::vector<int> a;
  bigint& normalize();
public:
  bigint(int x = 0);
  bigint(const std::string& s);
  bigint& operator = (const bigint& x);
  bigint& operator = (int x);
  bigint& operator = (const std::string& s);
  const bool operator < (const bigint& x) const;
  const bool operator > (const bigint& x) const;
  const bool operator <= (const bigint& x) const;
  const bool operator >= (const bigint& x) const;
  const bool operator != (const bigint& x) const;
  const bool operator == (const bigint& x) const;
  bigint operator -() const;
  bigint& operator += (const bigint& x);
  bigint& operator -= (const bigint& x);
  bigint& operator *= (const bigint& x);
  bigint& operator /= (const bigint& x);
  bigint& operator %= (const bigint& x);
  const bigint operator + (const bigint& x) const;
  const bigint operator - (const bigint& x) const;
  const bigint operator * (const bigint& x) const;
  const bigint operator / (const bigint& x) const;
  const bigint operator % (const bigint& x) const;
  friend std::pair<bigint,bigint> divmod(const bigint& lhs, const bigint& rhs);
  friend std::istream& operator >> (std::ostream& is, bigint& x); //??????????£?
  friend std::ostream& operator << (std::ostream& os, const bigint& x);
  friend const bigint abs(bigint x);
};
bigint& bigint::normalize() {
  int i = a.size()-1;
  while (i >= 0 && a[i] == 0) --i;
  a.resize(i+1);
  if (a.size() == 0) negative = false;
  return *this;
}
bigint::bigint(int x) : negative(x<0) {
  x = abs(x);
  for (; x > 0; x /= BASE) a.push_back(x % BASE);
}
bigint::bigint(const std::string& s): negative(false) {
  int p = 0;
  if (s[p] == '-') { ++p; negative = true; }
  else if (s[p] == '+') { ++p; }
  for (int i = s.size()-1, v = BASE; i >= p; --i, v*=10) {
    int x = s[i]-'0';
    if (x < 0 || 9 < x) {
      std::cerr<<"error: parse error:"<<s<<std::endl;
      exit(1);
    } 
    if (v == BASE) {
      v = 1;
      a.push_back(x);
    } else a.back() += (x)*v;
  }
  normalize();
}
bigint& bigint::operator = (const bigint& x) {
  negative = x.negative;
  a = x.a;
  return *this;
}
bigint& bigint::operator = (int x) { return *this = bigint(x); }
bigint& bigint::operator = (const std::string& s) { return *this = bigint(s); }
const bool bigint::operator < (const bigint& x) const {
  if (negative != x.negative) return negative < x.negative;
  if (a.size() != x.a.size()) return (a.size() < x.a.size())^negative;
  for(int i = a.size()-1; i >= 0; --i)
    if (a[i] != x.a[i]) return (a[i] < x.a[i])^negative;
  return false;
}
const bool bigint::operator > (const bigint& x) const { return x<(*this); }
const bool bigint::operator <= (const bigint& x) const { return !(x<(*this)); }
const bool bigint::operator >= (const bigint& x) const { return !((*this)<x); }
const bool bigint::operator != (const bigint& x) const { return (*this)<x || x<(*this); }
const bool bigint::operator == (const bigint& x) const { return !((*this)<x || x<(*this)); }
bigint bigint::operator -() const {
  bigint ret(*this);
  if (a.size()) ret.negative = !ret.negative;
  return ret;
}
bigint& bigint::operator += (const bigint& x) {
  if (negative != x.negative) return *this -= -x;
  if (a.size() < x.a.size()) a.resize(x.a.size());
  int tmp = 0;
  for (int i = 0; i < a.size(); ++i) {
    a[i] += (i<x.a.size()?x.a[i]:0) + tmp;
    tmp = a[i] / BASE;
    a[i] %= BASE;
  }
  if (tmp) a.push_back(1);
  return *this;
}
bigint& bigint::operator -= (const bigint& x) {
  if (negative != x.negative) return *this += -x;
  std::vector<int> b(x.a);
  if ((*this < x) ^ negative) {
    a.swap(b);
    negative = !negative;
  }
  for (int i = 0, tmp = 0; i < a.size(); ++i) {
    a[i] += BASE - (i<b.size()?b[i]:0) + tmp;
    tmp = a[i] / BASE - 1;
    a[i] %= BASE;
  }
  return this->normalize();
}
bigint& bigint::operator *= (const bigint& x) {
  negative ^= x.negative;
  std::vector<int> c(a.size()*x.a.size()+1);
  for (int i = 0; i < a.size(); ++i) {
    long long tmp = 0;
    for (int j = 0; j < x.a.size(); ++j) {
      long long v = (long long)a[i] * x.a[j] + c[i+j] + tmp;
      tmp = v / BASE;
      c[i+j] = (int)(v % BASE);
    }
    if (tmp) c[i+x.a.size()] += (int)tmp;
  }
  a.swap(c);
  return this->normalize();
}
bigint& bigint::operator /= (const bigint& x) {
  return *this = divmod(*this,x).first;
}
bigint& bigint::operator %= (const bigint& x) {
  return *this = divmod(*this,x).second;
}
const bigint bigint::operator + (const bigint& x) const {
  bigint res(*this); return res += x;
}
const bigint bigint::operator - (const bigint& x) const {
  bigint res(*this); return res -= x;
}
const bigint bigint::operator * (const bigint& x) const {
  bigint res(*this); return res *= x;
}
const bigint bigint::operator / (const bigint& x) const {
  bigint res(*this); return res /= x;
}
const bigint bigint::operator % (const bigint& x) const {
  bigint res(*this); return res %= x;
}
std::pair<bigint,bigint> divmod(const bigint& lhs, const bigint& rhs) {
  if (!rhs.a.size()) {
    std::cerr<<"error: division by zero"<<std::endl;
    exit(1);
  }
  bigint x(abs(rhs)), q, r;
  for (int i = lhs.a.size()-1; i >= 0; --i) {
    r = r * bigint::BASE + lhs.a[i];
    int head = 0, tail = bigint::BASE;
    if (r >= x) {
      while (head + 1 < tail) {
        int mid = (head + tail) / 2;
        if (x * bigint(mid) > r) tail = mid;
        else head = mid;
      }
      r -= x * head;
    }
    q.a.push_back(head);
  }
  reverse(q.a.begin(), q.a.end());
  bool neg = lhs.negative ^ lhs.negative;
  q.negative = neg; r.negative = neg;
  return std::make_pair(q.normalize(), r.normalize());
}
std::istream& operator >> (std::istream& is, bigint& x) {
  std::string tmp; is >> tmp;
  x = bigint(tmp);
  return is;
}
std::ostream& operator << (std::ostream& os, const bigint& x) {
  if (x.negative) os << '-';
  if (!x.a.size()) os << 0;
  else os << x.a.back();
  for (int i = x.a.size()-2; i >= 0; --i) {
    os.width(bigint::LEN);
    os.fill('0');
    os << x.a[i];
  }
  return os;
}
const bigint abs(bigint x) {
  x.negative = false;
  return x;
}

bigint base=bigint("100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
bigint inf=bigint("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");

typedef pair<bigint,int> P;

struct edge{
  int to,rev;
  bigint cap,cost;
  edge(){}
  edge(int to,bigint cap,int rev,bigint cost):to(to),cap(cap),rev(rev),cost(cost){}
};

int V;
vector<edge> G[MAX_V];
bigint h[MAX_V];
bigint dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];

void add_edge(int from,int to,bigint cap,bigint cost){
  G[from].push_back(edge(to,cap,G[to].size(),cost));
  G[to].push_back(edge(from,0,G[from].size()-1,-cost));
}

bigint min_cost_flow(int s,int t,bigint f){
  bigint res=0;
  for(int i=0;i<V;i++) h[i]=0;
  while(f>0){
    priority_queue<P,vector<P>,greater<P> > que;
    for(int i=0;bigint(i)<V;i++) dist[i]=inf;
    dist[s]=bigint(0);
    que.push(P(0,s));
    while(!que.empty()){
      P p=que.top();que.pop();
      int v=p.second;
      if(dist[v]<p.first) continue;
      for(int i=0;i<(int)G[v].size();i++){
	edge &e=G[v][i];
	if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
	  dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
	  prevv[e.to]=v;
	  preve[e.to]=i;
	  que.push(P(dist[e.to],e.to));
	}
      }
    }
    if(dist[t]==INF){
      return -1;
    }
    for(int v=0;bigint(v)<V;v++) h[v]+=dist[v];

    bigint d=f;
    for(int v=t;v!=s;v=prevv[v]){
      d=min(d,G[prevv[v]][preve[v]].cap);
    }
    f-=d;
    res+=d*h[t];
    for(int v=t;v!=s;v=prevv[v]){
      edge &e=G[prevv[v]][preve[v]];
      e.cap-=d;
      G[v][e.rev].cap+=d;
    }
  }
  return res;
}

signed main(){
  int n;
  cin>>n;
  string str[n],ans;
  for(int i=0;i<n;i++) cin>>str[i];
  V=n*2+2;
  int s=n*2,t=n*2+1;
  
  for(int i=0;i<n;i++){
    add_edge(s,i,1,0);
    add_edge(n+i,t,1,0);
  }
  bigint cost[52];
  for(int i=0;i<52;i++){
    cost[i]=1;
    for(int j=0;j<52-i;j++){
      cost[i]*=52;
    }
  }
  map<char,int> c;
  for(char i='A';i<='Z';i++) c[i]=i-'A';
  for(char i='a';i<='z';i++) c[i]=i-'a'+26;
  
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      add_edge(i,n+j,1,base-cost[c[str[i][j]]]);

  min_cost_flow(s,t,bigint(n));
  

  for(int i=0;i<n;i++){
    for(int j=0;j<(int)G[i].size();j++){
      if(G[i][j].cap>bigint(0)) continue;
      ans+=str[i][G[i][j].to-n];
    }
  }
  sort(ans.begin(),ans.end());
  cout<<ans<<endl;
  return 0;
}
```