#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

char buf[2001],work[2001];
int work_index;
bool check[1000][1000];


void func(){
	work_index = 0;

	for(int i = 0; buf[i] != '\0'; i++){
		if(buf[i] >= 'a' && buf[i] <= 'z'){
			work[work_index++] = buf[i]-32;
		}else if(buf[i] >= 'A' && buf[i] <= 'Z'){
			work[work_index++] = buf[i];
		}
	}
	if(work_index == 0){
		printf("\n");
		return;
	}

	for(int i = 0; i < work_index; i++){
		for(int k = 0; k < work_index; k++){
			check[i][k] = false;
		}
	}

	vector<string> V,REMOVE;
	bool FLG;

	for(int length = work_index; length >= 3; length--){
		for(int i = 0; i+length-1 < work_index; i++){
			if(check[i][i+length-1])continue;

			FLG = true;
			for(int k = 0; k < (length)/2; k++){
				if(work[i+k] != work[i+length-1-k]){
					FLG = false;
					break;
				}
			}

			if(!FLG)continue;

			string tmp;
			for(int k = i; k <= i+length-1; k++){
				tmp += work[k];
			}


			for(int k = 0; k < REMOVE.size(); k++){
				if(tmp == REMOVE[k]){
					FLG = false;
					break;
				}
			}
			if(!FLG)continue;

			V.push_back(tmp);

			for(int k = 0; k < length/2; k++){
				check[i+k][i+length-1-k] = true;
				string tmp2;
				for(int p = i+k; p <= i+length-1-k; p++){
					tmp2 += work[p];
				}
				REMOVE.push_back(tmp2);
			}
		}
	}

	if(V.size() == 0){
		printf("\n");
		return;
	}

	//sort(V.begin(),V.end());

	printf("%s",V[0].c_str());
	for(int i = 1; i < V.size(); i++){
		printf(" %s",V[i].c_str());
	}
	printf("\n");
}


int main(){

	while(fgets(buf,2000,stdin) != NULL){
		func();
	}

	return 0;
}