#include <bits/stdc++.h>

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a) { cout << #a << " = " << a << endl; }
template<class T1, class T2> inline bool minimize(T1 &a, T2 b) { return b < a && (a = b, 1); }
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }

typedef long long ll;
int const inf = 1<<29;

struct bigint : public array<int, 52> {
  bigint() { this->fill(0); }
};

bigint operator + (bigint const& l, bigint const& r) {
  bigint ret;
  rep(i, l.size()) ret[i] = l[i] + r[i];
  return ret;
}

bigint& operator += (bigint& l, bigint const& r) {
  rep(i, l.size()) l[i] += r[i];
  return l;
}

bigint& operator -= (bigint& l, bigint const& r) {
  rep(i, l.size()) l[i] -= r[i];
  return l;
}

bigint operator - (bigint const& l, bigint const& r) {
  bigint ret;
  rep(i, ret.size()) ret[i] = l[i] - r[i];
  return ret;
}

bigint operator * (int k, bigint const& x) {
  auto ret = x;
  rep(i, ret.size()) ret[i] *= k;
  return ret;
}

bigint operator - (bigint const& x) {
  auto ret = x;
  rep(i, ret.size()) ret[i] *= -1;
  return ret;
}

ostream& operator << (ostream& ost, bigint const& xs) {
  ost << "[";
  rep(i, xs.size()) ost << xs[i] << ", ";
  return ost << "]";
}

namespace flow {

template<typename Flow, typename Cost>
struct edge_ {
  int to; Flow cap; Cost cost; int rev;
  edge_(int t, Flow ca, Cost co, int r) : to{t}, cap{ca}, cost{co}, rev{r} {}
};

typedef edge_<int, bigint> edge;

template<typename Flow, typename Cost>
struct primal_dual {

  vector<vector<edge>> G;
  vector<Cost> h, dist;
  vector<int> prevv, preve;

  Cost zero_cost = bigint();
  Cost infinity_cost;
  Cost none_cost;

  bool cannot_reach_sink(int sink) {
    return dist[sink] == infinity_cost;
  }

  primal_dual(int V) : G(V), h(V), dist(V), prevv(V), preve(V) {
    rep(i, infinity_cost.size()) {
      infinity_cost[i] = none_cost[i] = inf;
    }
  }

  void add_edge(int from, int to, Flow cap, Cost cost) {
    G[from].emplace_back(to, cap, cost, G[to].size());
    G[to].emplace_back(from, 0, -cost, G[from].size()-1);
  }

  Cost min_cost_flow(int s, int t, Flow f) {
    Cost ret = zero_cost;
    fill(h.begin(), h.end(), zero_cost);
    while(f > 0) {
      typedef pair<Cost, int> P;
      priority_queue<P, vector<P>, greater<P>> pq;
      fill(dist.begin(), dist.end(), infinity_cost);
      dist[s] = zero_cost;
      pq.emplace(zero_cost, s);
      while(!pq.empty()) {
        P p = pq.top(); pq.pop();
        int v = p.second;
        if(dist[v] < p.first) continue;
        for(int i=0; i<G[v].size(); i++) {
          auto& 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;
            pq.emplace(dist[e.to], e.to);
          }
        }
      }

      if(cannot_reach_sink(t)) return none_cost;
      for(int i=0; i<h.size(); i++)
        h[i] += dist[i];

      Flow d = f;
      for(int i=t; i!=s; i=prevv[i])
        d = min(d, G[prevv[i]][preve[i]].cap);

      f -= d;
      ret += d * h[t];
      for(int i=t; i!=s; i=prevv[i]) {
        auto& e = G[prevv[i]][preve[i]];
        e.cap -= d;
        G[i][e.rev].cap += d;
      }
    }
    return ret;
  }

};

}

typedef flow::primal_dual<int, bigint> PrimalDual;

int main() {

  int N; cin >> N;
  vector<string> G(N);
  rep(i, N) cin >> G[i];

  string coef; rep(k, 2) rep(i, 26) coef += char("Aa"[k] + i);

  PrimalDual pd(N * 2 + 2);
  rep(i, N) rep(j, N) {
    bigint cost;
    cost[coef.find(G[i][j])]++;
    pd.add_edge(i, N+j, 1, -cost);
  }

  const int SRC = N * 2, SINK = N * 2 + 1;
  rep(i, N) {
    pd.add_edge(SRC, i, 1, bigint());
    pd.add_edge(N+i, SINK, 1, bigint());
  }

  auto r = -pd.min_cost_flow(SRC, SINK, N);

  rep(i, coef.size()) {
    rep(k, r[i]) cout << coef[i];
  }

  cout << 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 REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a) { cout << #a << " = " << a << endl; }
template<class T1, class T2> inline bool minimize(T1 &a, T2 b) { return b < a && (a = b, 1); }
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }

typedef long long ll;
int const inf = 1<<29;

struct bigint : public array<int, 52> {
  bigint() { this->fill(0); }
};

bigint operator + (bigint const& l, bigint const& r) {
  bigint ret;
  rep(i, l.size()) ret[i] = l[i] + r[i];
  return ret;
}

bigint& operator += (bigint& l, bigint const& r) {
  rep(i, l.size()) l[i] += r[i];
  return l;
}

bigint& operator -= (bigint& l, bigint const& r) {
  rep(i, l.size()) l[i] -= r[i];
  return l;
}

bigint operator - (bigint const& l, bigint const& r) {
  bigint ret;
  rep(i, ret.size()) ret[i] = l[i] - r[i];
  return ret;
}

bigint operator * (int k, bigint const& x) {
  auto ret = x;
  rep(i, ret.size()) ret[i] *= k;
  return ret;
}

bigint operator - (bigint const& x) {
  auto ret = x;
  rep(i, ret.size()) ret[i] *= -1;
  return ret;
}

ostream& operator << (ostream& ost, bigint const& xs) {
  ost << "[";
  rep(i, xs.size()) ost << xs[i] << ", ";
  return ost << "]";
}

namespace flow {

template<typename Flow, typename Cost>
struct edge_ {
  int to; Flow cap; Cost cost; int rev;
  edge_(int t, Flow ca, Cost co, int r) : to{t}, cap{ca}, cost{co}, rev{r} {}
};

typedef edge_<int, bigint> edge;

template<typename Flow, typename Cost>
struct primal_dual {

  vector<vector<edge>> G;
  vector<Cost> h, dist;
  vector<int> prevv, preve;

  Cost zero_cost = bigint();
  Cost infinity_cost;
  Cost none_cost;

  bool cannot_reach_sink(int sink) {
    return dist[sink] == infinity_cost;
  }

  primal_dual(int V) : G(V), h(V), dist(V), prevv(V), preve(V) {
    rep(i, infinity_cost.size()) {
      infinity_cost[i] = none_cost[i] = inf;
    }
  }

  void add_edge(int from, int to, Flow cap, Cost cost) {
    G[from].emplace_back(to, cap, cost, G[to].size());
    G[to].emplace_back(from, 0, -cost, G[from].size()-1);
  }

  Cost min_cost_flow(int s, int t, Flow f) {
    Cost ret = zero_cost;
    fill(h.begin(), h.end(), zero_cost);
    while(f > 0) {
      typedef pair<Cost, int> P;
      priority_queue<P, vector<P>, greater<P>> pq;
      fill(dist.begin(), dist.end(), infinity_cost);
      dist[s] = zero_cost;
      pq.emplace(zero_cost, s);
      while(!pq.empty()) {
        P p = pq.top(); pq.pop();
        int v = p.second;
        if(dist[v] < p.first) continue;
        for(int i=0; i<G[v].size(); i++) {
          auto& 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;
            pq.emplace(dist[e.to], e.to);
          }
        }
      }

      if(cannot_reach_sink(t)) return none_cost;
      for(int i=0; i<h.size(); i++)
        h[i] += dist[i];

      Flow d = f;
      for(int i=t; i!=s; i=prevv[i])
        d = min(d, G[prevv[i]][preve[i]].cap);

      f -= d;
      ret += d * h[t];
      for(int i=t; i!=s; i=prevv[i]) {
        auto& e = G[prevv[i]][preve[i]];
        e.cap -= d;
        G[i][e.rev].cap += d;
      }
    }
    return ret;
  }

};

}

typedef flow::primal_dual<int, bigint> PrimalDual;

int main() {

  int N; cin >> N;
  vector<string> G(N);
  rep(i, N) cin >> G[i];

  string coef; rep(k, 2) rep(i, 26) coef += char("Aa"[k] + i);

  PrimalDual pd(N * 2 + 2);
  rep(i, N) rep(j, N) {
    bigint cost;
    cost[coef.find(G[i][j])]++;
    pd.add_edge(i, N+j, 1, -cost);
  }

  const int SRC = N * 2, SINK = N * 2 + 1;
  rep(i, N) {
    pd.add_edge(SRC, i, 1, bigint());
    pd.add_edge(N+i, SINK, 1, bigint());
  }

  auto r = -pd.min_cost_flow(SRC, SINK, N);

  rep(i, coef.size()) {
    rep(k, r[i]) cout << coef[i];
  }

  cout << endl;

  return 0;
}
```