#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-10;
vector<int> z_function(const string& s) {
  int n = (int)s.length();
  vector<int> z(n);
  for (int i = 1, l = 0, r = 0; i < n; ++i) {
    if (i <= r) z[i] = min(r - i + 1, z[i - l]);
    while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
    if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
  }
  return z;
}
const int maxn = 50001;
bool currentState;
struct segment_tree {
  int n;
  vector<int> t, a;
  segment_tree() {}
  segment_tree(int n) : n(n) {
    t.resize(4 * n, -1);
    a.resize(4 * n, 0);
  }
  void update(int v, int tl, int tr) {
    if (t[v] == -1) return;
    if (tl == tr)
      a[v] = t[v];
    else {
      a[v] = t[v] * (tr - tl + 1);
      t[v * 2] = t[v * 2 + 1] = t[v];
    }
    t[v] = -1;
  }
  void set(int v, int tl, int tr, int l, int r, int val) {
    update(v, tl, tr);
    if (l > r) return;
    if (l == tl && r == tr) {
      t[v] = val;
      update(v, tl, tr);
      return;
    }
    int tm = (tl + tr) / 2;
    set(v * 2, tl, tm, l, min(r, tm), val);
    set(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, val);
    a[v] = a[v * 2] + a[v * 2 + 1];
  }
  int get(int v, int tl, int tr, int l, int r) {
    update(v, tl, tr);
    if (l > r) return 0;
    if (l == tl && r == tr) return a[v];
    int tm = (tl + tr) / 2;
    return get(v * 2, tl, tm, l, min(r, tm)) +
           get(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r);
  }
  void SET(int l, int r, int val) { set(1, 0, n - 1, l, r, val); }
  int GET(int l, int r) { return get(1, 0, n - 1, l, r); }
};
segment_tree T, T2;
void output_tandem(const string& s, int shift, bool left, int cntr, int l,
                   int l1, int l2) {
  int pos;
  if (left)
    pos = cntr - l1;
  else
    pos = cntr - l1 - l2 - l1 + 1;
  currentState = true;
  int ll = shift + pos, rr = shift + pos + 2 * l - 1;
  if (T.GET(ll, rr) == 0) T.SET(ll, rr, 1), T2.SET(ll, (ll + rr) / 2, 1);
}
void output_tandems(const string& s, int shift, bool left, int cntr, int l,
                    int k1, int k2) {
  int l1 = (l - k2 + k1) / 2;
  if (l1 <= k1 && l - l1 <= k2)
    output_tandem(s, shift, left, cntr, l, l1, l - l1);
}
inline int get_z(const vector<int>& z, int i) {
  return 0 <= i && i < (int)z.size() ? z[i] : 0;
}
void find_tandems(string s, int shift = 0) {
  int n = (int)s.length();
  if (n == 1) return;
  int nu = n / 2, nv = n - nu;
  string u = s.substr(0, nu), v = s.substr(nu);
  string ru = string(u.rbegin(), u.rend()), rv = string(v.rbegin(), v.rend());
  find_tandems(u, shift);
  find_tandems(v, shift + nu);
  vector<int> z1 = z_function(ru), z2 = z_function(v + '#' + u),
              z3 = z_function(ru + '#' + rv), z4 = z_function(v);
  for (int cntr = 0; cntr < n; ++cntr) {
    int l, k1, k2;
    if (cntr < nu) {
      l = nu - cntr;
      k1 = get_z(z1, nu - cntr);
      k2 = get_z(z2, nv + 1 + cntr);
    } else {
      l = cntr - nu + 1;
      k1 = get_z(z3, nu + 1 + nv - 1 - (cntr - nu));
      k2 = get_z(z4, (cntr - nu) + 1);
    }
    if (k1 + k2 >= l) output_tandems(s, shift, cntr < nu, cntr, l, k1, k2);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  string s;
  cin >> s;
  T = segment_tree((int)s.length());
  T2 = segment_tree((int)s.length());
  do {
    currentState = false;
    T.SET(0, T.n - 1, 0);
    T2.SET(0, T.n - 1, 0);
    find_tandems(s);
    string ns = "";
    for (int i = 0; i < (int)s.length(); i++)
      if (T2.GET(i, i) == 0) ns += s[i];
    s = ns;
  } while (currentState);
  cout << s << endl;
}
