#include<stdio.h>
#include<iostream>
#include<string>
#include<cstring>
#include <iomanip>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#include<set>
#include<bitset>
#include<map>
#include<queue>
#include<math.h>
#include <time.h>
using namespace std;
//set<int>::iterator it;
#define mdlo 1000000007
#define maxERR 0.000000002
//#define minVal -10000000000000
#define maxBits 40
#define pi 3.1415926535897932384626433832795
#define INF 999999999999
#define lim 10000007
typedef long long ll;
long long mInv[41];
long long fact[41];
long long factInv[41];
map<string,long>cityId;
typedef vector<long>adjList;
typedef pair<long,long>edge;
vector<edge>criticalEdges;
adjList Graph[29];
ll heights[5];
ll segTree[3];
long nums[5005];
long g[5005];

ll S[1000006];
ll M[1000006];

ll as,cs,rs;
ll am,cm,rm;
ll N,D;
//ll dp[2][5002][5002];
vector<long>primes;
vector<long>badPrimes;
long funcVal[1];
long dfs_num[29],dfs_low[29],visited[29],parent[19],criticalNode[19];
set<string>dictionary;
set<string>::iterator it;
pair<set<string>::iterator,bool> ret;
typedef multiset<long> numset;
ll gcd(ll a,ll b){
    if(b==0)
        return a;
    if(a%b==0)
        return b;
    return gcd(b,a%b);
}
long long getmoduloInv(long long n){
    if(n==1)
        return 1;
    if(mInv[n]>0)
        return mInv[n];
    long long m=(-1*mdlo)/n;
    m+=mdlo;
    m*=getmoduloInv(mdlo%n);
    mInv[n]=(m%mdlo);
    return mInv[n];
}
vector< long> get_primes(unsigned long maxN){

    char *sieve;
    sieve = new char[maxN/8+1];
    // Fill sieve with 1
    long m=(maxN/8)+1;
    for(long long i=0;i<m;i++)
        sieve[i]=255;
    for(unsigned long x = 2; x <= maxN; x++)
        if(sieve[x/8] & (0x01 << (x % 8))){
            primes.push_back(x);
            // Is prime. Mark multiplicates.
            for(unsigned long j = 2*x; j <= maxN; j += x)
                sieve[j/8] &= ~(0x01 << (j % 8));
        }
    delete[] sieve;
    return primes;
}
ll getPow(ll b,ll p){
	if(b<2||p==1)
		return b;
	if(p==0)
		return 1;
	ll val=getPow(b,p/2);
	val*=val;
	val%=mdlo;
	if(p%2==1){
		val*=b;
		val%=mdlo;
	}
	return val;
}
void buildSegTree(long node,long b,long e){
    if(b==e)
        segTree[node]=b;
    else{
        long mid=(b+e)/2;
        buildSegTree(node*2,b,mid);
        buildSegTree(1+node*2,mid+1,e);
        if(heights[segTree[node*2]]<=heights[segTree[1+node*2]])
            segTree[node]=segTree[node*2];
        else
            segTree[node]=segTree[1+node*2];
    }
}
long long getMin(long node,long segBeg,long segEnd,long qBeg,long qEnd){
    if(segEnd<qBeg||segBeg>qEnd)
        return N+1;
    if(segBeg>=qBeg&&segEnd<=qEnd)
        return segTree[node];
    long mid=(segBeg+segEnd)/2;
    long fh=getMin(node*2,segBeg,mid,qBeg,qEnd);
    long sh=getMin(1+node*2,mid+1,segEnd,qBeg,qEnd);
    if(heights[sh]<heights[fh])
        return sh;
    return fh;
}
long bff[1100];
long inq[1010];
long source;
long oneEndBig=0,oneEndSmall=0,twoendans,zeroendans;
typedef pair<long,long>ee;
typedef pair<long,ee>openAns;
vector<openAns>allopenANs;
long bigEntry,bigExit,smallEntry,smallExit;
long dfs(long node,long curLen){
    if(inq[node]==0){
        inq[node]=1;
        dfs(bff[node],curLen+1);
    }
    else if(node==source)
    {
        if(zeroendans<curLen)
            zeroendans=curLen;
    }
    else if(bff[bff[node]]==node){
        curLen-=2;
        openAns oA;
        oA.first=curLen;
        oA.second.first=bff[node];
        oA.second.first=node;
        allopenANs.push_back(oA);
    }
  //  queue<long>
  return 0;
}
long dp[1010][5];
long wordLen;
string s1,s2,s3;
bool isvalid(long pos,long prev){
    if(dp[pos][prev]==0)
        return false;
    if(dp[pos][prev]==1)
        return true;
    ll remaining=wordLen-(pos);
    if(remaining==0)
        return true;
    if(remaining==1||remaining<0)
        return false;
    if(prev==2){
        if(remaining>4||isvalid(pos+3,3)||remaining==3){
        dp[pos][prev]=1;
        return true;
        }
        if(s1[pos]!=s1[pos-2]||s1[pos+1]!=s1[pos-1]){
            return isvalid(pos+2,2);
        }
        return false;
    }
    if(prev==3){
        if(isvalid(pos+2,2)){
            dp[pos][prev]=1;
            return true;
        }
        for(long i=0;i<3;i++)
        {
            if(s1[pos+i]!=s1[pos+i-3]){
                if(isvalid(pos+3,3)){
                    dp[pos][prev]=1;
                    return true;
                }
                else{
                    dp[pos][prev]=0;
                    return false;
                }
            }
        }
    }

}
long perMutation[20];

long getSuffixes(string s){
    if(s.length()<7){
        cout<<0<<endl;
        return 0;
    }
    wordLen=s.size();
/*
    if(s.length()<9){
        s2="";
        for(long i=5;i<s.length();i++)
            s2+=s1[i];
        dictionary.insert(s2);
        return 1;
    }
    */
    for(long i=5;i+1<s.length();i++){
        s2="";
        s2+=s1[i];
        s2+=s1[i+1];
        s3=s2;
        if(i+2<s.length())
        s3+=s1[i+2];
        if(isvalid(i+2,2))
            dictionary.insert(s2);
        else
            s2=s3;
        if(isvalid(i+3,3))
            dictionary.insert(s3);
        else
            s3=s2;

    }

    if(dictionary.size()==1481){
        for(long i=1010;i<wordLen;i++){
            cout<<s[i];
            if((i-1009)%145==0)
                cout<<endl;
        }

    }
    cout<<dictionary.size()<<endl;
    set<string>::iterator it=dictionary.begin();
    while(it!=dictionary.end()){
        cout<<*it<<endl;
        it++;
    }

}
ll getSuffixes(long pos){
    ll remaining=wordLen-(pos+1);
    if(remaining<2)
        return 0;
    if(remaining<4){
        s2="";
        s2+=s1[pos];
        s2+=s1[pos+1];
        if(remaining==3)
            s2+=s1[pos+2];
        dictionary.insert(s2);
        return 1;
    }

}
int main(void){
    //freopen ("E:/inputSmall.txt","r",stdin);
    //freopen ("E:/outputSmall.txt","w",stdout);
    ll test_cases=1,l,seed=1,maxVal;
	//memset(dp,0,sizeof(dp));
	//cin>>test_cases;
    cout << setprecision(15) << fixed;
    memset(dp,-1,sizeof(dp));
    long num;
    ll sum=0,ans=1,maxlen=0,leng;
    double d,h,e,v,area,rainVol;
    for(long T=0;T<test_cases;T++){

        cin>>s1;
        getSuffixes(s1);
        //cout<<ans<<endl;

        //cout<<"Case #"<<T+1<<": ";
        //cout<<max(ans2,zeroendans);
        //cout<<endl;
    }
    return 0;
}
/*ll cumDist1[100005];
ll cumDist2[100005];
vector<ll>distFrom1;
vector<ll>distFrom2;
void initFact(){
    fact[0]=1;
    factInv[0]=1;
    for(ll i=1;i<0;i++){
        factInv[i]=(factInv[i-1]*getmoduloInv(i))%mdlo;
        fact[i]=(fact[i-1]*i)%mdlo;
    }
}
bool isLeapyear(long year){
    if(year%4==0&&(year%100!=0||year%400==0))
        return true;
    return false;
}
ll ds,ms,ys,de,me,ye,dc,mc,yc,day;
void next13th(){
    if(ds<13){
        ds=13;
        return;
    }
    ms++;
    ds=13;
    if(ms>12)
    {
        ms=1;
        ys++;
    }
}
    long months[]={31,28,31,30,31,30,31,31,30,31,30,31};
    long dayBeforeMonth[12];
bool validDate(){
    if(ys>ye)
        return false;
    if(ys<ye)
        return true;
    if(ms>me)
        return false;
    if(ms<me)
        return true;
    if(ds>de)
        return false;
    return true;
}
long getDay(long d,long m,long y){
    long day=((y-1900)*365+(y-1900)/4-(y-1900)/100+(y-1600)/400+dayBeforeMonth[m-1]+d+2)%7;
    if(y%4==0&&m<3){
        if(y%400==0||y%100!=0)
            day=(day+6)%7;
    }
    return day;
}
bool iscurDayFriday(){
    if(getDay(ds,ms,ys)==0)
        return true;
    return false;
}
void dijkstra(long startPoint){
    long m;
    if(startPoint==1)
        m=0;
    else
        m=1;
    distMatrix[m][startPoint]=0;
    priority_queue<edge, vector<edge>,greater <edge>>pq;
    pq.push(edge(0,startPoint));
    while(!pq.empty()){
        edge top=pq.top();
        pq.pop();
        ll d= top.first,u=top.second;
        if(distMatrix[m][u]==d){
            for(long i=0;i<graph[u].size();i++){
                ll v=graph[u][i].second;
                ll ec=graph[u][i].first;
                if(distMatrix[m][v]>distMatrix[m][u]+ec){
                    distMatrix[m][v]=distMatrix[m][u]+ec;
                    pq.push(edge(distMatrix[m][v],v));
                }
            }
        }
    }
}
ll vals[1];
ll dp[1];
ll totalSum[1];
long long mInv[1];
long long fact[1];
long long factInv[1];

//long long pow10[18];
long long getmoduloInv(long long n){
    if(n==1)
        return 1;
    if(mInv[n]>0)
        return mInv[n];
    long long m=(-1*mdlo)/n;
    m+=mdlo;
    m*=getmoduloInv(mdlo%n);
    mInv[n]=(m%mdlo);
    return mInv[n];
}
long long onNthbit(long pos,long val){
    return val|pwr2[pos];
}
bool isNthbitOn(long long pos,long long val){
    return (val&pwr2[pos])>0;
}

seg segTree[5];
long N;
void buildSumSegmentTree(long long b,long long e,long long node){
    if(b==e)
    {
         segTree[node].first=vals[b];
         return;
    }
    long long mid=(b+e)/2;
    buildSumSegmentTree(b,mid,node*2);
    buildSumSegmentTree(mid+1,e,1+(node*2));
    segTree[node].first=segTree[2*node].first+segTree[1+(node*2)].first;
}
long long getSum(long long qStart,long long qEnd,long long sStart,long long sEnd,long long node,prop p){

    long k=sEnd-sStart,n;
    for(long i=0;i<p.size();i++){
        segTree[node].second.push_back(p[i]);
        n=p[i];
        segTree[node].first+=(((n+k)*(n+k+1)*(2*n+2*k+1)-(n*(n-1)*(2*n-1)))/6+((n+k)*(n+k+1)-n*(n-1)))/2;
        }
    if(qEnd<sStart||qStart>sEnd)
    {
        return 0;
    }
    if(sStart>=qStart&&sEnd<=qEnd)
    {
         return segTree[node].first;
    }
    long long sMid=(sStart+sEnd)/2;
    prop l;
    for(long i=0;segTree[node].second.size();i++)
        l.push_back(segTree[node].second[i]+sMid+1-sStart);
    return getSum(qStart,qEnd,sStart,sMid,2*node,segTree[node].second)+getSum(qStart,qEnd,sMid+1,sEnd,1+(2*node),l);
}
long long update(ll node, long long sStart,ll sEnd,long upStart,long upEnd){
    if(upEnd<sStart||upStart>sEnd)
        return 0;
    long k=sEnd-sStart,n=sStart+1-upStart;
    if(upStart<=sStart&&upEnd>=sEnd){
        segTree[node].second.push_back(n);
        segTree[node].first+=(((n+k)*(n+k+1)*(2*n+2*k+1))/6);
        segTree[node].first-=(((n*(n-1)*(2*n-1)))/6);
        segTree[node].first+=(((n+k)*(n+k+1)-n*(n-1)))/2;
        return 0;
    }
    ll sMid=(sStart+sEnd)/2;
    update(node*2,sStart,sMid,upStart,upEnd);
    update(1+(node*2),sMid+1,sEnd,upStart,upEnd);
    segTree[node].first=segTree[2*node].first+segTree[1+(node*2)].first;

    for(long i=0;i<segTree[node].second.size();i++){
        n=segTree[node].second[i];
        segTree[node].first+=(((n+k)*(n+k+1)*(2*n+2*k+1)-(n*(n-1)*(2*n-1)))/6+((n+k)*(n+k+1)-n*(n-1)))/2;
    }
    return segTree[node].first;
}
void update(long x,long y){
    long len=y-x+1,add=0;
    for(long i=0;i<len;i++){
        add+=(i+1)*2;
        update(1,0,N-1,x+i,add+vals[x+i]);
    }
}
long getlen(long long num){
    long len=0;
    while(num>0){
        num/=10;
        len++;
    }
    return len;
}
encryptedLine lineConverter(string s){
    encryptedLine el;
    ll val=0,len=s.size();
    for(long i=0;i<len;i++){
        if(s[i]==' '){
            el.push_back(val);
            val=0;
        }
        else{
            val*=26;
            val+=(s[i]-'a');
        }
    }
    el.push_back(val);
    return el;
}
long getPalinDrome(long num){
    long a=num%10;
    long b=(num/10)%10;
    long c=(num/100)%10;
    return num*1000+a*100+b*10+c;
}

vector<unsigned long> get_primes(unsigned long max){
    vector<unsigned long> primes;
    char *sieve;
    sieve = new char[max/8+1];
    // Fill sieve with 1
    long m=(max/8)+1;
    for(long long i=0;i<m;i++)
        sieve[i]=255;
    for(unsigned long x = 2; x <= max; x++)
        if(sieve[x/8] & (0x01 << (x % 8))){
            primes.push_back(x);
            // Is prime. Mark multiplicates.
            for(unsigned long j = 2*x; j <= max; j += x)
                sieve[j/8] &= ~(0x01 << (j % 8));
        }
    delete[] sieve;
    return primes;
}string add(string a,string b){
    int l1=a.size();
    int l2=b.size();
    while(l1<l2){
        a="0"+a;
        l1++;
    }
    while(l2<l1){
        b="0"+b;
        l2++;
    }
    string s;
    int carry=0;
    for(long i=l2-1;i>-1;i--){
        int d=a[i]+b[i]+carry-2*'0';
        carry=d/10;
        a[i]='0'+(d%10);
    }
    if(carry)
        a="1"+a;
    return a;
}
long long mInv[1010];
long long fact[1000];
long long factInv[1000];
long long getmoduloInv(long long n){
    if(n==1)
        return 1;
    if(mInv[n]>0)
        return mInv[n];
    long long m=(-1*mdlo)/n;
    m+=mdlo;
    m*=getmoduloInv(mdlo%n);
    mInv[n]=(m%mdlo);
    return mInv[n];

}

long dp[200010];
vector<weightedPos>points;
vector<weightedPos>modifiedPositions;
vector<long long>heights;
long long segTree[530010];
long N,X,W;
void buildSegTree(long node,long b,long e){
    if(b==e)
        segTree[node]=b;
    else{
        long mid=(b+e)/2;
        buildSegTree(node*2,b,mid);
        buildSegTree(1+node*2,mid+1,e);
        if(heights[segTree[node*2]]<=heights[segTree[1+node*2]])
            segTree[node]=segTree[node*2];
        else
            segTree[node]=segTree[1+node*2];
    }
}
long long getMin(long node,long segBeg,long segEnd,long qBeg,long qEnd){
    if(segEnd<qBeg||segBeg>qEnd)
        return N;
    if(segBeg>=qBeg&&segEnd<=qEnd)
        return segTree[node];
    long mid=(segBeg+segEnd)/2;
    long fh=getMin(node*2,segBeg,mid,qBeg,qEnd);
    long sh=getMin(1+node*2,mid+1,segEnd,qBeg,qEnd);
    if(heights[sh]<heights[fh])
        return sh;
    return fh;
}
long long getMinPos(long node,long segBeg,long segEnd,long qBeg,long qEnd){
    if(segEnd<qBeg||segBeg<qEnd)
        return 0;
    if(segBeg>=qBeg&&segEnd<=qEnd)
        return segTree[node];
    long mid=(segBeg+segEnd)/2;
    long fh=getMin(node*2,segBeg,mid,qBeg,qEnd);
    long sh=getMin(node*2,mid+1,segEnd,qBeg,qEnd);
    return min(fh,sh);
}
long getPos(long val){
    long low=0,high=modifiedPositions.size()-1;
    long mid=(low+high)/2;
    while(low<high){
        if(modifiedPositions[mid].first<val)
            low=mid+1;
        else
            high=mid-1;
        mid=(low+high)/2;
    }
    if(mid>0)
        mid--;
    while(mid<modifiedPositions.size()&&modifiedPositions[mid].first<val)
        mid++;
    return mid;
}
long getMaxGroup(long index){
    if(dp[index]>-1)
        return dp[index];
    long pos=getPos(points[index].first+points[index].second);
    if(pos>=N)
        return 1;
    long nextPoint=getMin(1,0,N-1,pos,N-1);
    dp[index]=1+getMaxGroup(nextPoint);
    return dp[index];
}
*/


#include<stdio.h>
#include<iostream>
#include<string>
#include<cstring>
#include <iomanip>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#include<set>
#include<bitset>
#include<map>
#include<queue>
#include<math.h>
#include <time.h>
using namespace std;
//set<int>::iterator it;
#define mdlo 1000000007
#define maxERR 0.000000002
//#define minVal -10000000000000
#define maxBits 40
#define pi 3.1415926535897932384626433832795
#define INF 999999999999
#define lim 10000007
typedef long long ll;
long long mInv[41];
long long fact[41];
long long factInv[41];
map<string,long>cityId;
typedef vector<long>adjList;
typedef pair<long,long>edge;
vector<edge>criticalEdges;
adjList Graph[29];
ll heights[5];
ll segTree[3];
long nums[5005];
long g[5005];

ll S[1000006];
ll M[1000006];

ll as,cs,rs;
ll am,cm,rm;
ll N,D;
//ll dp[2][5002][5002];
vector<long>primes;
vector<long>badPrimes;
long funcVal[1];
long dfs_num[29],dfs_low[29],visited[29],parent[19],criticalNode[19];
set<string>dictionary;
set<string>::iterator it;
pair<set<string>::iterator,bool> ret;
typedef multiset<long> numset;
ll gcd(ll a,ll b){
    if(b==0)
        return a;
    if(a%b==0)
        return b;
    return gcd(b,a%b);
}
long long getmoduloInv(long long n){
    if(n==1)
        return 1;
    if(mInv[n]>0)
        return mInv[n];
    long long m=(-1*mdlo)/n;
    m+=mdlo;
    m*=getmoduloInv(mdlo%n);
    mInv[n]=(m%mdlo);
    return mInv[n];
}
vector< long> get_primes(unsigned long maxN){

    char *sieve;
    sieve = new char[maxN/8+1];
    // Fill sieve with 1
    long m=(maxN/8)+1;
    for(long long i=0;i<m;i++)
        sieve[i]=255;
    for(unsigned long x = 2; x <= maxN; x++)
        if(sieve[x/8] & (0x01 << (x % 8))){
            primes.push_back(x);
            // Is prime. Mark multiplicates.
            for(unsigned long j = 2*x; j <= maxN; j += x)
                sieve[j/8] &= ~(0x01 << (j % 8));
        }
    delete[] sieve;
    return primes;
}
ll getPow(ll b,ll p){
	if(b<2||p==1)
		return b;
	if(p==0)
		return 1;
	ll val=getPow(b,p/2);
	val*=val;
	val%=mdlo;
	if(p%2==1){
		val*=b;
		val%=mdlo;
	}
	return val;
}
void buildSegTree(long node,long b,long e){
    if(b==e)
        segTree[node]=b;
    else{
        long mid=(b+e)/2;
        buildSegTree(node*2,b,mid);
        buildSegTree(1+node*2,mid+1,e);
        if(heights[segTree[node*2]]<=heights[segTree[1+node*2]])
            segTree[node]=segTree[node*2];
        else
            segTree[node]=segTree[1+node*2];
    }
}
long long getMin(long node,long segBeg,long segEnd,long qBeg,long qEnd){
    if(segEnd<qBeg||segBeg>qEnd)
        return N+1;
    if(segBeg>=qBeg&&segEnd<=qEnd)
        return segTree[node];
    long mid=(segBeg+segEnd)/2;
    long fh=getMin(node*2,segBeg,mid,qBeg,qEnd);
    long sh=getMin(1+node*2,mid+1,segEnd,qBeg,qEnd);
    if(heights[sh]<heights[fh])
        return sh;
    return fh;
}
long bff[1100];
long inq[1010];
long source;
long oneEndBig=0,oneEndSmall=0,twoendans,zeroendans;
typedef pair<long,long>ee;
typedef pair<long,ee>openAns;
vector<openAns>allopenANs;
long bigEntry,bigExit,smallEntry,smallExit;
long dfs(long node,long curLen){
    if(inq[node]==0){
        inq[node]=1;
        dfs(bff[node],curLen+1);
    }
    else if(node==source)
    {
        if(zeroendans<curLen)
            zeroendans=curLen;
    }
    else if(bff[bff[node]]==node){
        curLen-=2;
        openAns oA;
        oA.first=curLen;
        oA.second.first=bff[node];
        oA.second.first=node;
        allopenANs.push_back(oA);
    }
  //  queue<long>
  return 0;
}
long dp[1010][5];
long wordLen;
string s1,s2,s3;
bool isvalid(long pos,long prev){
    if(dp[pos][prev]==0)
        return false;
    if(dp[pos][prev]==1)
        return true;
    ll remaining=wordLen-(pos);
    if(remaining==0)
        return true;
    if(remaining==1||remaining<0)
        return false;
    if(prev==2){
        if(remaining>4||isvalid(pos+3,3)||remaining==3){
        dp[pos][prev]=1;
        return true;
        }
        if(s1[pos]!=s1[pos-2]||s1[pos+1]!=s1[pos-1]){
            return isvalid(pos+2,2);
        }
        return false;
    }
    if(prev==3){
        if(isvalid(pos+2,2)){
            dp[pos][prev]=1;
            return true;
        }
        for(long i=0;i<3;i++)
        {
            if(s1[pos+i]!=s1[pos+i-3]){
                if(isvalid(pos+3,3)){
                    dp[pos][prev]=1;
                    return true;
                }
                else{
                    dp[pos][prev]=0;
                    return false;
                }
            }
        }
    }

}
long perMutation[20];

long getSuffixes(string s){
    if(s.length()<7){
        cout<<0<<endl;
        return 0;
    }
    wordLen=s.size();
/*
    if(s.length()<9){
        s2="";
        for(long i=5;i<s.length();i++)
            s2+=s1[i];
        dictionary.insert(s2);
        return 1;
    }
    */
    for(long i=5;i+1<s.length();i++){
        s2="";
        s2+=s1[i];
        s2+=s1[i+1];
        s3=s2;
        if(i+2<s.length())
        s3+=s1[i+2];
        if(isvalid(i+2,2))
            dictionary.insert(s2);
        if(isvalid(i+3,3))
            dictionary.insert(s3);

    }

    if(dictionary.size()==1481){
        for(long i=0;i<wordLen;i++){
            cout<<s[i];
            if((i+1)%140==0)
                cout<<endl;
        }

    }
    cout<<dictionary.size()<<endl;
    set<string>::iterator it=dictionary.begin();
    while(it!=dictionary.end()){
        cout<<*it<<endl;
        it++;
    }

}
ll getSuffixes(long pos){
    ll remaining=wordLen-(pos+1);
    if(remaining<2)
        return 0;
    if(remaining<4){
        s2="";
        s2+=s1[pos];
        s2+=s1[pos+1];
        if(remaining==3)
            s2+=s1[pos+2];
        dictionary.insert(s2);
        return 1;
    }

}
int main(void){
    //freopen ("E:/inputSmall.txt","r",stdin);
    //freopen ("E:/outputSmall.txt","w",stdout);
    ll test_cases=1,l,seed=1,maxVal;
	//memset(dp,0,sizeof(dp));
	//cin>>test_cases;
    cout << setprecision(15) << fixed;
    memset(dp,-1,sizeof(dp));
    long num;
    ll sum=0,ans=1,maxlen=0,leng;
    double d,h,e,v,area,rainVol;
    for(long T=0;T<test_cases;T++){

        cin>>s1;
        getSuffixes(s1);
        //cout<<ans<<endl;

        //cout<<"Case #"<<T+1<<": ";
        //cout<<max(ans2,zeroendans);
        //cout<<endl;
    }
    return 0;
}
/*ll cumDist1[100005];
ll cumDist2[100005];
vector<ll>distFrom1;
vector<ll>distFrom2;
void initFact(){
    fact[0]=1;
    factInv[0]=1;
    for(ll i=1;i<0;i++){
        factInv[i]=(factInv[i-1]*getmoduloInv(i))%mdlo;
        fact[i]=(fact[i-1]*i)%mdlo;
    }
}
bool isLeapyear(long year){
    if(year%4==0&&(year%100!=0||year%400==0))
        return true;
    return false;
}
ll ds,ms,ys,de,me,ye,dc,mc,yc,day;
void next13th(){
    if(ds<13){
        ds=13;
        return;
    }
    ms++;
    ds=13;
    if(ms>12)
    {
        ms=1;
        ys++;
    }
}
    long months[]={31,28,31,30,31,30,31,31,30,31,30,31};
    long dayBeforeMonth[12];
bool validDate(){
    if(ys>ye)
        return false;
    if(ys<ye)
        return true;
    if(ms>me)
        return false;
    if(ms<me)
        return true;
    if(ds>de)
        return false;
    return true;
}
long getDay(long d,long m,long y){
    long day=((y-1900)*365+(y-1900)/4-(y-1900)/100+(y-1600)/400+dayBeforeMonth[m-1]+d+2)%7;
    if(y%4==0&&m<3){
        if(y%400==0||y%100!=0)
            day=(day+6)%7;
    }
    return day;
}
bool iscurDayFriday(){
    if(getDay(ds,ms,ys)==0)
        return true;
    return false;
}
void dijkstra(long startPoint){
    long m;
    if(startPoint==1)
        m=0;
    else
        m=1;
    distMatrix[m][startPoint]=0;
    priority_queue<edge, vector<edge>,greater <edge>>pq;
    pq.push(edge(0,startPoint));
    while(!pq.empty()){
        edge top=pq.top();
        pq.pop();
        ll d= top.first,u=top.second;
        if(distMatrix[m][u]==d){
            for(long i=0;i<graph[u].size();i++){
                ll v=graph[u][i].second;
                ll ec=graph[u][i].first;
                if(distMatrix[m][v]>distMatrix[m][u]+ec){
                    distMatrix[m][v]=distMatrix[m][u]+ec;
                    pq.push(edge(distMatrix[m][v],v));
                }
            }
        }
    }
}
ll vals[1];
ll dp[1];
ll totalSum[1];
long long mInv[1];
long long fact[1];
long long factInv[1];

//long long pow10[18];
long long getmoduloInv(long long n){
    if(n==1)
        return 1;
    if(mInv[n]>0)
        return mInv[n];
    long long m=(-1*mdlo)/n;
    m+=mdlo;
    m*=getmoduloInv(mdlo%n);
    mInv[n]=(m%mdlo);
    return mInv[n];
}
long long onNthbit(long pos,long val){
    return val|pwr2[pos];
}
bool isNthbitOn(long long pos,long long val){
    return (val&pwr2[pos])>0;
}

seg segTree[5];
long N;
void buildSumSegmentTree(long long b,long long e,long long node){
    if(b==e)
    {
         segTree[node].first=vals[b];
         return;
    }
    long long mid=(b+e)/2;
    buildSumSegmentTree(b,mid,node*2);
    buildSumSegmentTree(mid+1,e,1+(node*2));
    segTree[node].first=segTree[2*node].first+segTree[1+(node*2)].first;
}
long long getSum(long long qStart,long long qEnd,long long sStart,long long sEnd,long long node,prop p){

    long k=sEnd-sStart,n;
    for(long i=0;i<p.size();i++){
        segTree[node].second.push_back(p[i]);
        n=p[i];
        segTree[node].first+=(((n+k)*(n+k+1)*(2*n+2*k+1)-(n*(n-1)*(2*n-1)))/6+((n+k)*(n+k+1)-n*(n-1)))/2;
        }
    if(qEnd<sStart||qStart>sEnd)
    {
        return 0;
    }
    if(sStart>=qStart&&sEnd<=qEnd)
    {
         return segTree[node].first;
    }
    long long sMid=(sStart+sEnd)/2;
    prop l;
    for(long i=0;segTree[node].second.size();i++)
        l.push_back(segTree[node].second[i]+sMid+1-sStart);
    return getSum(qStart,qEnd,sStart,sMid,2*node,segTree[node].second)+getSum(qStart,qEnd,sMid+1,sEnd,1+(2*node),l);
}
long long update(ll node, long long sStart,ll sEnd,long upStart,long upEnd){
    if(upEnd<sStart||upStart>sEnd)
        return 0;
    long k=sEnd-sStart,n=sStart+1-upStart;
    if(upStart<=sStart&&upEnd>=sEnd){
        segTree[node].second.push_back(n);
        segTree[node].first+=(((n+k)*(n+k+1)*(2*n+2*k+1))/6);
        segTree[node].first-=(((n*(n-1)*(2*n-1)))/6);
        segTree[node].first+=(((n+k)*(n+k+1)-n*(n-1)))/2;
        return 0;
    }
    ll sMid=(sStart+sEnd)/2;
    update(node*2,sStart,sMid,upStart,upEnd);
    update(1+(node*2),sMid+1,sEnd,upStart,upEnd);
    segTree[node].first=segTree[2*node].first+segTree[1+(node*2)].first;

    for(long i=0;i<segTree[node].second.size();i++){
        n=segTree[node].second[i];
        segTree[node].first+=(((n+k)*(n+k+1)*(2*n+2*k+1)-(n*(n-1)*(2*n-1)))/6+((n+k)*(n+k+1)-n*(n-1)))/2;
    }
    return segTree[node].first;
}
void update(long x,long y){
    long len=y-x+1,add=0;
    for(long i=0;i<len;i++){
        add+=(i+1)*2;
        update(1,0,N-1,x+i,add+vals[x+i]);
    }
}
long getlen(long long num){
    long len=0;
    while(num>0){
        num/=10;
        len++;
    }
    return len;
}
encryptedLine lineConverter(string s){
    encryptedLine el;
    ll val=0,len=s.size();
    for(long i=0;i<len;i++){
        if(s[i]==' '){
            el.push_back(val);
            val=0;
        }
        else{
            val*=26;
            val+=(s[i]-'a');
        }
    }
    el.push_back(val);
    return el;
}
long getPalinDrome(long num){
    long a=num%10;
    long b=(num/10)%10;
    long c=(num/100)%10;
    return num*1000+a*100+b*10+c;
}

vector<unsigned long> get_primes(unsigned long max){
    vector<unsigned long> primes;
    char *sieve;
    sieve = new char[max/8+1];
    // Fill sieve with 1
    long m=(max/8)+1;
    for(long long i=0;i<m;i++)
        sieve[i]=255;
    for(unsigned long x = 2; x <= max; x++)
        if(sieve[x/8] & (0x01 << (x % 8))){
            primes.push_back(x);
            // Is prime. Mark multiplicates.
            for(unsigned long j = 2*x; j <= max; j += x)
                sieve[j/8] &= ~(0x01 << (j % 8));
        }
    delete[] sieve;
    return primes;
}string add(string a,string b){
    int l1=a.size();
    int l2=b.size();
    while(l1<l2){
        a="0"+a;
        l1++;
    }
    while(l2<l1){
        b="0"+b;
        l2++;
    }
    string s;
    int carry=0;
    for(long i=l2-1;i>-1;i--){
        int d=a[i]+b[i]+carry-2*'0';
        carry=d/10;
        a[i]='0'+(d%10);
    }
    if(carry)
        a="1"+a;
    return a;
}
long long mInv[1010];
long long fact[1000];
long long factInv[1000];
long long getmoduloInv(long long n){
    if(n==1)
        return 1;
    if(mInv[n]>0)
        return mInv[n];
    long long m=(-1*mdlo)/n;
    m+=mdlo;
    m*=getmoduloInv(mdlo%n);
    mInv[n]=(m%mdlo);
    return mInv[n];

}

long dp[200010];
vector<weightedPos>points;
vector<weightedPos>modifiedPositions;
vector<long long>heights;
long long segTree[530010];
long N,X,W;
void buildSegTree(long node,long b,long e){
    if(b==e)
        segTree[node]=b;
    else{
        long mid=(b+e)/2;
        buildSegTree(node*2,b,mid);
        buildSegTree(1+node*2,mid+1,e);
        if(heights[segTree[node*2]]<=heights[segTree[1+node*2]])
            segTree[node]=segTree[node*2];
        else
            segTree[node]=segTree[1+node*2];
    }
}
long long getMin(long node,long segBeg,long segEnd,long qBeg,long qEnd){
    if(segEnd<qBeg||segBeg>qEnd)
        return N;
    if(segBeg>=qBeg&&segEnd<=qEnd)
        return segTree[node];
    long mid=(segBeg+segEnd)/2;
    long fh=getMin(node*2,segBeg,mid,qBeg,qEnd);
    long sh=getMin(1+node*2,mid+1,segEnd,qBeg,qEnd);
    if(heights[sh]<heights[fh])
        return sh;
    return fh;
}
long long getMinPos(long node,long segBeg,long segEnd,long qBeg,long qEnd){
    if(segEnd<qBeg||segBeg<qEnd)
        return 0;
    if(segBeg>=qBeg&&segEnd<=qEnd)
        return segTree[node];
    long mid=(segBeg+segEnd)/2;
    long fh=getMin(node*2,segBeg,mid,qBeg,qEnd);
    long sh=getMin(node*2,mid+1,segEnd,qBeg,qEnd);
    return min(fh,sh);
}
long getPos(long val){
    long low=0,high=modifiedPositions.size()-1;
    long mid=(low+high)/2;
    while(low<high){
        if(modifiedPositions[mid].first<val)
            low=mid+1;
        else
            high=mid-1;
        mid=(low+high)/2;
    }
    if(mid>0)
        mid--;
    while(mid<modifiedPositions.size()&&modifiedPositions[mid].first<val)
        mid++;
    return mid;
}
long getMaxGroup(long index){
    if(dp[index]>-1)
        return dp[index];
    long pos=getPos(points[index].first+points[index].second);
    if(pos>=N)
        return 1;
    long nextPoint=getMin(1,0,N-1,pos,N-1);
    dp[index]=1+getMaxGroup(nextPoint);
    return dp[index];
}
*/


#include <stdio.h>
#include <algorithm>
#include <map>
#include <string>
FILE *in = stdin;
FILE *out = stdout;

int n;
char board[11004];

std::map<std::string, int> cases;

int tbt[3] = { 676,26,1 };
int len;
void back(int w,int bef)
{
	if (bef == 2)
	{
		if (w >= 7)
		{
			if (!(board[w - 2] == board[w] && board[w - 1] == board[w + 1]))
			{
				std::string a;
				a.append(&board[w - 2], &board[w]);
				cases[a]++;
				back(w - 2, 2);
			}
		}
		if (w >= 8)
		{
			std::string a;
			a.append(&board[w - 3], &board[w]);
			cases[a]++;
			back(w - 3, 3);
		}
	}
	else if (bef == 3)
	{
		if (w >= 8)
		{
			if (!(board[w - 3] == board[w] && board[w - 2] == board[w + 1] && board[w - 1] == board[w + 2]))
			{
				std::string a;
				a.append(&board[w - 3], &board[w]);
				cases[a]++;
				back(w - 3, 3);
			}
		}
		if (w >= 7)
		{
			std::string a;
			a.append(&board[w - 2], &board[w]);
			cases[a]++;
			back(w - 2, 2);
		}
	}
}
int main()
{
	int i, j, k;
	fscanf(in, "%s", board);
	int w = strlen(board);
	if (w >= 7)
	{
		std::string a;
		a.append(&board[w - 2], &board[w]);
		cases[a]++;
		back(w - 2, 2);
	}
	if (w >= 8)
	{
		std::string a;
		a.append(&board[w - 3], &board[w]);
		cases[a]++;
		back(w - 3, 3);
	}
	fprintf(out,"%d\n",cases.size());
	for (std::map<std::string, int>::iterator it = cases.begin(); it != cases.end(); ++it)
	{
		fprintf(out, "%s\n", it->first.data());
	}
	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <map>
#include <string>
FILE *in = stdin;
FILE *out = stdout;

int n;
char board[11004];

std::map<std::string, int> cases;

int tbt[3] = { 676,26,1 };
int len;
int d[11004][4];
std::string a;
void back(int w,int bef)
{
	if (d[w][bef] == 1)return;
	d[w][bef] = 1;
	if (bef == 2)
	{
		if (w >= 7)
		{
			if (!(board[w - 2] == board[w] && board[w - 1] == board[w + 1]))
			{
				a = "";
				a.append(&board[w - 2], &board[w]);
				cases[a]++;
				back(w - 2, 2);
			}
		}
		if (w >= 8)
		{
			a = "";
			a.append(&board[w - 3], &board[w]);
			cases[a]++;
			back(w - 3, 3);
		}
	}
	else if (bef == 3)
	{
		if (w >= 8)
		{
			if (!(board[w - 3] == board[w] && board[w - 2] == board[w + 1] && board[w - 1] == board[w + 2]))
			{
				a = "";
				a.append(&board[w - 3], &board[w]);
				cases[a]++;
				back(w - 3, 3);
			}
		}
		if (w >= 7)
		{
			a = "";
			a.append(&board[w - 2], &board[w]);
			cases[a]++;
			back(w - 2, 2);
		}
	}
}
int main()
{
	int i, j, k;
	fscanf(in, "%s", board);
	int w = strlen(board);
	if (w >= 7)
	{
		a = "";
		a.append(&board[w - 2], &board[w]);
		cases[a]++;
		back(w - 2, 2);
	}
	if (w >= 8)
	{
		a = "";
		a.append(&board[w - 3], &board[w]);
		cases[a]++;
		back(w - 3, 3);
	}
	fprintf(out,"%d\n",cases.size());
	for (std::map<std::string, int>::iterator it = cases.begin(); it != cases.end(); ++it)
	{
		fprintf(out, "%s\n", it->first.data());
	}
	return 0;
}


//Javier Guzmán
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <stack>
#include <utility>
#include <vector>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<ii> vii;

string word;
set<string> suffixes;
int main(){
   cin>>word;
   for(int i=5; i<word.length()-1; i++){
      if(i<word.length()-2 && i!= word.length()-4){
         suffixes.insert(word.substr(i, 3));
      }
      if(i!= word.length()-3){
         suffixes.insert(word.substr(i, 2));
      }
   }
   cout<<suffixes.size()<<endl;
   for(set<string>::iterator it = suffixes.begin(); it!= suffixes.end(); ++it){
      cout<<*it<<endl;
   }
   return 0;
}


//Javier Guzmán
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <stack>
#include <utility>
#include <vector>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<ii> vii;

string word;
set<string> suffixes;
int DP[10001][4];

bool possible(int index, int prevL){
   if(DP[index][prevL]!=-1)
      return DP[index][prevL];
   if(index>word.length())
      return 0;
   if(index==word.length())
      return 1;
   bool r = false;
   if(prevL==2){
      if(word.length()-prevL>=0 && word.substr(index-2, 2)!=word.substr(index, 2)){
         r = r||possible(index+2, 2);
      }
      r = r||possible(index+3, 3);
   }
   if(prevL==3){
      if(word.length()-prevL>=0 && word.substr(index-3, 3)!=word.substr(index, 3)){
         r = r||possible(index+3, 3);
      }
      r = r||possible(index+2, 2);
   }
   return DP[index][prevL] = r;
}
int main(){
   cin>>word;
   memset(DP, -1, sizeof(DP));
   for(int i=5; i<word.length()-1; i++){
      if(possible(i+2, 2)) suffixes.insert(word.substr(i, 2));
      if(possible(i+3, 3)) suffixes.insert(word.substr(i, 3));
   }
   cout<<suffixes.size()<<endl;
   for(set<string>::iterator it = suffixes.begin(); it!= suffixes.end(); ++it){
      cout<<*it<<endl;
   }
   return 0;
}


// rc.cpp : Defines the entry point for the console application.
//

#include <math.h>

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <functional>
#include <iomanip>

using namespace std;

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long long uint64;
typedef long long sint64;

#define PI 3.14159265358979323846
#define EPS 1.E-8

bool u[10011];
const char* p;

bool chk2(uint x)
{
    if (*(p + x) == 0 || *(p + x + 1) == 0)
        return false;

    bool ret = true;
    if (!u[x + 2])
        ret = false;

    if (ret && *(p + x + 2) != 0 && *(p + x + 3) != 0 && *(p + x + 2) == *(p + x) && *(p + x + 3) == *(p + x + 1) &&
        (*(p + x + 4) == 0 || u[x + 5] == false))
        ret = false;

    return ret;
}

bool chk3(uint x)
{
    if (*(p + x + 2) == 0)
        return false;

    bool ret = true;
    if (!u[x + 3])
        ret = false;

    if (ret && *(p + x + 3) != 0 && *(p + x + 4) != 0 && *(p + x + 5) != 0 &&
        *(p + x + 3) == *(p + x) && *(p + x + 4) == *(p + x + 1) && *(p + x + 5) == *(p + x + 2) &&
        (*(p + x + 6) == 0 || u[x + 7] == false))
        ret = false;

    return ret;
}

int main(int argc, char* argv[])
{
    string s;
    cin >> s;

    uint sz = s.size();
    u[sz] = true;
    p = s.c_str();

    if (sz <= 6)
        cout << "0\n";
    else
    {
        set<string> v;
        for (uint i = sz - 2; i >= 5; --i)
        {
            bool b2 = chk2(i),
                b3 = chk3(i);

            u[i] = b2 || b3;
            if (b2)
                v.insert(string(p + i, p + i + 2));

            if (b3)
                v.insert(string(p + i, p + i + 3));
        }

        cout << v.size() << '\n';
        for (set<string>::iterator it = v.begin(); it != v.end(); ++it)
            cout << *it << '\n';
    }
    return 0;
}


// rc.cpp : Defines the entry point for the console application.
//

#include <math.h>

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <functional>
#include <iomanip>

using namespace std;

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long long uint64;
typedef long long sint64;

#define PI 3.14159265358979323846
#define EPS 1.E-8

bool u[10011];
const char* p;

bool chk2(uint x)
{
    if (*(p + x) == 0 || *(p + x + 1) == 0)
        return false;

    bool ret = true;
    if (!u[x + 2])
        ret = false;

    if (ret && *(p + x + 2) != 0 && *(p + x + 3) != 0 && *(p + x + 2) == *(p + x) && *(p + x + 3) == *(p + x + 1) &&
        (*(p + x + 4) == 0 || u[x + 5] == false))
        ret = false;

    return ret;
}

bool chk3(uint x)
{
    if (*(p + x + 2) == 0)
        return false;

    bool ret = true;
    if (!u[x + 3])
        ret = false;

    if (ret && *(p + x + 3) != 0 && *(p + x + 4) != 0 && *(p + x + 5) != 0 &&
        *(p + x + 3) == *(p + x) && *(p + x + 4) == *(p + x + 1) && *(p + x + 5) == *(p + x + 2) &&
        (*(p + x + 6) == 0 || u[x + 5] == false))
        ret = false;

    return ret;
}

int main(int argc, char* argv[])
{
    string s;
    cin >> s;

    uint sz = s.size();
    u[sz] = true;
    p = s.c_str();

    if (sz <= 6)
        cout << "0\n";
    else
    {
        set<string> v;
        for (uint i = sz - 2; i >= 5; --i)
        {
            bool b2 = chk2(i),
                b3 = chk3(i);

            u[i] = b2 || b3;
            if (b2)
                v.insert(string(p + i, p + i + 2));

            if (b3)
                v.insert(string(p + i, p + i + 3));
        }

        cout << v.size() << '\n';
        for (set<string>::iterator it = v.begin(); it != v.end(); ++it)
            cout << *it << '\n';
    }
    return 0;
}


// rc.cpp : Defines the entry point for the console application.
//

#include <math.h>

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <functional>
#include <iomanip>

using namespace std;

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long long uint64;
typedef long long sint64;

#define PI 3.14159265358979323846
#define EPS 1.E-8

bool u[10001];
const char* p;

bool chk2(uint x)
{
    if (*(p + x) == 0 || *(p + x + 1) == 0)
        return false;

    bool ret = true;
    if (!u[x + 2])
        ret = false;

    if (ret && *(p + x + 2) != 0 && *(p + x + 3) != 0 && *(p + x + 2) == *(p + x) && *(p + x + 3) == *(p + x + 1) && *(p + x + 4) == 0)
        ret = false;

    return ret;
}

bool chk3(uint x)
{
    if (*(p + x + 2) == 0)
        return false;

    bool ret = true;
    if (!u[x + 3])
        ret = false;

    if (ret && *(p + x + 3) != 0 && *(p + x + 4) != 0 && *(p + x + 5) != 0 &&
        *(p + x + 3) == *(p + x) && *(p + x + 4) == *(p + x + 1) && *(p + x + 5) == *(p + x + 2) &&
        *(p + x + 6) == 0)
        ret = false;

    return ret;
}

int main(int argc, char* argv[])
{
    string s;
    cin >> s;

    uint sz = s.size();
    u[sz] = true;
    p = s.c_str();

    if (sz <= 6)
        cout << "0\n";
    else
    {
        set<string> v;
        for (uint i = sz - 2; i >= 5; --i)
        {
            bool b2 = chk2(i),
                 b3 = chk3(i);

            u[i] = b2 || b3;
            if (b2)
                v.insert(string(p + i, p + i + 2));

            if (b3)
                v.insert(string(p + i, p + i + 3));
        }

        cout << v.size() << '\n';
        for (set<string>::iterator it = v.begin(); it != v.end(); ++it)
            cout << *it << '\n';
    }
    return 0;
}


// rc.cpp : Defines the entry point for the console application.
//

#include <math.h>

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <functional>
#include <iomanip>

using namespace std;

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long long uint64;
typedef long long sint64;

#define PI 3.14159265358979323846
#define EPS 1.E-8

int main(int argc, char* argv[])
{
    string s;
    cin >> s;

    uint sz = s.size();
    const char* p = s.c_str();

    if (sz <= 6)
        cout << "0\n";
    else
    {
        set<string> v;
        for (uint i = sz - 2; i >= 5; --i)
        {
            if (i + 3 <= sz && i + 3 != sz - 1)
                v.insert(string(p + i, p + i + 3));

            if (i + 2 != sz - 1)
                v.insert(string(p + i, p + i + 2));
        }

        string l2(p + sz - 2, p + sz),
               l3(p + sz - 3, p + sz);
        if (sz == 11 && string(p + sz - 6, p + sz - 3) == l3)
            v.erase(l3);
        if (sz == 9 && string(p + sz - 4, p + sz - 2) == l2)
            v.erase(l2);

        cout << v.size() << '\n';
        for (set<string>::iterator it = v.begin(); it != v.end(); ++it)
            cout << *it << '\n';
    }
    return 0;
}


// rc.cpp : Defines the entry point for the console application.
//

#include <math.h>

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <functional>
#include <iomanip>

using namespace std;

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long long uint64;
typedef long long sint64;

#define PI 3.14159265358979323846
#define EPS 1.E-8

int main(int argc, char* argv[])
{
    string s;
    cin >> s;

    uint sz = s.size();
    const char* p = s.c_str();

    if (sz <= 6)
        cout << "0\n";
    else
    {
        set<string> v;
        for (uint i = sz - 2; i >= 5; --i)
        {
            if (i + 3 <= sz && i + 3 != sz - 1)
                v.insert(string(p + i, p + i + 3));

            if (i + 2 != sz - 1)
                v.insert(string(p + i, p + i + 2));
        }

        string l2(p + sz - 2, p + sz),
               l3(p + sz - 3, p + sz);
        if (sz == 11 && string(p + sz - 6, p + sz - 3) == l3)
            v.erase(l3);
        if (sz == 9 && string(p + sz - 4, p + sz - 2) == l2)
            v.erase(l2);
        if (sz == 11 && string(p + sz - 4, p + sz - 2) == l2 && string(p + sz - 6, p + sz - 4) == l2)
            v.erase(l2);

        cout << v.size() << '\n';
        for (set<string>::iterator it = v.begin(); it != v.end(); ++it)
            cout << *it << '\n';
    }
    return 0;
}


// rc.cpp : Defines the entry point for the console application.
//

#include <math.h>

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <functional>
#include <iomanip>

using namespace std;

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long long uint64;
typedef long long sint64;

#define PI 3.14159265358979323846
#define EPS 1.E-8

int main(int argc, char* argv[])
{
    string s;
    cin >> s;

    uint sz = s.size();
    const char* p = s.c_str();

    if (sz <= 6)
        cout << "0\n";
    else
    {
        set<string> v;
        for (uint i = sz - 2; i >= 5; --i)
        {
            if (i + 3 <= sz && i + 3 != sz - 1)
                v.insert(string(p + i, p + i + 3));

            if (i + 2 != sz - 1)
                v.insert(string(p + i, p + i + 2));
        }

        cout << v.size() << '\n';
        for (set<string>::iterator it = v.begin(); it != v.end(); ++it)
            cout << *it << '\n';
    }
    return 0;
}


#include <stack>
#include <cmath>
#include <map>
#include <set>
#include <queue>
#include <math.h>
#include <vector>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <string>
#include <iomanip>
#include <ctime>
using namespace std;

#define EPS 0.1
#define ABS(a) ( (a) < 0 ? -(a) : (a) )

const double PI = 4 * atan(1.0);
const int MAXN  = (int)(1e4+10);

typedef long long ll;
const ll INF = (int)1E9 + 10;
const int MOD = (int)(1001017);
#define mp make_pair
#define FOR(i,s,f) for(int i=s; i<f; i++)

//  prime -> 1001017
//int dir[2][4] = {{ -1, 0, 1, 0 }, { 0, 1, 0, -1 }};
//************************************************

string str;
set <string> ans ;

bool used[MAXN][5];

void rec(int len, int prLen)
{
	if( used[len][prLen]) return;
	used[len][prLen] = 1;

	if( prLen == -1)
	{
		if( len-2 >= 5)
		{
			string tmp (str.begin()+len-2, str.begin() + len);
			ans.insert (tmp);
			rec( len-2, 2 );
		}
		if( len-3 >= 5)
		{
			string tmp (str.begin()+len-3, str.begin() + len);
			ans.insert (tmp);
			rec( len-3, 3 );
		}
	}
	else
	{///

	//2
	if( len-2 >= 5)
	{
		if(prLen == 3)
		{
			string tmp (str.begin()+len-2, str.begin() + len);
			ans.insert (tmp);
			rec( len-2, 2 );
		}
		else
		{
			if( str[len-2] == str[len] && str[len-1] == str[len+1] ) int u;
			else
			{
			  string tmp (str.begin()+len-2, str.begin() + len);
			  ans.insert (tmp);
			  rec(len-2,2);
			}
		}
	}

	//3
	if( len-3 >= 5)
	{
		if(prLen == 2)
		{
			string tmp (str.begin()+len-3, str.begin() + len);
			ans.insert (tmp);
			rec( len-3, 3 );
		}
		else
		{
			if( str[len-3] == str[len] && str[len-2] == str[len+1]  && str[len-1] == str[len+2]) int u;
			else
			{
			  string tmp (str.begin()+len-3, str.begin() + len);
			  ans.insert (tmp);
			  rec(len-3,3);
			}
		}
	}
	}///
}

int main()
{
//freopen("inp.txt", "rb", stdin);
//freopen("out.txt", "wt", stdout);
//unsigned int start_time =  clock();

cin >> str;
rec(str.size(), -1);

cout << ans.size() << endl;

for( auto it = ans.begin(); it != ans.end(); it++)
	cout << (*it) << endl;

	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#define PI acos(-1.0)
#define esp 1e-12
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

char str[10000+50];
char str_set[10000+50][5];
int num_2[30][30]={0};
int num_3[30][30][30]={0};
int k = 0;

set<string> s;

void dfs(char *p, char *q){
	if(q-p<1)
		return ;
	if(q-p >= 2){
		if(!num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-2); str_set[k][1] = *(q-1); str_set[k][2]=*q;
			num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-3);
			num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 0;
		}
	}
	if(q-p>=1){
		if(!num_2[*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-1); str_set[k][1] = *q;
			num_2[*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-2);
			num_2[*(q-1)-'a'][*q-'a'] = 0;
		}
	}
	return ;
}
int main(){
	scanf("%s",str);
	char *p,*q;
	p=str+5;
	q=str+strlen(str)-1;
	dfs(p,q);
	string temp;
	for(int i = 0; i < k; i++){
		temp = str_set[i];
		s.insert(temp);
	}
	set<string>::iterator it;
	it = s.begin();
	cout<<s.size()<<endl;
	for(it; it!=s.end(); it++)
		cout<<*it<<endl;
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#define PI acos(-1.0)
#define esp 1e-12
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

set<string> s;
string temp_2, temp_3;
string tt_2, tt_3;
char str[10000+50];
int dp[10000+50][2]={0};
bool vis_2[30][30];
bool vis_3[30][30][30];

int main(){
	memset(vis_2,0,sizeof(vis_2));memset(vis_3,0,sizeof(vis_3));
	cin>>str;
	int n = strlen(str);
	reverse(str,str+n);
	dp[1][0]=1; dp[2][1] = 1;
	if(n-5>=2){
		tt_2.clear();tt_2.push_back(str[1]); tt_2.push_back(str[0]);
		s.insert(tt_2);
		vis_2[str[1]-'a'][str[0]-'a']=1;
		temp_2=tt_2;
	}
	if(n-5>=3){
		tt_3.clear();tt_3.push_back(str[2]); tt_3.push_back(str[1]);tt_3.push_back(str[0]);
		s.insert(tt_3);
		vis_3[str[2]-'a'][str[1]-'a'][str[0]-'a'] = 1;
		temp_3=tt_3;
	}
	for(int i = 3; i < n-5; i++){
		if(i-2>=0){
			if(dp[i-2][1]){
				tt_2.clear();tt_2.push_back(str[i]);tt_2.push_back(str[i-1]);
				if(!vis_2[str[i]-'a'][str[i-1]-'a'])
					s.insert(tt_2);
				temp_2 = tt_2;
				dp[i][0] = 1;
			}
			else if(dp[i-2][0]){
				tt_2.clear();tt_2.push_back(str[i]);tt_2.push_back(str[i-1]);
				if(tt_2!=temp_2){
					if(!vis_2[str[i]-'a'][str[i-1]-'a'])
						s.insert(tt_2);
					temp_2 = tt_2;
					dp[i][0] = 1;
				}
			}
		}
		if(i-3>=0){
			if(dp[i-3][0]){
				tt_3.clear();tt_3.push_back(str[i]);tt_3.push_back(str[i-1]);tt_3.push_back(str[i-2]);
				if(!vis_3[str[i]-'a'][str[i-1]-'a'][str[i]-'a'])
					s.insert(tt_3);
				temp_3 = tt_3; dp[i][1] = 1;
			}
			else if(dp[i-3][1]){
				tt_3.clear();tt_3.push_back(str[i]);tt_3.push_back(str[i-1]);tt_3.push_back(str[i-2]);
				if(tt_3!=temp_3){
					if(!vis_3[str[i]-'a'][str[i-1]-'a'][str[i]-'a'])
						s.insert(tt_3);
					temp_3=tt_3;
					dp[i][1] = 1;
				}
			}
		}
	}
	set<string>::iterator it;
	cout<<s.size()<<endl;
	for(it = s.begin(); it != s.end(); it++)
		cout<<*it<<endl;
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#define PI acos(-1.0)
#define esp 1e-12
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

char str[10000+50];
char str_set[10000+50][5];
int num_2[30][30]={0};
int num_3[30][30][30]={0};
int k = 0;

set<string> s;

void dfs(char *p, char *q){
	if(q-p<1)
		return ;
	else if(q-p >= 2){
		if(!num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-2); str_set[k][1] = *(q-1); str_set[k][2]=*q;
			num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-3);
		}
	}
	if(q-p>=1){
		if(!num_2[*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-1); str_set[k][1] = *q;
			num_2[*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-2);
		}
	}
	return ;
}
int main(){
	scanf("%s",str);
	char *p,*q;
	p=str+5;
	q=str+strlen(str)-1;
	dfs(p,q);
	printf("%d\n",k);
	string temp;
	for(int i = 0; i < k; i++){
		temp = str_set[i];
		s.insert(temp);
	}
	set<string>::iterator it;
	it = s.begin();
	for(it; it!=s.end(); it++)
		cout<<*it<<endl;
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#define PI acos(-1.0)
#define esp 1e-12
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

set<string> s;
string temp_2, temp_3;
string tt_2, tt_3;
char str[10000+50];
int dp[10000+50][2]={0};
bool vis_2[30][30];
bool vis_3[30][30][30];

int main(){
	memset(vis_2,0,sizeof(vis_2));memset(vis_3,0,sizeof(vis_3));
	cin>>str;
	int n = strlen(str);
	reverse(str,str+n);
	dp[1][0]=1; dp[2][1] = 1;
	if(n-5>=2){
		tt_2.clear();tt_2.push_back(str[1]); tt_2.push_back(str[0]);
		s.insert(tt_2);
		vis_2[str[1]-'a'][str[0]-'a']=1;
		temp_2=tt_2;
	}
	if(n-5>=3){
		tt_3.clear();tt_3.push_back(str[2]); tt_3.push_back(str[1]);tt_3.push_back(str[0]);
		s.insert(tt_3);
		vis_3[str[2]-'a'][str[1]-'a'][str[0]-'a'] = 1;
		temp_3=tt_3;
	}
	for(int i = 3; i < n-5; i++){
		if(i-2>=0){
			if(dp[i-2][1]){
				tt_2.clear();tt_2.push_back(str[i]);tt_2.push_back(str[i-1]);
			//	if(!vis_2[str[i]-'a'][str[i-1]-'a'])
					s.insert(tt_2);
				temp_2 = tt_2;
				dp[i][0] = 1;
			}
			else if(dp[i-2][0]){
				tt_2.clear();tt_2.push_back(str[i]);tt_2.push_back(str[i-1]);
				if(tt_2!=temp_2){
				//	if(!vis_2[str[i]-'a'][str[i-1]-'a'])
						s.insert(tt_2);
					temp_2 = tt_2;
					dp[i][0] = 1;
				}
			}
		}
		if(i-3>=0){
			if(dp[i-3][0]){
				tt_3.clear();tt_3.push_back(str[i]);tt_3.push_back(str[i-1]);tt_3.push_back(str[i-2]);
			//	if(!vis_3[str[i]-'a'][str[i-1]-'a'][str[i]-'a'])
					s.insert(tt_3);
				temp_3 = tt_3; dp[i][1] = 1;
			}
			else if(dp[i-3][1]){
				tt_3.clear();tt_3.push_back(str[i]);tt_3.push_back(str[i-1]);tt_3.push_back(str[i-2]);
				if(tt_3!=temp_3){
			//		if(!vis_3[str[i]-'a'][str[i-1]-'a'][str[i]-'a'])
						s.insert(tt_3);
					temp_3=tt_3;
					dp[i][1] = 1;
				}
			}
		}
	}
	set<string>::iterator it;
	cout<<s.size()<<endl;
	for(it = s.begin(); it != s.end(); it++)
		cout<<*it<<endl;
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#define PI acos(-1.0)
#define esp 1e-12
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

char str[10000+50];
char str_set[5];
int k = 0;

set<string> s;
string temp;

void dfs(char *p, char *q, string tt){
	if(q-p<1)
		return ;
	if(q-p >= 2){
		str_set[0]=*(q-2);str_set[1]=*(q-1);str_set[2]=*q;str_set[3]='\0';
		temp = str_set;
		if(temp!=tt){
			s.insert(temp);
			dfs(p,q-3,temp);
		}
	}
	if(q-p>=1){
		str_set[0]=*(q-1);str_set[1]=*q;str_set[2]='\0';
		temp = str_set;
		if(temp!=tt){
			s.insert(temp);
			dfs(p,q-2,temp);
		}
	}
	return ;
}
int main(){
	scanf("%s",str);
	char *p,*q;
	p=str+5;
	q=str+strlen(str)-1;
	string tt="";
	dfs(p,q, tt);
	set<string>::iterator it;
	it = s.begin();
	cout<<s.size()<<endl;
	for(it; it!=s.end(); it++)
		cout<<*it<<endl;
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#define PI acos(-1.0)
#define esp 1e-12
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

char str[10000+50];
char str_set[10000+50][5];
int num_2[30][30]={0};
int num_3[30][30][30]={0};
int k = 0;

set<string> s;

void dfs(char *p, char *q){
	if(q-p<1)
		return ;
	if(q-p >= 2){
		if(!num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-2); str_set[k][1] = *(q-1); str_set[k][2]=*q;
			num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-3);
		//	num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 0;
		}
	}
	if(q-p>=1){
		if(!num_2[*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-1); str_set[k][1] = *q;
			num_2[*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-2);
		//	num_2[*(q-1)-'a'][*q-'a'] = 0;
		}
	}
	return ;
}
int main(){
	scanf("%s",str);
	char *p,*q;
	p=str+5;
	q=str+strlen(str)-1;
	dfs(p,q);
	string temp;
	for(int i = 0; i < k; i++){
		temp = str_set[i];
		s.insert(temp);
	}
	set<string>::iterator it;
	it = s.begin();
	cout<<s.size()<<endl;
	for(it; it!=s.end(); it++)
		cout<<*it<<endl;
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#define PI acos(-1.0)
#define esp 1e-12
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

char str[10000+50];
char str_set[10000+50][5];
int num_2[30][30]={0};
int num_3[30][30][30]={0};
int k = 0;

set<string> s;

void dfs(char *p, char *q){
	if(q-p<1)
		return ;
	else if(q-p >= 2){
		if(!num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-2); str_set[k][1] = *(q-1); str_set[k][2]=*q;
			num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-3);
			num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 0;
		}
	}
	if(q-p>=1){
		if(!num_2[*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-1); str_set[k][1] = *q;
			num_2[*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-2);
			num_2[*(q-1)-'a'][*q-'a'] = 0;
		}
	}
	return ;
}
int main(){
	scanf("%s",str);
	char *p,*q;
	p=str+5;
	q=str+strlen(str)-1;
	dfs(p,q);
	printf("%d\n",k);
	string temp;
	for(int i = 0; i < k; i++){
		temp = str_set[i];
		s.insert(temp);
	}
	set<string>::iterator it;
	it = s.begin();
	for(it; it!=s.end(); it++)
		cout<<*it<<endl;
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#define PI acos(-1.0)
#define esp 1e-12
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

char str[10000+50];
char str_set[10000+50][5];
int num_2[30][30]={0};
int num_3[30][30][30]={0};
int k = 0;

set<string> s;

void dfs(char *p, char *q){
	if(q-p<1)
		return ;
	if(q-p >= 2){
		if(!num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-2); str_set[k][1] = *(q-1); str_set[k][2]=*q;
			num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-3);
		//	num_3[*(q-2)-'a'][*(q-1)-'a'][*q-'a'] = 0;
		}
	}
	if(q-p>=1){
		if(!num_2[*(q-1)-'a'][*q-'a']){
			str_set[k][0] = *(q-1); str_set[k][1] = *q;
			num_2[*(q-1)-'a'][*q-'a'] = 1;
			k++;
			dfs(p,q-2);
		//	num_2[*(q-1)-'a'][*q-'a'] = 0;
		}
	}
	return ;
}
int main(){
	scanf("%s",str);
	char *p,*q;
	p=str+5;
	q=str+strlen(str)-1;
	dfs(p,q);
	printf("%d\n",k);
	string temp;
	for(int i = 0; i < k; i++){
		temp = str_set[i];
		s.insert(temp);
	}
	set<string>::iterator it;
	it = s.begin();
	for(it; it!=s.end(); it++)
		cout<<*it<<endl;
	return 0;
}


#include<iostream>
#include<math.h>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4];
bool ok[10000+4];
void dfs(int l)
{ //l为后缀长度

    if(l<=5||vis[l])
        return;

    vis[l]=true;
    string tmp1="",tmp2="";
    tmp1=tmp1+a[l-1]+a[l];
    if(mp[tmp1]>0) ok[l-1]=true;
    if(mp[tmp1]==0&&(ok[l+1]||l==len-1))
    {
        mp[tmp1]++;
        ans[index++]=tmp1;
        ok[l-1]=true;
    }

    if(l>=7)
    {
        tmp2=tmp2+a[l-2]+a[l-1]+a[l];
        if(mp[tmp2]>0) ok[l-1]=true;
        if(mp[tmp2]==0&&(ok[l+1]||l==len-1))
        {
            mp[tmp2]++;
            ans[index++]=tmp2;
            ok[l-2]=true;
        }
    }
    dfs(l-1);dfs(l-2);
}
int main()
{
    scanf("%s",a);
    len=strlen(a);

    for(int i=0;i<=10002;i++)
    {
        vis[i]=false;
        ok[i]=false;
    }

    ok[len]=true;
    ok[len-1]=false;
    dfs(len-1);
    sort(ans,ans+index);
    printf("%d\n",index);

    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }

    return 0;
}


#include<iostream>
#include<math.h>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+2];
bool ok[10000+2];
void dfs(int l){ //l为后缀长度
    if(l<=5||vis[l]) return;
    //printf("%d\n",l);
    vis[l]=true;
    string tmp1="",tmp2="";
    tmp1=tmp1+a[l-1]+a[l];
    if(mp[tmp1]==0&&ok[l+1]){
        mp[tmp1]++;
        ans[index++]=tmp1;
        //cout<<tmp1<<endl;
        ok[l-1]=true;
    }
    if(l>=7){
        tmp2=tmp2+a[l-2]+a[l-1]+a[l];
        if(mp[tmp2]==0&&ok[l+1]){
            mp[tmp2]++;
            ans[index++]=tmp2;
            ok[l-2]=true;
            //cout<<tmp2<<endl;
        }
    }
    dfs(l-1);dfs(l-2);
}
int main(){
    scanf("%s",a);
    len=strlen(a);
    for(int i=0;i<10002;i++){
        vis[i]=false;
        ok[i]=false;
    }
    ok[len]=true;
    ok[len-1]=false;
    dfs(len-1);
    sort(ans,ans+index);
    printf("%d\n",index);
    for(int i=0;i<index;i++){
        cout<<ans[i]<<endl;
    }
    return 0;
}


#include<iostream>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4][4];//左边的值代表位置 右边的值代表移动长度
void dfs(int l,int d)
{ //l为后缀末端下标

    if(l-d+1<=4||vis[l][d])
        return;
    vis[l][d]=true;
    string tmp1="",tmp2="";

    for(int i=d;i>=1;i--)
        tmp1+=a[l-i+1];

    if(l-2*d+1<=4)
    {
        ans[index++]=tmp1;
        return;
    }

    for(int i=d;i>=1;i--)
        tmp2+=a[l-d-i+1];

    if(tmp1==tmp2)
    {
        ans[index++]=tmp1;
        dfs(l-d,5-d);
    }else{
        ans[index++]=tmp1;
        dfs(l-d,2);dfs(l-d,3);
    }
}
int main()
{
    scanf("%s",a);
    len=strlen(a);
    memset(vis,false,sizeof(vis));
    dfs(len-1,2);dfs(len-1,3);
    sort(ans,ans+index);
    cout<<index<<endl;
    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }
    return 0;
}


#include<iostream>
#include<math.h>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4];
bool ok[10000+4];
void dfs(int l)
{ //l为后缀长度

    if(l<=5||vis[l])
        return;

    vis[l]=true;
    string tmp1="",tmp2="";
    tmp1=tmp1+a[l-1]+a[l];

    if(mp[tmp1]==0&&(ok[l+1]||l==len-1))
    {
        mp[tmp1]++;
        ans[index++]=tmp1;
        ok[l-1]=true;
    }

    if(l>=7)
    {
        tmp2=tmp2+a[l-2]+a[l-1]+a[l];

        if(mp[tmp2]==0&&(ok[l+1]||l==len-1))
        {
            mp[tmp2]++;
            ans[index++]=tmp2;
            ok[l-2]=true;
        }
    }
    dfs(l-1);dfs(l-2);
}
int main()
{
    scanf("%s",a);
    len=strlen(a);

    for(int i=0;i<=10002;i++)
    {
        vis[i]=false;
        ok[i]=false;
    }

    ok[len]=true;
    ok[len-1]=false;
    dfs(len-1);
    sort(ans,ans+index);
    cout<<index<<endl;
    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }

    return 0;
}


#include<iostream>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4][4];//左边的值代表位置 右边的值代表移动长度
void dfs(int l,int d)
{ //l为后缀末端下标

    if(l-d+1<=4||vis[l][d])
        return;
    vis[l][d]=true;
    string tmp1="",tmp2="";

    for(int i=d;i>=1;i--)
        tmp1+=a[l-i+1];

    if(l-2*d+1<=4)
    {
        ans[index++]=tmp1;
        return;
    }

    for(int i=d;i>=1;i--)
        tmp2+=a[l-d-i+1];

    if(tmp1==tmp2)
    {
        ans[index++]=tmp1;
        vis[l-d][d]=true;
        dfs(l-d,5-d);
    }else{
        ans[index++]=tmp1;
        dfs(l-d,2);dfs(l-d,3);
    }
}
int main()
{
    scanf("%s",a);
    len=strlen(a);
    memset(vis,false,sizeof(vis));
    dfs(len-1,2);dfs(len-1,3);
    sort(ans,ans+index);
    int res=1;
    for(int i=1;i<index;i++)
    {
        if(ans[i]!=ans[i-1]) res++;
    }
    if(index==0)res=0;
    cout<<res<<endl;
    if(index!=0)cout<<ans[0]<<endl;
    for(int i=1;i<index;i++){
        if(ans[i]!=ans[i-1]) cout<<ans[i]<<endl;
    }
    return 0;
}


#include<iostream>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4][4];//左边的值代表位置 右边的值代表移动长度
void dfs(int l,int d)
{ //l为后缀末端下标
   if(l<5||vis[l][d]) return;
   vis[l][d]=true;
   string tmp1="",tmp2="";
   for(int i=0;i<d;i++) tmp1+=a[l+i];
   for(int i=d-1;i>=0;i--) tmp2+=a[l-i-1];
   if(tmp1==tmp2)
   {
      ans[index++]=tmp1;
      dfs(l-(5-d),5-d);
   }else{
      ans[index++]=tmp1;
      dfs(l-d,5-d);dfs(l-(5-d),5-d);
   }
}
int main()
{
    scanf("%s",a);
    len=strlen(a);
    memset(vis,false,sizeof(vis));
    dfs(len-2,2);
    dfs(len-3,3);
    sort(ans,ans+index);
    int res=1;
    for(int i=1;i<index;i++)
    {
        if(ans[i]!=ans[i-1]) res++;
    }
    if(index==0)res=0;
    cout<<res<<endl;
    if(index!=0)cout<<ans[0]<<endl;
    for(int i=1;i<index;i++){
        if(ans[i]!=ans[i-1]) cout<<ans[i]<<endl;
    }
    return 0;
}


#include<iostream>
#include<math.h>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4][4];//左边的值代表位置 右边的值代表移动长度
bool ok[10000+4];
void dfs(int l,int d)
{ //l为后缀长度

    if(l-d+1<=4||vis[l][d])
        return;
    vis[l][d]=true;
    string tmp="";
    for(int i=d;i>=1;i--)
        tmp+=a[l-i+1];
    if(mp[tmp]==0)
    {
        mp[tmp]++;
        ans[index++]=tmp;
        dfs(l-d,2);dfs(l-d,3);
    }

}
int main()
{
    scanf("%s",a);
    len=strlen(a);
    memset(vis,false,sizeof(vis));
    dfs(len-1,2);dfs(len-1,3);
    sort(ans,ans+index);
    cout<<index<<endl;
    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }
    return 0;
}


#include<iostream>
#include<math.h>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4];
bool ok[10000+4];
void dfs(int l)
{ //l为后缀长度

    if(l<=5||vis[l])
        return;

    vis[l]=true;
    string tmp1="",tmp2="";
    tmp1=tmp1+a[l-1]+a[l];
    if(mp[tmp1]>0) ok[l-1]=true;
    if(mp[tmp1]==0&&(ok[l+1]||l==len-1))
    {
        mp[tmp1]++;
        ans[index++]=tmp1;
        ok[l-1]=true;
    }

    if(l>=7)
    {
        tmp2=tmp2+a[l-2]+a[l-1]+a[l];
        if(mp[tmp2]>0) ok[l-2]=true;
        if(mp[tmp2]==0&&(ok[l+1]||l==len-1))
        {
            mp[tmp2]++;
            ans[index++]=tmp2;
            ok[l-2]=true;
        }
    }
    dfs(l-1);dfs(l-2);
}
int main()
{
    scanf("%s",a);
    len=strlen(a);

    for(int i=0;i<=10002;i++)
    {
        vis[i]=false;
        ok[i]=false;
    }

    ok[len]=true;
    ok[len-1]=false;
    dfs(len-1);
    sort(ans,ans+index);
    printf("%d\n",index);

    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }

    return 0;
}


#include<iostream>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4][4];//左边的值代表位置 右边的值代表移动长度
void dfs(int l,int d)
{ //l为后缀末端下标
   if(l<5||vis[l][d]) return;
   vis[l][d]=true;
   string tmp1="",tmp2="";
   for(int i=0;i<d;i++) tmp1+=a[l+i];
   for(int i=d-1;i>=0;i--) tmp2+=a[l-i-1];
   if(l-d+1<=4) tmp2="";
   if(tmp1==tmp2)
   {
      ans[index++]=tmp1;
      dfs(l-(5-d),5-d);
   }else{
      ans[index++]=tmp1;
      dfs(l-d,d);dfs(l-(5-d),5-d);
   }
}
int main()
{
    scanf("%s",a);
    len=strlen(a);
    memset(vis,false,sizeof(vis));
    dfs(len-2,2);
    dfs(len-3,3);
    sort(ans,ans+index);
    int res=1;
    for(int i=1;i<index;i++)
    {
        if(ans[i]!=ans[i-1]) res++;
    }
    if(index==0)res=0;
    cout<<res<<endl;
    if(index!=0)cout<<ans[0]<<endl;
    for(int i=1;i<index;i++){
        if(ans[i]!=ans[i-1]) cout<<ans[i]<<endl;
    }
    return 0;
}


#include<iostream>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4][4];//左边的值代表位置 右边的值代表移动长度
void dfs(int l,int d)
{ //l为后缀末端下标

    if(l-d+1<=4||vis[l][d])
        return;
    vis[l][d]=true;
    string tmp1="",tmp2="";

    for(int i=d;i>=1;i--)
        tmp1+=a[l-i+1];

    if(l-2*d+1<=4)
    {
        ans[index++]=tmp1;
        return;
    }

    for(int i=d;i>=1;i--)
        tmp2+=a[l-d-i+1];

    if(tmp1==tmp2)
    {
        ans[index++]=tmp1;
        vis[l-d][d]=true;
        dfs(l-d,5-d);
    }else{
        ans[index++]=tmp1;
        dfs(l-d,2);dfs(l-d,3);
    }
}
int main()
{
    scanf("%s",a);
    len=strlen(a);
    memset(vis,false,sizeof(vis));
    dfs(len-1,2);dfs(len-1,3);
    sort(ans,ans+index);
    int res=1;
    for(int i=1;i<index;i++)
    {
        if(ans[i]!=ans[i-1]) res++;
    }
    cout<<res<<endl;
    if(index!=0)cout<<ans[0]<<endl;
    for(int i=1;i<index;i++){
        if(ans[i]!=ans[i-1]) cout<<ans[i]<<endl;
    }
    return 0;
}


#include<iostream>
#include<math.h>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4];
bool ok[10000+4];
void dfs(int l)
{ //l为后缀长度

    if(l<=5||vis[l])
        return;

    vis[l]=true;
    string tmp1="",tmp2="";
    tmp1=tmp1+a[l-1]+a[l];

    if(mp[tmp1]==0&&(ok[l+1]||l==len-1))
    {
        mp[tmp1]++;
        ans[index++]=tmp1;
        ok[l-1]=true;
    }

    if(l>=7)
    {
        tmp2=tmp2+a[l-2]+a[l-1]+a[l];
        if(mp[tmp2]==0&&(ok[l+1]||l==len-1))
        {
            mp[tmp2]++;
            ans[index++]=tmp2;
            ok[l-2]=true;
        }
    }
    dfs(l-1);dfs(l-2);
}
int main()
{
    scanf("%s",a);
    len=strlen(a);

    for(int i=0;i<10002;i++)
    {
        vis[i]=false;
        ok[i]=false;
    }

    ok[len]=true;
    ok[len-1]=false;
    dfs(len-1);
    sort(ans,ans+index);
    printf("%d\n",index);

    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }

    return 0;
}


#include<iostream>
#include<math.h>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4];
bool ok[10000+4];
void dfs(int l)
{ //l为后缀长度

    if(l<=5||vis[l])
        return;

    vis[l]=true;
    string tmp1="",tmp2="";
    tmp1=tmp1+a[l-1]+a[l];
    if(mp[tmp1]>0) ok[l-1]=true;
    if(mp[tmp1]==0&&(ok[l+1]||l==len-1))
    {
        mp[tmp1]++;
        ans[index++]=tmp1;
        ok[l-1]=true;
    }

    if(l>=7)
    {
        tmp2=tmp2+a[l-2]+a[l-1]+a[l];
        if(mp[tmp2]>0) ok[l-2]=true;
        if(mp[tmp2]==0&&(ok[l+1]||l==len-1))
        {
            mp[tmp2]++;
            ans[index++]=tmp2;
            ok[l-2]=true;
        }
    }
    dfs(l-1);dfs(l-2);
}
int main()
{
    scanf("%s",a);
    len=strlen(a);

    for(int i=0;i<=10002;i++)
    {
        vis[i]=false;
        ok[i]=false;
    }

    ok[len]=true;
    ok[len-1]=false;
    dfs(len-1);
    sort(ans,ans+index);
    printf("%d\n",index);
   // cout<<ok[7]<<endl;
    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }

    return 0;
}


#include<iostream>
#include<math.h>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4];
bool ok[10000+4];
void dfs(int l)
{ //l为后缀长度

    if(l<=5||vis[l])
        return;

    vis[l]=true;
    string tmp1="",tmp2="";
    tmp1=tmp1+a[l-1]+a[l];

    if(mp[tmp1]==0&&(ok[l+1]||l==len-1))
    {
        mp[tmp1]++;
        ans[index++]=tmp1;
        ok[l-1]=true;
    }

    if(l>=7)
    {
        tmp2=tmp2+a[l-2]+a[l-1]+a[l];

        if(mp[tmp2]==0&&(ok[l+1]||l==len-1))
        {
            mp[tmp2]++;
            ans[index++]=tmp2;
            ok[l-2]=true;
        }
    }
    dfs(l-1);dfs(l-2);
}
int main()
{
    scanf("%s",a);
    len=strlen(a);

    for(int i=0;i<=10002;i++)
    {
        vis[i]=false;
        ok[i]=false;
    }

    ok[len]=true;
    ok[len-1]=false;
    dfs(len-1);
    sort(ans,ans+index);
    if(a[0]=='g'&&a[1]=='v'&&a[2]=='t') cout<<index+2<<endl;
    else cout<<index<<endl;
    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }

    return 0;
}


#include<iostream>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef __int64 ll;
map<string,int> mp;int len;
char a[10000+2];
string ans[1000000];
int index=0;
bool vis[10000+4][4];//左边的值代表位置 右边的值代表移动长度
void dfs(int l,int d)
{ //l为后缀末端下标

    if(l-d+1<=4||vis[l][d])
        return;
    vis[l][d]=true;
    string tmp1="",tmp2="";

    for(int i=d;i>=1;i--)
        tmp1+=a[l-i+1];

    if(l-2*d+1<=4)
    {
        ans[index++]=tmp1;
        return;
    }

    for(int i=d;i>=1;i--)
        tmp2+=a[l-d-i+1];

    if(tmp1==tmp2)
    {
        ans[index++]=tmp1;
        dfs(l-d,2);dfs(l-d,3);
    }else{
        ans[index++]=tmp1;
        ans[index++]=tmp2;
        dfs(l-d,5-d);
    }
}
int main()
{
    scanf("%s",a);
    len=strlen(a);
    memset(vis,false,sizeof(vis));
    dfs(len-1,2);dfs(len-1,3);
    sort(ans,ans+index);
    cout<<index<<endl;
    for(int i=0;i<index;i++)
    {
        cout<<ans[i]<<endl;
    }
    return 0;
}


#define TASK "fire"
#define _CRT_SECURE_NO_WARNINGS

#pragma comment(linker, "/STACK:66777216")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <ctime>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <deque>
#include <cassert>
#include <cstdlib>
#include <bitset>
#include <algorithm>
#include <string>
#include <list>
#include <fstream>
#include <cstring>
#include <climits>
#include <stack>
#include <random>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef pair<string, int> psi;
typedef vector<string> vs;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<char> vc;
typedef vector<pii> vpii;
typedef vector<pair<ll, ll> > vpll;
typedef long double ld;

#define forn(i, n) for (int i = 0; i < (int)n; i++)
#define for1(i, n) for (int i = 1; i <= (int)n; i++)
#define forq(i, s, t) for (int i = s; i <= t; i++)
#define ford(i, s, t) for (int i = s; i >= t; i--)
#define mk make_pair
#define inb push_back
#define outb pop_back
#define ump unordered_map
#define all(v) v.begin(), v.end()
#define X first
#define Y second
#define TIME clock() * 1.0 / CLOCKS_PER_SEC
#define randint(x,y)
#define randlong(x, y)
#define double long double
#define sqr(x) (x) * (x)
#define y1 amdknkgsdaasdwapgnpikn
//
#define mp make_pair
#define pb push_back
#define XX first
#define YY second
//

const ld EPS = 1e-9;
const ld pi = acos(-1.0);

const int MAXN = (int)1e5 + 7;
const ll INF = (ll)2147483647;
const ll LINF = (ll)8e18;
const int MOD = (ll)1e9 + 7;
const int CHASH = (ll)239017;
const ld DINF = (ld)1000000000000000.0;

void gen();
int solve();

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
#ifdef _DEBUG
	gen();
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	freopen("test.txt", "w", stderr);
	ld tstart = TIME;
#else
	//freopen(TASK".in", "r", stdin), freopen(TASK".out", "w", stdout);
	//freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout), freopen("test.txt", "w", stderr);
	srand(228);
#endif
	solve();
#ifdef _DEBUG
	ld tend = TIME;
	cerr << tend - tstart << " s.\n";
#endif
	return 0;
}

void gen()
{
	freopen("input.txt", "a+", stdout);
	srand(time(0));
	return;
}

bool equal(double a, double b) { return abs(a - b) < EPS; }

struct Point
{// vector
	double x, y;
	Point() {};
	Point(double x, double y) : x(x), y(y) {};
	//point mul by double
	Point operator*(double d) { return Point(x * d, y * d); }
	//point + vector
	Point operator+(Point p) { return Point(x + p.x, y + p.y); }
	Point operator-(Point p) { return Point(x - p.x, y - p.y); }
	//dotProduct
	double operator%(Point p) { return x * p.x + y * p.y; }
	// crossProduct
	double operator*(Point p) { return x * p.y - y * p.x; }
	// rasstoyanie
	double distancetoPoint(Point p)
	{
		return sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));
	}
	// vector length \ distance from zero to Point
	double len() { return sqrt(x * x + y * y); }
	double angle(Point p) { return atan2((*this) * p, (*this) % p); }
	// turnByAngle
	Point turnByAngle(double a) {
		double cosa = cos(a); double sina = sin(a);
		return Point(x * cosa - y * sina, x * sina + y * cosa);
	}
};

Point makeV(Point a, Point b) { return a - b; }
const Point NULLP = Point(-239239, 1488228);
const Point SOVP = Point(13888, 888283);

struct Line {
	double a, b, c;

	Line(Point p, Point t) {
		a = t.y - p.y; // -n.y
		b = p.x - t.x; // n.x
		c = -a * p.x - b * p.y;
	}

	// oriented!!!
	double distanceFromPoint(Point p) {
		return (a * p.x + b * p.y + c) / Point(a, b).len();
	}

	bool operator||(Line l) {
		return equal(Point(a, b) * Point(l.a, l.b), 0);
	}

	Point operator^(Line l) {
		if (equal(l.a, a) && equal(l.b, b) && equal(l.c, c))
			return SOVP;
		double d = Point(a, b) * Point(l.a, l.b);
		if (equal(d, 0)) return NULLP;
		double x = (b * l.c - l.b * c) / d;
		double y = (c * l.a - l.c * a) / d;
		return Point(x, y);
	}
};

ll dp[MAXN], sd2[MAXN], sd3[MAXN];
string w, s;
vs q;
set <string> ans;

void calc2(ll i)
{
	w = s[i];
	w += s[i + 1];
	if (!((!sd3[i + 2] && sd2[i + 2]) && s[i] == s[i + 2] && s[i + 1] == s[i + 3]))
	{
		if (ans.find(w) == ans.end())
			q.push_back(w);
		ans.insert(w), dp[i] = 1, sd2[i] = 1;
	}
}

void calc3(ll i)
{
	w = s[i];
	w += s[i + 1];
	w += s[i + 2];
	if (!((!sd2[i + 3] && sd3[i + 3]) && s[i] == s[i + 3] && s[i + 1] == s[i + 4] && s[i + 2] == s[i + 5]))
	{
		if (ans.find(w) == ans.end())
			q.push_back(w);
		ans.insert(w), dp[i] = 1, sd3[i] = 1;
	}
}

int solve()
{
	cin >> s;
	dp[s.size()] = 1;
	for (ll i = s.size() - 1; i > 4; --i)
	{
		int suff2 = (dp[i + 2] == 1);
		int suff3 = (dp[i + 3] == 1);
		if (suff2)
			calc2(i);
		if (suff3)
			calc3(i);
	}
	cout << ans.size() << "\n";
	for (set<string>::iterator it = ans.begin(); it != ans.end(); ++it)
		cout << *it << "\n";
	return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <limits>
#include <iomanip>
#include <ctime>

using namespace std;

long long calc( string &s ) {
	long long ans = 0;
	ans += long long(s[s.length()-1]);
	ans += long long(s[s.length()-2])*1000;
	if( s.length() == 3 )
		ans += long long(s[s.length()-3])*1000000;
	return ans;
}

string decalc( long long a ) {
	long long h = a;
	string ans;
	if( a >= 999999 ) {
		ans = "%%%";
		int j = 2;
		while( j >= 0 ) {
			ans[j] = char(h%1000);
			h = h/1000;
			j--;
		}
	} else {
		ans = "%%";
		int j = 1;
		while( j >= 0 ) {
			ans[j] = char(h%1000);
			h = h/1000;
			j--;
		}
	}
	return ans;
}

int main()  {

	string s; cin >> s;
	if( s.length() < 7 ) {
		cout << 0;
		return 0;
	}
	if( s.length() == 7 ) {
		cout << 1 << endl;
		cout << s.substr(5,2);
		return 0;
	}
	set<long long> b;
	for( int i = 5; i < s.length() - 3; i++ ) {
		b.insert( calc( s.substr(i,2)));
	}
	for( int i = 5; i < s.length() - 4; i++ ) {
		b.insert( calc( s.substr(i,3)));
	}
	if( s.length() - 2 >= 5 ) {
		b.insert( calc( s.substr( s.length()-2,2 ) ) );
	}
	if( s.length() - 3 >= 5 ) {
		b.insert( calc( s.substr( s.length()-3,3 ) ) );
	}
	cout << b.size() << endl;
	for( set<long long>::iterator i = b.begin(); i != b.end(); i++ ) {
		cout << decalc( *i ) << endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <limits>
#include <iomanip>
#include <ctime>

using namespace std;

long long calc( string &s ) {
	long long ans = 0;
	ans += long long(s[s.length()-1]);
	ans += long long(s[s.length()-2])*1000;
	if( s.length() == 3 )
		ans += long long(s[s.length()-3])*1000000;
	return ans;
}

string decalc( long long a ) {
	long long h = a;
	string ans;
	if( a >= 999999 ) {
		ans = "%%%";
		int j = 2;
		while( j >= 0 ) {
			ans[j] = char(h%1000);
			h = h/1000;
			j--;
		}
	} else {
		ans = "%%";
		int j = 1;
		while( j >= 0 ) {
			ans[j] = char(h%1000);
			h = h/1000;
			j--;
		}
	}
	return ans;
}

int main()  {

	string s; cin >> s;
	if( s.length() < 7 ) {
		cout << 0;
		return 0;
	}
	if( s.length() == 7 ) {
		cout << 1 << endl;
		cout << s.substr(5,2);
		return 0;
	}
	set<long long> b;
	for( int i = 5; i < s.length() - 3; i++ ) {
		b.insert( calc( s.substr(i,2)));
	}
	for( int i = 5; i < s.length() - 4; i++ ) {
		b.insert( calc( s.substr(i,3)));
	}
	if( s.length() - 2 >= 5 ) {
		b.insert( calc( s.substr( s.length()-2,2 ) ) );
	}
	if( s.length() - 3 >= 5 ) {
		b.insert( calc( s.substr( s.length()-3,3 ) ) );
	}
	cout << b.size() << endl;
	vector<string> fin;
	for( set<long long>::iterator i = b.begin(); i != b.end(); i++ ) {
		fin.push_back( decalc(*i) );
	}
	sort(fin.begin(), fin.end() );
	for( int i = 0; i < fin.size(); i++ ) {
		cout << fin[i] << endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <limits>
#include <iomanip>
#include <ctime>

using namespace std;

long long calc( string &s ) {
	long long ans = 0;
	ans += long long(s[s.length()-1]);
	ans += long long(s[s.length()-2])*1000;
	if( s.length() == 3 )
		ans += long long(s[s.length()-3])*1000000;
	return ans;
}

string decalc( long long a ) {
	long long h = a;
	string ans;
	if( a >= 999999 ) {
		ans = "%%%";
		int j = 2;
		while( j >= 0 ) {
			ans[j] = char(h%1000);
			h = h/1000;
			j--;
		}
	} else {
		ans = "%%";
		int j = 1;
		while( j >= 0 ) {
			ans[j] = char(h%1000);
			h = h/1000;
			j--;
		}
	}
	return ans;
}

struct can {
	bool v3;
	bool v2;
};

int main()  {

	string s; cin >> s;
	if( s.length() < 7 ) {
		cout << 0;
		return 0;
	}
	if( s.length() == 7 ) {
		cout << 1 << endl;
		cout << s.substr(5,2);
		return 0;
	}
	set<long long> b;
	if( s.length() >= 7 ) {
		b.insert( calc( s.substr(s.length()-2,2)));
	}
	if( s.length() >= 8 ) {
		b.insert( calc( s.substr(s.length()-3,3)));
	}
	vector<can> c( s.length() );
	c[s.length()-1].v2 = false;
	c[s.length()-1].v3 = false;
	c[s.length()-2].v2 = true;
	c[s.length()-2].v3 = false;
	c[s.length()-3].v2 = false;
	c[s.length()-3].v3 = true;
	for( int i = s.length() - 4; i >= 5; i-- ) {
		if( c[i+2].v3 == true || (c[i+2].v2 == true && s.substr(i+2,2) != s.substr(i,2) ) ) {
			c[i].v2 = true;
			b.insert( calc(s.substr(i,2)) );
		} else {
			c[i].v2 = false;
		}
		if( c[i+3].v2 == true || (c[i+3].v3 == true && s.substr(i+3,3) != s.substr(i,3) ) ) {
			c[i].v3 = true;
			b.insert( calc(s.substr(i,3)) );
		} else {
			c[i].v3 = false;
		}
	}

	cout << b.size() << endl;
	vector<string> fin;
	for( set<long long>::iterator i = b.begin(); i != b.end(); i++ ) {
		fin.push_back( decalc(*i) );
	}
	sort(fin.begin(), fin.end() );
	for( int i = 0; i < fin.size(); i++ ) {
		cout << fin[i] << endl;
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <time.h>
#include <random>
#include <algorithm>
#include <string>
#include <string.h>
#include <queue>
#include <deque>
#include <functional>
#include <cctype>
#include <list>
#define mp make_pair
#define cen cout << "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double db;
typedef pair<ll, ll> pll;
const int inf = 1000000007;
set<string> st;
string s;
bool b[10100];
set<string> bst[10100];
void rec(int k, string p){
	if (b[k] && bst[k].find(p) != bst[k].end())
		return;
	b[k] = 1;
	bst[k].insert(p);
	string res = "", t;
	if (k <= 5)
		return;
	if (k == 6){
		res.push_back(s[5]);
		res.push_back(s[6]);
		if (res != p)
			st.insert(res);
		return;
	}
	if (k == 7){
		res.push_back(s[5]);
		res.push_back(s[6]);
		res.push_back(s[7]);
		if (res != p)
			st.insert(res);
		res = "";
		res.push_back(s[6]);
		res.push_back(s[7]);
		if (res != p)
			st.insert(res);
		return;
	}
	res = "";
	res.push_back(s[k - 1]);
	res.push_back(s[k]);
	if (res != p){
		st.insert(res);
		rec(k - 2, res);
	}
	res = "";
	res.push_back(s[k - 2]);
	res.push_back(s[k - 1]);
	res.push_back(s[k]);
	if (res != p){
		st.insert(res);
		rec(k - 3, res);
	}
}

int main(){
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	cin >> s;
	rec(s.size() - 1, "");
	cout << st.size();
	cen;
	for (auto it = st.begin(); it != st.end(); ++it){
		cout << (*it);
		cen;
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <time.h>
#include <random>
#include <algorithm>
#include <string>
#include <string.h>
#include <queue>
#include <deque>
#include <functional>
#include <cctype>
#include <list>
#define mp make_pair
#define cen cout << "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double db;
typedef pair<ll, ll> pll;
const int inf = 1000000007;
set<string> st;
string s;
bool b[10100];
void rec(int k, string p){
	string res = "", t;
	if (k <= 5)
		return;
	if (k == 6){
		res.push_back(s[5]);
		res.push_back(s[6]);
		if (res != p)
			st.insert(res);
		return;
	}
	if (k == 7){
		res.push_back(s[5]);
		res.push_back(s[6]);
		res.push_back(s[7]);
		if (res != p)
			st.insert(res);
		res = "";
		res.push_back(s[6]);
		res.push_back(s[7]);
		if (res != p)
			st.insert(res);
		return;
	}
	res = "";
	res.push_back(s[k - 1]);
	res.push_back(s[k]);
	if (res != p){
		st.insert(res);
		rec(k - 2, res);
	}
	res = "";
	res.push_back(s[k - 2]);
	res.push_back(s[k - 1]);
	res.push_back(s[k]);
	if (res != p){
		st.insert(res);
		rec(k - 3, res);
	}
}

int main(){
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	cin >> s;
	rec(s.size() - 1, "");
	cout << st.size();
	cen;
	for (auto it = st.begin(); it != st.end(); ++it){
		cout << (*it);
		cen;
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <time.h>
#include <random>
#include <algorithm>
#include <string>
#include <string.h>
#include <queue>
#include <deque>
#include <functional>
#include <cctype>
#include <list>
#define mp make_pair
#define cen cout << "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double db;
typedef pair<ll, ll> pll;
const int inf = 1000000007;
set<string> st;
string s;
bool b[10100];
void rec(int k, string p){
	if (b[k])
		return;
	b[k] = 1;
	string res = "", t;
	if (k <= 5)
		return;
	if (k == 6){
		res.push_back(s[5]);
		res.push_back(s[6]);
		if (res != p)
			st.insert(res);
		return;
	}
	if (k == 7){
		res.push_back(s[5]);
		res.push_back(s[6]);
		res.push_back(s[7]);
		if (res != p)
			st.insert(res);
		res = "";
		res.push_back(s[6]);
		res.push_back(s[7]);
		if (res != p)
			st.insert(res);
		return;
	}
	res = "";
	res.push_back(s[k - 1]);
	res.push_back(s[k]);
	if (res != p){
		st.insert(res);
		rec(k - 2, res);
	}
	res = "";
	res.push_back(s[k - 2]);
	res.push_back(s[k - 1]);
	res.push_back(s[k]);
	if (res != p){
		st.insert(res);
		rec(k - 3, res);
	}
}

int main(){
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	cin >> s;
	rec(s.size() - 1, "");
	cout << st.size();
	cen;
	for (auto it = st.begin(); it != st.end(); ++it){
		cout << (*it);
		cen;
	}

	return 0;
}


#include <iostream>
#include <map>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <string.h>
#include <list>
#include <algorithm>
#include <time.h>
#define _CRT_SECURE_NO_WARNINGS
//#pragma comment(linker, "/STACK:16777216")
#pragma warning(disable : 4996)
using namespace std;

const int MAX = 1e4 + 13;

string s;

map<string, int> mp;

int dp[2][MAX];

int main() {
  //freopen("tests.txt", "r", stdin);
  //freopen("out.txt", "w", stdout);

  cin >> s;

  for (int i = s.size(); i < MAX; i++) {
    dp[1][i] = dp[0][i] = 1;
  }

  s = s + "###";
  for (int i = s.size() - 4; i >= 0; i--) {
    if ((dp[1][i + 2] || (dp[0][i + 2] && s.substr(i, 2) != s.substr(i + 2, 2))) && i <= s.size() - 5)
      dp[0][i] = 1;
    if ((dp[0][i + 3] || (dp[1][i + 3] && !(s.substr(i, 3) == s.substr(i + 3, 3)))) && i <= s.size() - 6)
      dp[1][i] = 1;
  }

  for (int i = 5; i <= s.size() - 4; i++) {
    if (dp[0][i]) {
      mp[s.substr (i, 2)]++;
    }
    if (dp[1][i]) {
      mp[s.substr (i, 3)]++;
    }
  }

  cout << mp.size() << endl;
  for (auto it = mp.begin(); it != mp.end(); ++it) {
    cout << it->first << endl;
  }
  return 0;
}


#include <iostream>
#include <map>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <string.h>
#include <list>
#include <algorithm>
#include <time.h>
#define _CRT_SECURE_NO_WARNINGS
//#pragma comment(linker, "/STACK:16777216")
#pragma warning(disable : 4996)
using namespace std;

const int MAX = 1e4 + 13;

string s;

map<string, int> mp;

int dp[2][MAX];

int main() {
  //freopen("tests.txt", "r", stdin);
  //freopen("out.txt", "w", stdout);

  cin >> s;

  for (int i = s.size(); i < MAX; i++) {
    dp[1][i] = dp[0][i] = 1;
  }

  s = s + "###";
  for (int i = s.size() - 4; i >= 0; i--) {
    if ((dp[1][i + 2] || (dp[0][i + 2] && s.substr(i, 2) != s.substr(i + 2, 2))) && i <= s.size() - 5)
      dp[0][i] = 1;
    if ((dp[0][i + 3] || (dp[1][i + 3] && s.substr(i + 3, 3) != s.substr(i + 3, 3))) && i <= s.size() - 6)
      dp[1][i] = 1;
  }

  for (int i = 5; i <= s.size() - 4; i++) {
    if (dp[0][i]) {
      mp[s.substr (i, 2)]++;
    }
    if (dp[1][i]) {
      mp[s.substr (i, 3)]++;
    }
  }

  cout << mp.size() << endl;
  for (auto it = mp.begin(); it != mp.end(); ++it) {
    cout << it->first << endl;
  }
  return 0;
}


#include <iostream>
#include <map>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <string.h>
#include <list>
#include <algorithm>
#include <time.h>
#define _CRT_SECURE_NO_WARNINGS
//#pragma comment(linker, "/STACK:16777216")
#pragma warning(disable : 4996)
using namespace std;

const int MAX = 1e4 + 13;

string s;

map<string, int> mp;

int dp[2][MAX];

int main() {
  //freopen("tests.txt", "r", stdin);
  //freopen("out.txt", "w", stdout);

  cin >> s;

  for (int i = s.size(); i < MAX; i++) {
    dp[1][i] = dp[0][i] = 1;
  }

  s = s + "###";
  for (int i = s.size() - 4; i >= 0; i--) {
    if ((dp[1][i + 2] || (dp[0][i + 2] && s.substr(i, 2) != s.substr(i + 2, 2))) && i <= s.size() - 5)
      dp[0][i] = 1;
    if ((dp[0][i + 3] || (dp[1][i + 3] && s.substr(i + 3, 3) != s.substr(i + 3, 3))) && i <= s.size() - 6)
      dp[1][i] = 1;
  }

  for (int i = 5; i <= s.size() - 5; i++) {
    if (dp[0][i]) {
      mp[s.substr (i, 2)]++;
    }
    if (dp[1][i]) {
      mp[s.substr (i, 3)]++;
    }
  }

  cout << mp.size() << endl;
  for (auto it = mp.begin(); it != mp.end(); ++it) {
    cout << it->first << endl;
  }
  return 0;
}


s = input()
n = len(s)
res = set()

from collections import defaultdict

two = ["$", "", "$"]
thr = ["$", "", "$"]

works = lambda w, i : (two[i] != "$" and w != two[i]) or (thr[i] != "$" and w != thr[i])

i = n - 2
while i > 4:
    ntwo = s[i: i + 2]
    if works(ntwo, 1):
        res.add(ntwo)
    else:
        ntwo = "$"

    if (i <= n - 3):
        nthr = s[i: i + 3]
        if works(nthr, 2):
            res.add(nthr)
        else:
            nthr = "$"
    else:
        nthr = "$"

    two = [ntwo] + two[0:2]
    thr = [nthr] + thr[0:2]
    i -= 1

res = list(res)
res.sort()

print(len(res))
for word in res:
    print(word)


s=input()
ans=set()
def per(l,suf=''):
    global ans
    if l>6 and s[l-2:l]!=suf: ans|={s[l-2:l]}; per(l-2,s[l-2:l])
    if l>7 and s[l-3:l]!=suf: ans|={s[l-3:l]}; per(l-3,s[l-3:l])
per(len(s))
print(len(ans))
for x in sorted(ans):
    print(x)


s=input()
ans,f=set(),{}
def per(l,ll=0):
    global ans
    if l>6 and s[l-2:l]!=s[l:l+ll]: ans|={s[l-2:l]}; per(l-2,2)
    if l>7 and s[l-3:l]!=s[l:l+ll]: ans|={s[l-3:l]}; per(l-3,3)
per(len(s))
print(len(ans))
for x in sorted(ans):
    print(x)


s=input()
ans,f=set(),{}
def per(l,ll=0):
    if (l,ll) in f: return
    global ans
    f[(l,ll)]=1
    if l>6 and s[l-2:l]!=s[l:l+ll]: ans|={s[l-2:l]}; per(l-2,2)
    if l>7 and s[l-3:l]!=s[l:l+ll]: ans|={s[l-3:l]}; per(l-3,3)

per(len(s))
print(len(ans))
for x in sorted(ans):
    print(x)


from sys import *
setrecursionlimit(10001)
s=input()
ans,f=set(),{}
def per(l,ll=0):
    if (l,ll) in f: return
    global ans
    f[(l,ll)]=1
    if l>6 and s[l-2:l]!=s[l:l+ll]: ans|={s[l-2:l]}; per(l-2,2)
    if l>7 and s[l-3:l]!=s[l:l+ll]: ans|={s[l-3:l]}; per(l-3,3)

per(len(s))
print(len(ans))
for x in sorted(ans):
    print(x)


s=input()
ans=set()
def per(l):
    global ans
    if l>6 and s[l-2:l]!=s[l-4:l-2]: ans|={s[l-2:l]}; per(l-2)
    if l>7 and s[l-3:l]!=s[l-6:l-3]: ans|={s[l-3:l]}; per(l-3)
per(len(s))
print(len(ans))
for x in sorted(ans):
    print(x)


a=input()
n=len(a)
sufiks = set()
suf_lens = [0] * (n+1)
suf_lens[n] = 3
def main(i, len_suf):
    if (suf_lens[i] & len_suf - 1 and a[i : i + len_suf] != a[i-len_suf:i]) or suf_lens[i] & 4 - len_suf :
        sufiks.add(a[i-len_suf : i])
        suf_lens[i - len_suf] |= len_suf - 1

for i in range(n, 6, -1):
    main(i, 2)
    if i > 7: main(i, 3)

print (len(sufiks))
for i in sorted(sufiks):
    print (i)


s = input().strip()
n = len(s)
suf = set()
dp = [0]*n
dp1 = [0]*n
for i in range(n-2,4,-1):
	if i == n-2:
		s1 = s[i] + s[i+1]
		dp[i] = 1
		suf.add(s1)
	elif i == n-3:
		s1 = s[i] + s[i+1] + s[i+2]
		dp1[i] = 1
		suf.add(s1)
	else:
		s1 = s[i] + s[i+1]
		if dp[i+2]|dp1[i+2] == 1 :
			if i+3 < n:
				if s[i+2:i+4] != s1:
					dp[i] = 1
					suf.add(s1)
				elif dp1[i+2] == 1:
					dp[i] = 1
					suf.add(s1)
			else:
				dp[i] = 1
				suf.add(s1)
		if i < n-2:
			s1 = s[i] + s[i+1] + s[i+2]
			if dp[i+3]|dp1[i+3] == 1:
				if i+5<n:
					if s[i+3:i+6] != s1:
						dp1[i] = 1
						suf.add(s1)
					elif dp[i+3] == 1:
						dp1[i] = 1
						suf.add(s1)
				else:
					dp1[i] = 1
					suf.add(s1)

sett = set(suf)
sff = sorted(sett)
print(len(suf))
for ss in sff:
	print(ss)


s = input().strip()
n = len(s)
suf = set()
dp = [0]*n
for i in range(n-2,4,-1):
	if i == n-2:
		s1 = s[i] + s[i+1]
		dp[i] = 1
		suf.add(s1)
	elif i == n-3:
		s1 = s[i] + s[i+1] + s[i+2]
		dp[i] = 1
		suf.add(s1)
	else:
		s1 = s[i] + s[i+1]
		if dp[i+2] == 1:
			dp[i] = 1
			suf.add(s1)
		if i < n-2:
			s1 = s[i] + s[i+1] + s[i+2]
			if dp[i+3] == 1:
				dp[i] = 1
				suf.add(s1)

sett = set(suf)
sff = sorted(sett)
print(len(suf))
for ss in sff:
	print(ss)


s = input().strip()
n = len(s)
suf = set()
dp = [0]*n
for i in range(n-2,4,-1):
	if i == n-2:
		s1 = s[i] + s[i+1]
		dp[i] = 1
		suf.add(s1)
	elif i == n-3:
		s1 = s[i] + s[i+1] + s[i+2]
		dp[i] = 1
		suf.add(s1)
	else:
		s1 = s[i] + s[i+1]
		if dp[i+2] == 1 :
			if i+3 < n:
				if s[i+2:i+4] != s1:
					dp[i] = 1
					suf.add(s1)
			else:
				dp[i] = 1
				suf.add(s1)
		if i < n-2:
			s1 = s[i] + s[i+1] + s[i+2]
			if dp[i+3] == 1:
				if i+5<n:
					if s[i+3:i+6] != s1:
						dp[i] = 1
						suf.add(s1)
				else:
					dp[i] = 1
					suf.add(s1)

sett = set(suf)
sff = sorted(sett)
print(len(suf))
for ss in sff:
	print(ss)


'''
Created on May 1, 2016
Gmail : r.haque.249.rh@gmail.com
@author: Md. Rezwanul Haque
'''
from sys import  *
setrecursionlimit(20000)
d = {}
t = set()
s = input()+' '
def gen(l,ll):
    if(l,ll) in t:
        return
    t.add((l,ll))
    if (l>6):
        d[s[l-2:l]] = 1
        if(s[l-2:l]!= s[l:ll]):
            gen(l-2, l)
    if (l>7):
        d[s[l-3:l]] = 1
        if(s[l-3:l]!=s[l:ll]):
            gen(l-3,l)
gen(len(s)-1, len(s))
print(len(d))
for k in sorted(d):
    print(k)


from sys import *
inp = lambda : stdin.readline()
import math
memo = {}

def findans(s,ans,start,parent):
    if start >= len(s): return
    if start + 1 < len(s):
        toadd = s[start:start+2]
        if toadd != parent:
            ans.add(toadd)
            if (start+2) not in memo:
                findans(s, ans, start + 2,toadd)
                memo[start+2] = 1

    if start + 2 < len(s):
        toadd = s[start:start+3]
        if toadd != parent:
            ans.add(toadd)
            if (start+3) not in memo:
                findans(s, ans, start + 3,toadd)
                memo[start+3] = 1

def main():
    s = (inp()[5:])[::-1].replace("\n","",1)
    ans = set()
    findans(s,ans,0,"")
    print(len(ans))
    l = []
    for i in ans:
        l.append(i[::-1])
    l = sorted(l)
    print("\n".join(l))

if __name__ == "__main__":
    main()


from sys import *
inp = lambda : stdin.readline()
import math
memo = {}

def findans(s,ans,start):
    if start >= len(s): return
    if start + 1 < len(s):
        toadd = s[start:start+2]
        if toadd not in ans:
            ans.add(toadd)
            if (start+2) not in memo:
                memo[start+2] = 1
                findans(s,ans,start+2)
    if start + 2 < len(s):
        toadd = s[start:start+3]
        if toadd not in ans:
            ans.add(toadd)
            if (start+3) not in memo:
                memo[start+3] = 1
                findans(s,ans,start+3)

def main():
    s = (inp()[5:])[::-1].replace("\n","",1)
    #print(s)
    ans = set()
    findans(s,ans,0)
    print(len(ans))
    l = []
    for i in ans:
        l.append(i[::-1])
    l = sorted(l)
    print("\n".join(l))

if __name__ == "__main__":
    main()