Problem: A substring of a string is a contiguous subsequence of that string. So, string bca is substring of string abcabc, but string cc is not.

A repeating block is a string formed by concatenating some string with itself. So, string abcabc is a repeating block, but strings abcabd, ababab are not.

You've got a sequence of Latin characters (string). At each step you find the shortest substring that is a repeating block, if there exists more than one you must choose the leftmost. As the substring is of form XX (X — some string) you replace this substring with X, in other words you delete one of the X substrings in the substring. You repeat this process until there remains no repeating block in the string. 

How would the final string looks like? Look at the sample explanation to understand the statement more precise.

Input

In the first line of input you're given a string of small Latin characters with length between 1 to 50000, inclusive.

Output

Print the final string after applying changes.

Examples

Input

abccabc


Output

abc


Input

aaaabaaab


Output

ab


Input

birdbirdbirdistheword


Output

birdistheword

Note

At the first sample the string transforms as follows: abccabc →  abcabc →  abc.

At the second sample the string transforms as follows: aaaabaaab →  aaabaaab →  aabaaab →  abaaab →  abaab →  abab →  ab.

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;

public class D {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int FAST_THRESHOLD = 100;
	static final int INF = Integer.MAX_VALUE / 2;

	static List<Integer> shortestTandems(String s) {
		String rev = new StringBuilder(s).reverse().toString();
		return shortestTandems(s, rev);
	}

	static List<Integer> shortestTandems(String s, String rev) {
		// res[0] = len, res[1..) = positions of second half
		// returns [inf] if there are no tandmes

		if (s.length() < FAST_THRESHOLD) {
			List<Integer> ret = new ArrayList<>();
			for (int len = 1; len * 2 <= s.length(); len++) {
				for (int i = len; i <= s.length() - len; i++) {
					if (s.substring(i - len, i).equals(s.substring(i, i + len))) {
						if (ret.isEmpty())
							ret.add(len);
						ret.add(i);
					}
				}
				if (!ret.isEmpty()) {
					return ret;
				}
			}
			ret.add(INF);
			return ret;
		}
		int n = s.length();
		int lenL = n / 2;
		int lenR = n - lenL;
		String left = s.substring(0, lenL);
		String right = s.substring(lenL);
		String leftRev = rev.substring(lenR);
		String rightRev = rev.substring(0, lenR);

		List<Integer> goL = shortestTandems(left, leftRev);
		List<Integer> goR = shortestTandems(right, rightRev);
		for (int i = 1; i < goR.size(); i++) {
			goR.set(i, goR.get(i) + lenL);
		}

		List<Integer> mid = new ArrayList<Integer>();
		mid.add(Math.min(goL.get(0), goR.get(0)));

		int[] z1 = zFunc(right + left);
		int[] z2 = zFunc(leftRev + rightRev);
		// left
		for (int len = 1; len <= mid.get(0) && len <= lenL; len++) {
			int forw = Math.min(len, z1[n - len]);
			int back = Math.min(z2[len], Math.min(lenL - len, len));

			if (forw > 0 && forw + back >= len) {
				for (int i = Math.max(len - back, 1); i <= forw; i++) {
					update(mid, len, lenL - len + i);
				}
			}
		}

		// right
		for (int len = 1; len <= mid.get(0) && len <= lenR; len++) {
			int forw = Math.min(z1[len], Math.min(len, lenR - len));
			int back = Math.min(len, z2[n - len]);
			if (back > 0 && forw + back >= len) {
				// min(len - 1, back) cause we don't want to count abab in
				// xab|aby twice
				for (int i = Math.min(len - 1, back); i >= Math.max(len - forw,
						1); i--) {
					update(mid, len, lenL + len - i);
				}
			}
		}

		return combine(combine(goL, mid), goR);
	}

	static void update(List<Integer> ret, int len, int pos) {
		if (len < ret.get(0)) {
			ret.clear();
			ret.add(len);
		}
		ret.add(pos);
	}

	static List<Integer> combine(List<Integer> p1, List<Integer> p2) {
		if (!p1.get(0).equals(p2.get(0))) {
			return p1.get(0) < p2.get(0) ? p1 : p2;
		}
		for (int i = 1; i < p2.size(); i++)
			p1.add(p2.get(i));
		return p1;
	}

	static int[] zFunc(String s) {
		int n = s.length();
		int[] z = new int[n];
		for (int i = 1, l = 0, r = 0; i < n; i++) {
			int val = i < r ? Math.min(r - i, z[i - l]) : 0;
			while (i + val < n && s.charAt(val) == s.charAt(i + val))
				val++;
			if (i + val > r) {
				l = i;
				r = i + val;
			}
			z[i] = val;
		}
		return z;
	}

	static String solve(String s) {
		while (true) {
			List<Integer> tand = shortestTandems(s);
			if (tand.get(0).intValue() == INF) {
				break;
			}
			StringBuilder sb = new StringBuilder();
			int len = tand.get(0);
			for (int i = 0, j = 1, rem = 0; i < s.length(); i++) {
				if (j < tand.size() && i == tand.get(j).intValue()) {
					rem = i + len;
					j++;
				}
				if (i >= rem)
					sb.append(s.charAt(i));
			}
			s = sb.toString();
		}
		return s;
	}

	static String solveEgor(String ss) {
		char[] s = ss.toCharArray();
		int size = s.length;
		boolean[] processed = new boolean[size];
		for (int i = 1; i * 2 <= size; i++) {
			int j = 0;
			int k = i;
			int same = 0;
			boolean change = false;
			while (k < size) {
				if (s[j] == s[k])
					same++;
				else
					same = 0;
				if (same == i) {
					for (int l = 0; l < i; l++) {
						processed[j - l] = true;
					}
					same = 0;
					change = true;
				}
				j++;
				k++;
			}
			if (change) {
				int newSize = 0;
				for (int l = 0; l < size; l++) {
					if (!processed[l])
						s[newSize++] = s[l];
				}
				size = newSize;
				Arrays.fill(processed, 0, size, false);
			}
		}
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < size; i++)
			builder.append(s[i]);
		return builder.toString();
	}

	void solve() throws IOException {
		String s = br.readLine();
		//out.println(solve(s));
		out.println(solveEgor(s));
	}

	D() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

	public static void main(String[] args) throws IOException {
		new D();
	}

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
}