#include <bits/stdc++.h>
using namespace std;
template <typename T, typename E>
T qpow(T x, E e) {
  if (e == 0) return 1;
  if (e % 2 == 0) return qpow(x * x, e / 2);
  return x * qpow(x * x, e / 2);
}
template <unsigned m>
struct Mint {
  Mint() : val(0) {}
  Mint(int raw) : val((raw % m + m) % m) {}
  Mint(long long raw) : val((raw % m + m) % m) {}
  Mint(unsigned raw) : val(raw % m) {}
  Mint(unsigned long long raw) : val(raw % m) {}
  friend Mint operator+(Mint a, Mint b) { return a.val + b.val; }
  friend Mint operator-(Mint a, Mint b) { return m + a.val - b.val; }
  friend Mint operator*(Mint a, Mint b) { return 1ull * a.val * b.val; }
  friend Mint operator/(Mint a, Mint b) { return a * qpow(b, m - 2); }
  friend Mint& operator+=(Mint& a, Mint b) { return a = a + b; }
  friend Mint& operator-=(Mint& a, Mint b) { return a = a - b; }
  friend Mint& operator*=(Mint& a, Mint b) { return a = a * b; }
  friend Mint& operator/=(Mint& a, Mint b) { return a = a / b; }
  friend bool operator==(Mint a, Mint b) { return a.val == b.val; }
  friend bool operator!=(Mint a, Mint b) { return a.val != b.val; }
  friend ostream& operator<<(ostream& out, Mint x) { return out << x.val; }
  unsigned val;
};
template <typename T>
T load() {
  T r;
  cin >> r;
  return r;
}
template <typename T>
vector<T> loadMany(int n) {
  vector<T> rs(n);
  generate(rs.begin(), rs.end(), &load<T>);
  return rs;
}
using M = Mint<1000000349>;
vector<M> pexp(1000001);
vector<M> pinv(1000001);
vector<M> prefhashes(const string& txt) {
  auto hash = vector<M>(txt.size() + 1, 0);
  for (auto i = 0; i < (int)txt.size(); ++i) {
    hash[i + 1] = hash[i] + txt[i] * pexp[i];
  }
  return hash;
}
M hashslice(const vector<M>& hash, int i, int j) {
  return (hash[j] - hash[i]) * pinv[i];
}
string wordmerge(string&& a, string&& b) {
  auto n1 = (int)a.size();
  auto n2 = (int)b.size();
  auto h1 = prefhashes(a);
  auto h2 = prefhashes(b);
  for (auto l = min(n1, n2); l >= 0; --l)
    if (hashslice(h1, n1 - l, n1) == hashslice(h2, 0, l))
      return move(a) + move(b).substr(l);
  assert(false);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  auto n = load<int>();
  auto words = loadMany<string>(n);
  auto lensum = 0;
  for (auto& word : words) {
    lensum += (int)word.size();
  }
  pexp[0] = 1;
  pinv[0] = 1;
  for (auto i = 0; i < lensum; ++i) {
    pexp[i + 1] = pexp[i] * 907;
    pinv[i + 1] = 1 / pexp[i + 1];
  }
  auto total = string();
  auto th = vector<M>(1, 0);
  for (auto& word : words) {
    auto wh = prefhashes(word);
    for (auto l = min((int)word.size(), (int)total.size());; --l) {
      assert(l >= 0);
      if (hashslice(th, (int)total.size() - l, (int)total.size()) ==
          hashslice(wh, 0, l)) {
        for (auto j = l; j < (int)word.size(); ++j) {
          auto i = total.size();
          total += word[j];
          th.push_back(th.back() + pexp[i] * word[j]);
        }
        break;
      }
    }
  }
  cout << total << '\n';
}
