#include <cstdio>
#include <cmath>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

const int buf_len = 3001;
const int buf_size = buf_len * sizeof(char);
char buf[buf_len], *bufb(buf + buf_len - 1), *bufe(buf + buf_len);
#define readBuf() { \
	if (++ bufb == bufe) { \
		bufe = buf + fread(buf, 1, buf_size, stdin); \
		bufb = buf; \
	} \
}
#define readInt(_x_) { \
	register int _s_(0); \
	do { \
		readBuf(); \
	} while (!isdigit(*bufb)); \
	do { \
		_s_ = (_s_ << 3) + (_s_ << 1) + *bufb - 48; \
		readBuf(); \
	} while (isdigit(*bufb)); \
	_x_ = _s_; \
}

typedef unsigned int uint;
typedef pair <int, int> qpr;
typedef set <int> :: iterator setiter;

struct qry {
	int a, b, s;
};
struct edge {
	int a, b, c;
};
inline bool cmpEdge(const edge& a, const edge& b) {
	return a. c < b. c;
}

const int maxn = 100009;
const int maxs = 309;
const int maxa = maxn * maxs;

int n, m, tq, t, r[maxn], rtm[maxn], ttm;
edge e[maxn];
qry q[maxn];
qpr a[maxa];
set <int> rp;
int p[maxn];

inline int vis(int x) {
	if (rtm[x] == ttm)
		return r[x];
	else
		return rtm[x] = ttm, r[x] = x;
}

inline void chg(int x, int v) {
	rtm[x] = ttm;
	r[x] = v;
}

int getRoot(int x) {
	int p, q;
	for (p = x; vis(p) ^ p; p = r[p]);
	for (; x ^ p; x = q) {
		q = vis(x);
		chg(x, p);
	}
	return p;
}

inline void join(int u, int v) {
	if (getRoot(u) ^ getRoot(v))
		chg(getRoot(u), getRoot(v));
}

int main() {
	readInt(n);
	readInt(m);
	for (int i = 0; i < m; ++ i) {
		readInt(e[i]. a);
		readInt(e[i]. b);
		readInt(e[i]. c);
		if (e[i]. a > e[i]. b)
			swap(e[i]. a, e[i]. b);
	}
	sort(e, e + m, cmpEdge);
	readInt(tq);
	for (int i = 0; i < tq; ++ i) {
		readInt(q[i]. a);
		readInt(q[i]. b);
		q[i]. s = 0;
	}
	memset(rtm, 0, sizeof(rtm));
	ttm = 0;
	t = 0;
	for (int i = 0, j; i < m; i = j) {
		for (j = i; j < m && e[j]. c == e[i]. c; ++ j);
		if (j - i > 100) {
			++ ttm;
			for (int k = i; k < j; ++ k)
				join(e[k]. a, e[k]. b);
			for (int k = 0; k < tq; ++ k)
				if (getRoot(q[k]. a) == getRoot(q[k]. b))
					++ q[i]. s;
		}
		else {
			++ ttm;
			rp. clear();
			for (int k = i; k < j; ++ k) {
				join(e[k]. a, e[k]. b);
				rp. insert(e[k]. a);
				rp. insert(e[k]. b);
			}
			uint e = 0;
			for (set <int> :: iterator it = rp. begin(); it != rp. end(); ++ it)
				p[e ++] = *it;
			sort(p, p + e);
			for (uint x = 0; x < e; ++ x)
				for (uint y = i + 1; y < e; ++ y)
					if (getRoot(p[x]) == getRoot(p[y]))
						a[t ++] = qpr(p[x], p[y]);
		}
	}
	sort(a, a + t);
	for (int i = 0; i < tq; ++ i) {
		if (q[i]. a > q[i]. b)
			swap(q[i]. a, q[i]. b);
		qpr g(q[i]. a, q[i]. b);
		q[i]. s += upper_bound(a, a + t, g) - lower_bound(a, a + t, g);
		printf("%d\n", q[i]. s);
	}
}


#include <cstdio>
#include <cmath>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

const int buf_len = 3001;
const int buf_size = buf_len * sizeof(char);
char buf[buf_len], *bufb(buf + buf_len - 1), *bufe(buf + buf_len);
#define readBuf() { \
	if (++ bufb == bufe) { \
		bufe = buf + fread(buf, 1, buf_size, stdin); \
		bufb = buf; \
	} \
}
#define readInt(_x_) { \
	register int _s_(0); \
	do { \
		readBuf(); \
	} while (!isdigit(*bufb)); \
	do { \
		_s_ = (_s_ << 3) + (_s_ << 1) + *bufb - 48; \
		readBuf(); \
	} while (isdigit(*bufb)); \
	_x_ = _s_; \
}

typedef unsigned int uint;
typedef pair <int, int> qpr;
typedef set <int> :: iterator setiter;

struct qry {
	int a, b, s;
};
struct edge {
	int a, b, c;
};
inline bool cmpEdge(const edge& a, const edge& b) {
	return a. c < b. c;
}

const int maxn = 100009;
const int maxs = 309;
const int maxa = maxn * maxs;

int n, m, tq, t, r[maxn], rtm[maxn], ttm;
edge e[maxn];
qry q[maxn];
qpr a[maxa];
set <int> rp;
int p[maxn];

inline int vis(int x) {
	if (rtm[x] == ttm)
		return r[x];
	else
		return rtm[x] = ttm, r[x] = x;
}

inline void chg(int x, int v) {
	rtm[x] = ttm;
	r[x] = v;
}

int getRoot(int x) {
	int p, q;
	for (p = x; vis(p) ^ p; p = r[p]);
	for (; x ^ p; x = q) {
		q = vis(x);
		chg(x, p);
	}
	return p;
}

inline void join(int u, int v) {
	if (getRoot(u) ^ getRoot(v))
		chg(getRoot(u), getRoot(v));
}

int main() {
	readInt(n);
	readInt(m);
	for (int i = 0; i < m; ++ i) {
		readInt(e[i]. a);
		readInt(e[i]. b);
		readInt(e[i]. c);
		if (e[i]. a > e[i]. b)
			swap(e[i]. a, e[i]. b);
	}
	sort(e, e + m, cmpEdge);
	readInt(tq);
	for (int i = 0; i < tq; ++ i) {
		readInt(q[i]. a);
		readInt(q[i]. b);
		q[i]. s = 0;
		if (q[i]. a > q[i]. b)
			swap(q[i]. a, q[i]. b);
	}
	memset(rtm, 0, sizeof(rtm));
	ttm = 0;
	t = 0;
	for (int i = 0, j; i < m; i = j) {
		for (j = i; j < m && e[j]. c == e[i]. c; ++ j);
		if (j - i > 100) {
			++ ttm;
			for (int k = i; k < j; ++ k)
				join(e[k]. a, e[k]. b);
			for (int k = 0; k < tq; ++ k)
				if (getRoot(q[k]. a) == getRoot(q[k]. b))
					++ q[k]. s;
		}
		else {
			++ ttm;
			rp. clear();
			for (int k = i; k < j; ++ k) {
				join(e[k]. a, e[k]. b);
				rp. insert(e[k]. a);
				rp. insert(e[k]. b);
			}
			uint e = 0;
			for (set <int> :: iterator it = rp. begin(); it != rp. end(); ++ it)
				p[e ++] = *it;
			sort(p, p + e);
			for (uint x = 0; x < e; ++ x)
				for (uint y = x + 1; y < e; ++ y)
					if (getRoot(p[x]) == getRoot(p[y]))
						a[t ++] = qpr(p[x], p[y]);
		}
	}
	sort(a, a + t);
	for (int i = 0; i < tq; ++ i) {
		qpr g(q[i]. a, q[i]. b);
		q[i]. s += upper_bound(a, a + t, g) - lower_bound(a, a + t, g);
		printf("%d\n", q[i]. s);
	}
}


#include <cstdio>
#include <cmath>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

const int buf_len = 3001;
const int buf_size = buf_len * sizeof(char);
char buf[buf_len], *bufb(buf + buf_len - 1), *bufe(buf + buf_len);
#define readBuf() { \
	if (++ bufb == bufe) { \
		bufe = buf + fread(buf, 1, buf_size, stdin); \
		bufb = buf; \
	} \
}
#define readInt(_x_) scanf("%d",&_x_);
typedef unsigned int uint;
typedef pair <int, int> qpr;
typedef set <int> :: iterator setiter;

struct qry {
	int a, b, s;
};
struct edge {
	int a, b, c;
};
inline bool cmpEdge(const edge& a, const edge& b) {
	return a. c < b. c;
}

const int maxn = 100009;
const int maxs = 309;
const int maxa = maxn * maxs;

int n, m, tq, t, r[maxn], rtm[maxn], ttm;
edge e[maxn];
qry q[maxn];
qpr a[maxa];
set <int> rp;
int p[maxn];

inline int vis(int x) {
	if (rtm[x] == ttm)
		return r[x];
	else
		return rtm[x] = ttm, r[x] = x;
}

inline void chg(int x, int v) {
	rtm[x] = ttm;
	r[x] = v;
}

int getRoot(int x) {
	int p, q;
	for (p = x; vis(p) ^ p; p = r[p]);
	for (; x ^ p; x = q) {
		q = vis(x);
		chg(x, p);
	}
	return p;
}

inline void join(int u, int v) {
	if (getRoot(u) ^ getRoot(v))
		chg(getRoot(u), getRoot(v));
}

int main() {
	readInt(n);
	readInt(m);
	for (int i = 0; i < m; ++ i) {
		readInt(e[i]. a);
		readInt(e[i]. b);
		readInt(e[i]. c);
		if (e[i]. a > e[i]. b)
			swap(e[i]. a, e[i]. b);
	}
	sort(e, e + m, cmpEdge);
	readInt(tq);
	for (int i = 0; i < tq; ++ i) {
		readInt(q[i]. a);
		readInt(q[i]. b);
		q[i]. s = 0;
		if (q[i]. a > q[i]. b)
			swap(q[i]. a, q[i]. b);
	}
	memset(rtm, 0, sizeof(rtm));
	ttm = 0;
	t = 0;
	for (int i = 0, j; i < m; i = j) {
		for (j = i; j < m && e[j]. c == e[i]. c; ++ j);
		if (j - i > 100) {
			++ ttm;
			for (int k = i; k < j; ++ k)
				join(e[k]. a, e[k]. b);
			for (int k = 0; k < tq; ++ k)
				if (getRoot(q[k]. a) == getRoot(q[k]. b))
					++ q[i]. s;
		}
		else {
			++ ttm;
			rp. clear();
			for (int k = i; k < j; ++ k) {
				join(e[k]. a, e[k]. b);
				rp. insert(e[k]. a);
				rp. insert(e[k]. b);
			}
			uint e = 0;
			for (set <int> :: iterator it = rp. begin(); it != rp. end(); ++ it)
				p[e ++] = *it;
			sort(p, p + e);
			for (uint x = 0; x < e; ++ x)
				for (uint y = x + 1; y < e; ++ y)
					if (getRoot(p[x]) == getRoot(p[y]))
						a[t ++] = qpr(p[x], p[y]);
		}
	}
	sort(a, a + t);
	for (int i = 0; i < tq; ++ i) {
		qpr g(q[i]. a, q[i]. b);
		q[i]. s += upper_bound(a, a + t, g) - lower_bound(a, a + t, g);
		printf("%d\n", q[i]. s);
	}
}


#include <cstdio>
#include <cmath>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

const int buf_len = 3001;
const int buf_size = buf_len * sizeof(char);
char buf[buf_len], *bufb(buf + buf_len - 1), *bufe(buf + buf_len);
#define readBuf() { \
	if (++ bufb == bufe) { \
		bufe = buf + fread(buf, 1, buf_size, stdin); \
		bufb = buf; \
	} \
}
#define readInt(_x_) { \
	register int _s_(0); \
	do { \
		readBuf(); \
	} while (!isdigit(*bufb)); \
	do { \
		_s_ = (_s_ << 3) + (_s_ << 1) + *bufb - 48; \
		readBuf(); \
	} while (isdigit(*bufb)); \
	_x_ = _s_; \
}

typedef unsigned int uint;
typedef pair <int, int> qpr;
typedef set <int> :: iterator setiter;

struct qry {
	int a, b, s;
};
struct edge {
	int a, b, c;
};
inline bool cmpEdge(const edge& a, const edge& b) {
	return a. c < b. c;
}

const int maxn = 100009;
const int maxs = 309;
const int maxa = maxn * maxs;

int n, m, tq, t, r[maxn], rtm[maxn], ttm;
edge e[maxn];
qry q[maxn];
qpr a[maxa];
set <int> rp;
int p[maxn];

inline int vis(int x) {
	if (rtm[x] == ttm)
		return r[x];
	else
		return rtm[x] = ttm, r[x] = x;
}

inline void chg(int x, int v) {
	rtm[x] = ttm;
	r[x] = v;
}

int getRoot(int x) {
	int p, q;
	for (p = x; vis(p) ^ p; p = r[p]);
	for (; x ^ p; x = q) {
		q = vis(x);
		chg(x, p);
	}
	return p;
}

inline void join(int u, int v) {
	if (getRoot(u) ^ getRoot(v))
		chg(getRoot(u), getRoot(v));
}

int main() {
	readInt(n);
	readInt(m);
	for (int i = 0; i < m; ++ i) {
		readInt(e[i]. a);
		readInt(e[i]. b);
		readInt(e[i]. c);
		if (e[i]. a > e[i]. b)
			swap(e[i]. a, e[i]. b);
	}
	sort(e, e + m, cmpEdge);
	readInt(tq);
	for (int i = 0; i < tq; ++ i) {
		readInt(q[i]. a);
		readInt(q[i]. b);
		q[i]. s = 0;
		if (q[i]. a > q[i]. b)
			swap(q[i]. a, q[i]. b);
	}
	memset(rtm, 0, sizeof(rtm));
	ttm = 0;
	t = 0;
	for (int i = 0, j; i < m; i = j) {
		for (j = i; j < m && e[j]. c == e[i]. c; ++ j);
		if (j - i > 100 && 0) {
			++ ttm;
			for (int k = i; k < j; ++ k)
				join(e[k]. a, e[k]. b);
			for (int k = 0; k < tq; ++ k)
				if (getRoot(q[k]. a) == getRoot(q[k]. b))
					++ q[k]. s;
		}
		else {
			++ ttm;
			rp. clear();
			for (int k = i; k < j; ++ k) {
				join(e[k]. a, e[k]. b);
				rp. insert(e[k]. a);
				rp. insert(e[k]. b);
			}
			uint e = 0;
			for (set <int> :: iterator it = rp. begin(); it != rp. end(); ++ it)
				p[e ++] = *it;
			sort(p, p + e);
			for (uint x = 0; x < e; ++ x)
				for (uint y = x + 1; y < e; ++ y)
					if (getRoot(p[x]) == getRoot(p[y]))
						a[t ++] = qpr(p[x], p[y]);
		}
	}
	sort(a, a + t);
	for (int i = 0; i < tq; ++ i) {
		qpr g(q[i]. a, q[i]. b);
		q[i]. s += upper_bound(a, a + t, g) - lower_bound(a, a + t, g);
		printf("%d\n", q[i]. s);
	}
}


#include <cstdio>
#include <cmath>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

const int buf_len = 3001;
const int buf_size = buf_len * sizeof(char);
char buf[buf_len], *bufb(buf + buf_len - 1), *bufe(buf + buf_len);
#define readBuf() { \
	if (++ bufb == bufe) { \
		bufe = buf + fread(buf, 1, buf_size, stdin); \
		bufb = buf; \
	} \
}
#define readInt(_x_) { \
	register int _s_(0); \
	do { \
		readBuf(); \
	} while (!isdigit(*bufb)); \
	do { \
		_s_ = (_s_ << 3) + (_s_ << 1) + *bufb - 48; \
		readBuf(); \
	} while (isdigit(*bufb)); \
	_x_ = _s_; \
}

typedef unsigned int uint;
typedef pair <int, int> qpr;
typedef set <int> :: iterator setiter;

struct qry {
	int a, b, s;
};
struct edge {
	int a, b, c;
};
inline bool cmpEdge(const edge& a, const edge& b) {
	return a. c < b. c;
}

const int maxn = 100009;
const int maxs = 309;
const int maxa = maxn * maxs;

int n, m, tq, t, r[maxn], rtm[maxn], ttm;
edge e[maxn];
qry q[maxn];
qpr a[maxa];
set <int> rp;
int p[maxn];

inline int vis(int x) {
	if (rtm[x] == ttm)
		return r[x];
	else
		return rtm[x] = ttm, r[x] = x;
}

inline void chg(int x, int v) {
	rtm[x] = ttm;
	r[x] = v;
}

int getRoot(int x) {
	int p, q;
	for (p = x; vis(p) ^ p; p = r[p]);
	for (; x ^ p; x = q) {
		q = vis(x);
		chg(x, p);
	}
	return p;
}

inline void join(int u, int v) {
	if (getRoot(u) ^ getRoot(v))
		chg(getRoot(u), getRoot(v));
}

int main() {
	readInt(n);
	readInt(m);
	for (int i = 0; i < m; ++ i) {
		readInt(e[i]. a);
		readInt(e[i]. b);
		readInt(e[i]. c);
		if (e[i]. a > e[i]. b)
			swap(e[i]. a, e[i]. b);
	}
	sort(e, e + m, cmpEdge);
	readInt(tq);
	for (int i = 0; i < tq; ++ i) {
		readInt(q[i]. a);
		readInt(q[i]. b);
		q[i]. s = 0;
	}
	memset(rtm, 0, sizeof(rtm));
	ttm = 0;
	t = 0;
	for (int i = 0, j; i < m; i = j) {
		for (j = i; j < m && e[j]. c == e[i]. c; ++ j);
		if (j - i > 100) {
			++ ttm;
			for (int k = i; k < j; ++ k)
				join(e[k]. a, e[k]. b);
			for (int k = 0; k < tq; ++ k)
				if (getRoot(q[k]. a) == getRoot(q[k]. b))
					++ q[i]. s;
		}
		else {
			++ ttm;
			rp. clear();
			for (int k = i; k < j; ++ k) {
				join(e[k]. a, e[k]. b);
				rp. insert(e[k]. a);
				rp. insert(e[k]. b);
			}
			uint e = 0;
			for (set <int> :: iterator it = rp. begin(); it != rp. end(); ++ it)
				p[e ++] = *it;
			sort(p, p + e);
			for (uint x = 0; x < e; ++ x)
				for (uint y = x + 1; y < e; ++ y)
					if (getRoot(p[x]) == getRoot(p[y]))
						a[t ++] = qpr(p[x], p[y]);
		}
	}
	sort(a, a + t);
	for (int i = 0; i < tq; ++ i) {
		if (q[i]. a > q[i]. b)
			swap(q[i]. a, q[i]. b);
		qpr g(q[i]. a, q[i]. b);
		q[i]. s += upper_bound(a, a + t, g) - lower_bound(a, a + t, g);
		printf("%d\n", q[i]. s);
	}
}


#!/usr/bin/env python3
# 667C_ling.py - Codeforces.com/problemset/problem/667/C by Sergey 2016

import unittest
import sys
from collections import deque

###############################################################################
# Ling Class (Main Program)
###############################################################################

class Ling:
    """ Ling representation """

    def __init__(self, test_inputs=None):
        """ Default constructor """

        it = iter(test_inputs.split("\n")) if test_inputs else None

        def uinput():
            return next(it) if it else sys.stdin.readline().rstrip()

        # Reading single elements
        self.s = uinput()

    def calculate(self):
        """ Main calcualtion function of the class """

        chars = list(self.s)
        slen = len(chars)
        result = set([])
        vis = set([])
        q = deque([(0, "")])
        while q:
            pos, prev = q.popleft()
            if (pos, prev) in vis:
                continue
            pos2 = pos + 2
            if slen - pos2 > 4:
                new = str(chars[slen-1-pos-1]) + str(chars[slen-1-pos])
                if new != prev:
                    result.add(new)
                    q.append((pos2, new))
            pos3 = pos + 3
            if slen - pos3 > 4:
                new = (str(chars[slen-1-pos-2]) +
                       str(chars[slen-1-pos-1]) + str(chars[slen-1-pos]))
                if new != prev:
                    result.add(new)
                    q.append((pos3, new))

            vis.add((pos, prev))

        return (str(len(result)) + "\n" + "\n".join(sorted(result))
                if result else "0")

###############################################################################
# Unit Tests
###############################################################################

class unitTests(unittest.TestCase):

    def test_single_test(self):
        """ Ling class testing """

        # Constructor test
        test = "abacabaca"
        d = Ling(test)
        self.assertEqual(d.s, "abacabaca")

        # Sample test
        self.assertEqual(Ling(test).calculate(), "3\naca\nba\nca")

        # Sample test
        test = "abaca"
        self.assertEqual(Ling(test).calculate(), "0")

        # My tests
        test = "fffffaafgfg"
        # self.assertEqual(Ling(test).calculate(), "0")

        # Time limit test
        # self.time_limit_test(5000)

    def time_limit_test(self, nmax):
        """ Timelimit testing """
        import random
        import timeit

        # Random inputs
        test = str(nmax) + " " + str(nmax) + "\n"
        numnums = [str(i) + " " + str(i+1) for i in range(nmax)]
        test += "\n".join(numnums) + "\n"
        nums = [random.randint(1, 10000) for i in range(nmax)]
        test += " ".join(map(str, nums)) + "\n"

        # Run the test
        start = timeit.default_timer()
        d = Ling(test)
        calc = timeit.default_timer()
        d.calculate()
        stop = timeit.default_timer()
        print("\nTimelimit Test: " +
              "{0:.3f}s (init {1:.3f}s calc {2:.3f}s)".
              format(stop-start, calc-start, stop-calc))

if __name__ == "__main__":

    # Avoiding recursion limitaions
    sys.setrecursionlimit(100000)

    if sys.argv[-1] == "-ut":
        unittest.main(argv=[" "])

    # Print the result string
    sys.stdout.write(Ling().calculate())


#!/usr/bin/env python3
# 667C_ling.py - Codeforces.com/problemset/problem/667/C by Sergey 2016

import unittest
import sys
from collections import deque

###############################################################################
# Ling Class (Main Program)
###############################################################################

class Ling:
    """ Ling representation """

    def __init__(self, test_inputs=None):
        """ Default constructor """

        it = iter(test_inputs.split("\n")) if test_inputs else None

        def uinput():
            return next(it) if it else sys.stdin.readline().rstrip()

        # Reading single elements
        self.s = uinput()

    def calculate(self):
        """ Main calcualtion function of the class """

        chars = list(self.s)
        slen = len(chars)
        result = set([])
        vis = set([])
        q = deque([1])
        while q:
            pos = q.popleft()
            if pos in vis:
                continue
            pos2 = pos + 2
            if slen - pos2 >= 4:
                result.add(str(chars[-pos-1]) + str(chars[-pos]))
                q.append(pos2)
            pos3 = pos + 3
            if slen - pos3 >= 4:
                result.add(str(chars[-pos-2]) +
                           str(chars[-pos-1]) + str(chars[-pos]))
                q.append(pos3)

            vis.add(pos)

        return (str(len(result)) + "\n" + "\n".join(sorted(result))
                if result else "0")

###############################################################################
# Unit Tests
###############################################################################

class unitTests(unittest.TestCase):

    def test_single_test(self):
        """ Ling class testing """

        # Constructor test
        test = "abacabaca"
        d = Ling(test)
        self.assertEqual(d.s, "abacabaca")

        # Sample test
        self.assertEqual(Ling(test).calculate(), "3\naca\nba\nca")

        # Sample test
        test = "abaca"
        self.assertEqual(Ling(test).calculate(), "0")

        # Sample test
        test = ""
        # self.assertEqual(Ling(test).calculate(), "0")

        # My tests
        test = ""
        # self.assertEqual(Ling(test).calculate(), "0")

        # Time limit test
        # self.time_limit_test(5000)

    def time_limit_test(self, nmax):
        """ Timelimit testing """
        import random
        import timeit

        # Random inputs
        test = str(nmax) + " " + str(nmax) + "\n"
        numnums = [str(i) + " " + str(i+1) for i in range(nmax)]
        test += "\n".join(numnums) + "\n"
        nums = [random.randint(1, 10000) for i in range(nmax)]
        test += " ".join(map(str, nums)) + "\n"

        # Run the test
        start = timeit.default_timer()
        d = Ling(test)
        calc = timeit.default_timer()
        d.calculate()
        stop = timeit.default_timer()
        print("\nTimelimit Test: " +
              "{0:.3f}s (init {1:.3f}s calc {2:.3f}s)".
              format(stop-start, calc-start, stop-calc))

if __name__ == "__main__":

    # Avoiding recursion limitaions
    sys.setrecursionlimit(100000)

    if sys.argv[-1] == "-ut":
        unittest.main(argv=[" "])

    # Print the result string
    sys.stdout.write(Ling().calculate())


#!/usr/bin/env python3
# 667C_ling.py - Codeforces.com/problemset/problem/667/C by Sergey 2016

import unittest
import sys
from collections import deque

###############################################################################
# Ling Class (Main Program)
###############################################################################

class Ling:
    """ Ling representation """

    def __init__(self, test_inputs=None):
        """ Default constructor """

        it = iter(test_inputs.split("\n")) if test_inputs else None

        def uinput():
            return next(it) if it else sys.stdin.readline().rstrip()

        # Reading single elements
        self.s = uinput()

    def calculate(self):
        """ Main calcualtion function of the class """

        chars = list(self.s)
        slen = len(chars)
        result = set([])
        vis = set([])
        q = deque([(0, "")])
        while q:
            pos, prev = q.popleft()
            if pos in vis:
                continue
            pos2 = pos + 2
            if slen - pos2 > 4:
                new = str(chars[slen-1-pos-1]) + str(chars[slen-1-pos])
                if new != prev:
                    result.add(new)
                    q.append((pos2, new))
            pos3 = pos + 3
            if slen - pos3 > 4:
                new = (str(chars[slen-1-pos-2]) +
                       str(chars[slen-1-pos-1]) + str(chars[slen-1-pos]))
                if new != prev:
                    result.add(new)
                    q.append((pos3, new))

            vis.add(pos)

        return (str(len(result)) + "\n" + "\n".join(sorted(result))
                if result else "0")

###############################################################################
# Unit Tests
###############################################################################

class unitTests(unittest.TestCase):

    def test_single_test(self):
        """ Ling class testing """

        # Constructor test
        test = "abacabaca"
        d = Ling(test)
        self.assertEqual(d.s, "abacabaca")

        # Sample test
        self.assertEqual(Ling(test).calculate(), "3\naca\nba\nca")

        # Sample test
        test = "abaca"
        self.assertEqual(Ling(test).calculate(), "0")

        # My tests
        test = "fffffaafgfg"
        # self.assertEqual(Ling(test).calculate(), "0")

        # Time limit test
        # self.time_limit_test(5000)

    def time_limit_test(self, nmax):
        """ Timelimit testing """
        import random
        import timeit

        # Random inputs
        test = str(nmax) + " " + str(nmax) + "\n"
        numnums = [str(i) + " " + str(i+1) for i in range(nmax)]
        test += "\n".join(numnums) + "\n"
        nums = [random.randint(1, 10000) for i in range(nmax)]
        test += " ".join(map(str, nums)) + "\n"

        # Run the test
        start = timeit.default_timer()
        d = Ling(test)
        calc = timeit.default_timer()
        d.calculate()
        stop = timeit.default_timer()
        print("\nTimelimit Test: " +
              "{0:.3f}s (init {1:.3f}s calc {2:.3f}s)".
              format(stop-start, calc-start, stop-calc))

if __name__ == "__main__":

    # Avoiding recursion limitaions
    sys.setrecursionlimit(100000)

    if sys.argv[-1] == "-ut":
        unittest.main(argv=[" "])

    # Print the result string
    sys.stdout.write(Ling().calculate())


#!/usr/bin/env python3
# 667C_ling.py - Codeforces.com/problemset/problem/667/C by Sergey 2016

import unittest
import sys
from collections import deque

###############################################################################
# Ling Class (Main Program)
###############################################################################

class Ling:
    """ Ling representation """

    def __init__(self, test_inputs=None):
        """ Default constructor """

        it = iter(test_inputs.split("\n")) if test_inputs else None

        def uinput():
            return next(it) if it else sys.stdin.readline().rstrip()

        # Reading single elements
        self.s = uinput()

    def calculate(self):
        """ Main calcualtion function of the class """

        chars = list(self.s)
        slen = len(chars)
        result = set([])
        vis = set([])
        q = deque([0])
        while q:
            pos = q.popleft()
            if pos in vis:
                continue
            pos2 = pos + 2
            if slen - pos2 > 4:
                result.add(str(chars[slen-1-pos-1]) + str(chars[slen-1-pos]))
                q.append(pos2)
            pos3 = pos + 3
            if slen - pos3 > 4:
                result.add(str(chars[slen-1-pos-2]) +
                           str(chars[slen-1-pos-1]) + str(chars[slen-1-pos]))
                q.append(pos3)

            vis.add(pos)

        return (str(len(result)) + "\n" + "\n".join(sorted(result))
                if result else "0")

###############################################################################
# Unit Tests
###############################################################################

class unitTests(unittest.TestCase):

    def test_single_test(self):
        """ Ling class testing """

        # Constructor test
        test = "abacabaca"
        d = Ling(test)
        self.assertEqual(d.s, "abacabaca")

        # Sample test
        self.assertEqual(Ling(test).calculate(), "3\naca\nba\nca")

        # Sample test
        test = "abaca"
        self.assertEqual(Ling(test).calculate(), "0")

        # Sample test
        test = "xyzttgfgg"
        # self.assertEqual(Ling(test).calculate(), "0")

        # My tests
        test = ""
        # self.assertEqual(Ling(test).calculate(), "0")

        # Time limit test
        # self.time_limit_test(5000)

    def time_limit_test(self, nmax):
        """ Timelimit testing """
        import random
        import timeit

        # Random inputs
        test = str(nmax) + " " + str(nmax) + "\n"
        numnums = [str(i) + " " + str(i+1) for i in range(nmax)]
        test += "\n".join(numnums) + "\n"
        nums = [random.randint(1, 10000) for i in range(nmax)]
        test += " ".join(map(str, nums)) + "\n"

        # Run the test
        start = timeit.default_timer()
        d = Ling(test)
        calc = timeit.default_timer()
        d.calculate()
        stop = timeit.default_timer()
        print("\nTimelimit Test: " +
              "{0:.3f}s (init {1:.3f}s calc {2:.3f}s)".
              format(stop-start, calc-start, stop-calc))

if __name__ == "__main__":

    # Avoiding recursion limitaions
    sys.setrecursionlimit(100000)

    if sys.argv[-1] == "-ut":
        unittest.main(argv=[" "])

    # Print the result string
    sys.stdout.write(Ling().calculate())


import sys
input = sys.stdin.readline
from collections import *

s = input()[:-1]
n = len(s)
dp = [[False]*2 for _ in range(n+1)]
dp[n][0] = True
dp[n][1] = True
dp[n-2][0] = True
dp[n-3][1] = True

for i in range(n-4, -1, -1):
    if (dp[i+2][0] and i+4<=n and s[i:i+2]!=s[i+2:i+4]) or dp[i+2][1]:
        dp[i][0] = True

    if dp[i+3][0] or (dp[i+3][1] and i+6<=n and s[i:i+3]!=s[i+3:i+6]):
        dp[i][1] = True

ans = set()

for i in range(5, n):
    if i+2<=n and dp[i][0]:
        ans.add(s[i:i+2])

    if i+3<=n and dp[i][1]:
        ans.add(s[i:i+3])

ans = list(ans)
ans.sort()
print(len(ans))

for ans_i in ans:
    print(ans_i)


import sys
input = sys.stdin.readline
from collections import *

s = input()[:-1]
n = len(s)
dp = [False]*(n+1)
dp[n] = True
dp[n-2] = True
dp[n-3] = True

for i in range(n-4, -1, -1):
    if dp[i+2] and s[i:i+2]!=s[i+2:i+4]:
        dp[i] = True
    elif dp[i+3] and s[i:i+3]!=s[i+3:i+6]:
        dp[i] = True

ans = set()

for i in range(5, n):
    if i+2<=n and dp[i] and dp[i+2]:
        ans.add(s[i:i+2])

    if i+3<=n and dp[i] and dp[i+3]:
        ans.add(s[i:i+3])

ans = list(ans)
ans.sort()
print(len(ans))

for ans_i in ans:
    print(ans_i)


import sys
input = sys.stdin.readline

s = input()[:-1]
n = len(s)
dp = [[False]*2 for _ in range(n)]
dp[n-2][0] = True
dp[n-3][1] = True

for i in range(n-4, -1, -1):
    dp[i][0] = (dp[i+2][0] and s[i:i+2]!=s[i+2:i+4]) or dp[i+2][1]
    dp[i][1] = dp[i+3][0] or (dp[i+3][1] and s[i:i+3]!=s[i+3:i+6])

ans = set()

for i in range(5, n):
    if dp[i][0]:
        ans.add(s[i:i+2])

    if dp[i][1]:
        ans.add(s[i:i+3])

ans = list(ans)
ans.sort()
print(len(ans))

for ans_i in ans:
    print(ans_i)


import sys

s = input().rstrip()
n = len(s)
pos2, pos3, V = [False] * n, [False] * n, []
if n >= 7:
    pos2[n-2] = True
    V.append(s[n-2:])
if n >= 8:
    pos3[n-3] = True
    V.append(s[n-3:])
for i in range(n-4, 4, -1):
    if pos3[i+2] or pos2[i+2] and s[i : i+2] != s[i+2 : i+4]:
        pos2[i] = True
        V.append(s[i : i+2])
    if pos2[i+3] or pos3[i+3] and s[i : i+3] != s[i+3 : i+6]:
        pos3[i] = True
        V.append(s[i : i+3])

V.sort()
sys.stdout.write(str(len(V)) + '\n')
for v in V:
    sys.stdout.write(v + '\n')


import sys

s = input().rstrip()
n = len(s)
pos2, pos3, V = [False] * n, [False] * n, set()
if n >= 7:
    pos2[n-2] = True
    V.add(s[n-2:])
if n >= 8:
    pos3[n-3] = True
    V.add(s[n-3:])
for i in range(n-4, 4, -1):
    if pos3[i+2] or pos2[i+2] and s[i : i+2] != s[i+2 : i+4]:
        pos2[i] = True
        V.add(s[i : i+2])
    if pos2[i+3] or pos3[i+3] and s[i : i+3] != s[i+3 : i+6]:
        pos3[i] = True
        V.add(s[i : i+3])

sys.stdout.write(str(len(V)) + '\n')
for v in sorted(V):
    sys.stdout.write(v + '\n')


using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var s = cin.NextString();
            s = s.Substring(5);

            if (s.Length == 0)
            {
                Console.WriteLine(0);
                return;
            }

            var sets = new HashSet<string>[s.Length];

            var ans = new HashSet<string>();
            if (sets.Length >= 2)
            {
                var sub = s.Substring(s.Length - 2, 2);
                sets[sets.Length - 2] = new HashSet<string>(new[]{ sub});
                ans.Add(sub);
            }
            if (sets.Length >= 3)
            {
                var sub = s.Substring(s.Length - 3, 3);
                sets[sets.Length - 3] = new HashSet<string>(new[]{ sub });
                ans.Add(sub);
            }
            if (sets.Length >= 4)
            {
                var sub = s.Substring(s.Length - 4, 2);
                if (!sets[sets.Length - 2].Contains(sub))
                {
                    sets[sets.Length - 4] = new HashSet<string>(sets[sets.Length - 2]) {sub};
                    ans.Add(sub);
                }
            }

            for (var i = s.Length - 5; i >= 0; i--)
            {
                if (sets[i + 2] == null && sets[i + 3] == null)
                {
                    continue;
                }
                var two = s.Substring(i, 2);
                var three = s.Substring(i, 3);
                HashSet<string> set = null;
                if (sets[i + 2] != null && !sets[i + 2].Contains(two))
                {
                    ans.Add(two);
                    set = new HashSet<string>{ two };
                }
                if (sets[i + 3] != null && !sets[i + 3].Contains(three))
                {
                    ans.Add(three);
                    if (set == null)
                    {
                        set = new HashSet<string> {three};
                    }
                    else
                    {
                        set.Add(three);
                    }
                }
                sets[i] = set;
            }

            var result = ans.OrderBy(x => x).ToList();
            Console.WriteLine(result.Count);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var s = cin.NextString();
            s = s.Substring(5);

            if (s.Length == 0)
            {
                Console.WriteLine(0);
                return;
            }

            var sets = new HashSet<string>[s.Length];

            var ans = new HashSet<string>();
            if (sets.Length >= 2)
            {
                var sub = s.Substring(s.Length - 2, 2);
                sets[sets.Length - 2] = new HashSet<string>(new[]{ sub});
                ans.Add(sub);
            }
            if (sets.Length >= 3)
            {
                var sub = s.Substring(s.Length - 3, 3);
                sets[sets.Length - 3] = new HashSet<string>(new[]{ sub });
                ans.Add(sub);
            }
            if (sets.Length >= 4)
            {
                var sub = s.Substring(s.Length - 4, 2);
                if (!sets[sets.Length - 2].Contains(sub))
                {
                    sets[sets.Length - 4] = new HashSet<string>(sets[sets.Length - 2]) {sub};
                    ans.Add(sub);
                }
            }

            for (var i = s.Length - 5; i >= 0; i--)
            {
                if (sets[i + 2] == null && sets[i + 3] == null)
                {
                    continue;
                }
                var two = s.Substring(i, 2);
                var three = s.Substring(i, 3);
                HashSet<string> set = null;
                if (sets[i + 2] != null && (sets[i + 2].Count <= 1 || !sets[i + 2].Contains(two)))
                {
                    ans.Add(two);
                    set = new HashSet<string>{ two };
                }
                if (sets[i + 3] != null && (sets[i + 3].Count <= 1 || !sets[i + 3].Contains(three)))
                {
                    ans.Add(three);
                    if (set == null)
                    {
                        set = new HashSet<string> {three};
                    }
                    else
                    {
                        set.Add(three);
                    }
                }
                sets[i] = set;
            }

            var result = ans.OrderBy(x => x).ToList();
            Console.WriteLine(result.Count);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var s = cin.NextString();
            s = s.Substring(5);

            if (s.Length == 0)
            {
                Console.WriteLine(0);
                return;
            }

            var sets = new HashSet<string>[s.Length];

            var ans = new HashSet<string>();
            if (sets.Length >= 2)
            {
                var sub = s.Substring(s.Length - 2, 2);
                sets[sets.Length - 2] = new HashSet<string>(new[]{ sub});
                ans.Add(sub);
            }
            if (sets.Length >= 3)
            {
                var sub = s.Substring(s.Length - 3, 3);
                sets[sets.Length - 3] = new HashSet<string>(new[]{ sub });
                ans.Add(sub);
            }
            if (sets.Length >= 4)
            {
                var sub = s.Substring(s.Length - 4, 2);
                if (!sets[sets.Length - 2].Contains(sub))
                {
                    sets[sets.Length - 4] = new HashSet<string>(sets[sets.Length - 2]) {sub};
                    ans.Add(sub);
                }
            }

            for (var i = s.Length - 5; i >= 0; i--)
            {
                if (sets[i + 2] == null && sets[i + 3] == null)
                {
                    continue;
                }
                var two = s.Substring(i, 2);
                var three = s.Substring(i, 3);
                HashSet<string> set = null;
                if (sets[i + 2] != null && (sets[i + 2].Count > 1 || !sets[i + 2].Contains(two)))
                {
                    ans.Add(two);
                    set = new HashSet<string>{ two };
                }
                if (sets[i + 3] != null && (sets[i + 3].Count > 1 || !sets[i + 3].Contains(three)))
                {
                    ans.Add(three);
                    if (set == null)
                    {
                        set = new HashSet<string> {three};
                    }
                    else
                    {
                        set.Add(three);
                    }
                }
                sets[i] = set;
            }

            var result = ans.OrderBy(x => x).ToList();
            Console.WriteLine(result.Count);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var s = cin.NextString();
            s = s.Substring(5);

            if (s.Length == 0)
            {
                Console.WriteLine(0);
                return;
            }

            var sets = new HashSet<string>[s.Length];

            if (sets.Length >= 2)
            {
                sets[sets.Length - 2] = new HashSet<string>(new[]{ s.Substring(s.Length - 2, 2)});
            }
            if (sets.Length >= 3)
            {
                sets[sets.Length - 3] = new HashSet<string>(new[]{ s.Substring(s.Length - 3, 3)});
            }
            if (sets.Length >= 4)
            {
                var sub = s.Substring(s.Length - 4, 2);
                if (!sets[sets.Length - 2].Contains(sub))
                {
                    sets[sets.Length - 4] = new HashSet<string>(sets[sets.Length - 2]) {sub};
                }
            }

            for (var i = s.Length - 5; i > 0; i--)
            {
                if (sets[i + 2] == null || sets[i + 3] == null)
                {
                    continue;
                }
                var two = s.Substring(i, 2);
                var three = s.Substring(i, 3);
                HashSet<string> set = null;
                if (!sets[i + 2].Contains(two))
                {
                    set = new HashSet<string>(sets[i + 2]){ two};
                }
                if (!sets[i + 3].Contains(three))
                {
                    if (set == null)
                    {
                        set = new HashSet<string>(sets[i + 3]) {three};
                    }
                    else
                    {
                        var intersection = new HashSet<string>();
                        if (set.Contains(three))
                        {
                            intersection.Add(three);
                        }
                        foreach (var item in sets[i + 3])
                        {
                            if (set.Contains(item))
                            {
                                intersection.Add(item);
                            }
                        }
                        set = intersection;
                    }
                }
                sets[i] = set;
            }

            var all = new HashSet<string>();
            foreach (var set in sets)
            {
                if (set != null)
                {
                    foreach (var item in set)
                    {
                        all.Add(item);
                    }
                }
            }

            var result = all.OrderBy(x => x).ToList();
            Console.WriteLine(result.Count);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var s = cin.NextString();
            s = s.Substring(5);

            if (s.Length == 0)
            {
                Console.WriteLine(0);
                return;
            }

            var sets = new HashSet<string>[s.Length];

            var ans = new HashSet<string>();
            if (sets.Length >= 2)
            {
                var sub = s.Substring(s.Length - 2, 2);
                sets[sets.Length - 2] = new HashSet<string>(new[]{ sub});
                ans.Add(sub);
            }
            if (sets.Length >= 3)
            {
                var sub = s.Substring(s.Length - 3, 3);
                sets[sets.Length - 3] = new HashSet<string>(new[]{ sub });
                ans.Add(sub);
            }
            if (sets.Length >= 4)
            {
                var sub = s.Substring(s.Length - 4, 2);
                if (!sets[sets.Length - 2].Contains(sub))
                {
                    sets[sets.Length - 4] = new HashSet<string>(sets[sets.Length - 2]) {sub};
                    ans.Add(sub);
                }
            }

            for (var i = s.Length - 5; i >= 0; i--)
            {
                if (sets[i + 2] == null && sets[i + 3] == null)
                {
                    continue;
                }
                var two = s.Substring(i, 2);
                var three = s.Substring(i, 3);
                HashSet<string> set = null;
                if (sets[i + 2] != null && !sets[i + 2].Contains(two))
                {
                    ans.Add(two);
                    set = new HashSet<string>(sets[i + 2]){ two};
                }
                if (sets[i + 3] != null && !sets[i + 3].Contains(three))
                {
                    ans.Add(three);
                    if (set == null)
                    {
                        set = new HashSet<string>(sets[i + 3]) {three};
                    }
                    else
                    {
                        var intersection = new HashSet<string>();
                        if (set.Contains(three))
                        {
                            intersection.Add(three);
                        }
                        foreach (var item in sets[i + 3])
                        {
                            if (set.Contains(item))
                            {
                                intersection.Add(item);
                            }
                        }
                        set = intersection;
                    }
                }
                sets[i] = set;
            }

            var result = ans.OrderBy(x => x).ToList();
            Console.WriteLine(result.Count);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var s = cin.NextString();
            s = s.Substring(5);

            if (s.Length == 0)
            {
                Console.WriteLine(0);
                return;
            }

            var canVisit = new bool[s.Length];
            canVisit[canVisit.Length - 1] = true;

            var set = new HashSet<string>();

            for (var i = s.Length - 1; i > 0; i--)
            {
                if (canVisit[i] && i != s.Length - 2)
                {
                    for (var j = 2; j <= 3; j++)
                    {
                        var idx = i - j + 1;
                        if (idx >= 0)
                        {
                            var sub = s.Substring(idx, j);
                            if (!set.Contains(sub))
                            {
                                set.Add(sub);
                                canVisit[idx] = true;
                            }
                        }
                    }
                }
            }

            var result = set.OrderBy(x => x).ToList();
            Console.WriteLine(result.Count);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var s = cin.NextString();
            s = s.Substring(5);

            if (s.Length == 0)
            {
                Console.WriteLine(0);
                return;
            }

            var sets = new HashSet<string>[s.Length];

            var ans = new HashSet<string>();
            if (sets.Length >= 2)
            {
                var sub = s.Substring(s.Length - 2, 2);
                sets[sets.Length - 2] = new HashSet<string>(new[]{ sub});
                ans.Add(sub);
            }
            if (sets.Length >= 3)
            {
                var sub = s.Substring(s.Length - 3, 3);
                sets[sets.Length - 3] = new HashSet<string>(new[]{ sub });
                ans.Add(sub);
            }
            if (sets.Length >= 4)
            {
                var sub = s.Substring(s.Length - 4, 2);
                if (!sets[sets.Length - 2].Contains(sub))
                {
                    sets[sets.Length - 4] = new HashSet<string>(sets[sets.Length - 2]) {sub};
                    ans.Add(sub);
                }
            }

            for (var i = s.Length - 5; i >= 0; i--)
            {
                if (sets[i + 2] == null || sets[i + 3] == null)
                {
                    continue;
                }
                var two = s.Substring(i, 2);
                var three = s.Substring(i, 3);
                HashSet<string> set = null;
                if (!sets[i + 2].Contains(two))
                {
                    ans.Add(two);
                    set = new HashSet<string>(sets[i + 2]){ two};
                }
                if (!sets[i + 3].Contains(three))
                {
                    ans.Add(three);
                    if (set == null)
                    {
                        set = new HashSet<string>(sets[i + 3]) {three};
                    }
                    else
                    {
                        var intersection = new HashSet<string>();
                        if (set.Contains(three))
                        {
                            intersection.Add(three);
                        }
                        foreach (var item in sets[i + 3])
                        {
                            if (set.Contains(item))
                            {
                                intersection.Add(item);
                            }
                        }
                        set = intersection;
                    }
                }
                sets[i] = set;
            }

            var result = ans.OrderBy(x => x).ToList();
            Console.WriteLine(result.Count);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var s = cin.NextString();
            var uniqueTwo = new HashSet<string>();
            var uniqueThree = new HashSet<string>();
            for (var i = 5; i < s.Length; i++)
            {
                if (i + 2 <= s.Length && i + 2 != s.Length - 1)
                {
                    var two = s.Substring(i, 2);
                    uniqueTwo.Add(two);
                }
                if (i + 3 <= s.Length && i + 3 != s.Length - 1)
                {
                    var three = s.Substring(i, 3);
                    uniqueThree.Add(three);
                }
            }
            var set = uniqueTwo.Concat(uniqueThree).OrderBy(x => x).ToList();
            Console.WriteLine(set.Count);
            foreach (var item in set)
            {
                Console.WriteLine(item);
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CodeForces._666
{
    class Pa
    {
        static void Main(string[] args)
        {
            string s = Console.ReadLine();
            var result = new Dictionary<string, bool>();
            GetSuffixes(s, "", result, new Dictionary<string, bool>());
            Console.WriteLine(result.Count);
            var items = result.Keys.ToList();
            items.Sort();
            foreach(var item in items)
            {
                Console.WriteLine(item);
            }
        }

        static void GetSuffixes(string s, string last, Dictionary<string, bool> found, Dictionary<string, bool> visited)
        {
            var s2 = s.Substring(s.Length - 2);
            var s3 = s.Substring(s.Length - 3);
            var key = s + "___" + (s2 == last ? "t" : "f") + "___" + (s3 == last ? "t" : "f");
            if (visited.ContainsKey(key)) return;
            visited[key] = true;
            if (s.Length <= 6)
            {
                return;
            }

            if(s2 != last)
            {
                found[s2] = true;
                GetSuffixes(s.Substring(0, s.Length - 2), s2, found, visited);
            }
            if (s.Length > 7)
            {
                if(s3 != last)
                {
                    found[s3] = true;
                    GetSuffixes(s.Substring(0, s.Length - 3), s3, found, visited);
                }
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharp {
	class Program {
		static void Main(string[] args) {
			//string s = "abacaaa";
			HashSet<string> set = new HashSet<string>();
			String s = Console.ReadLine();

			bool[] b2, b3;
			b2 = new bool[s.Length];
			b3 = new bool[s.Length];

			int n = s.Length;
			for (int i = n - 2; i >= 5; i--) {
				string s2 = s.Substring(i, 2);
				if (i + 2 == n) {
					b2[i] = true;
					set.Add(s2);
				}
				else if (i <= n - 4) {
					if (i < n - 4) {
						if (b3[i + 2]) {
							b2[i] = true;
							if (!set.Contains(s2)) {
								set.Add(s2);
							}
						}
					}
					string ss2 = s.Substring(i + 2, 2);
					if (s2 != ss2) {
						if (b2[i + 2]) {
							b2[i] = true;
							if (!set.Contains(s2)) {
								set.Add(s2);
							}
						}
					}
				}

				if (i <= n - 3) {
					string s3 = s.Substring(i, 3);
					if (i + 3 == n) {
						b3[i] = true;
						set.Add(s3);
					}
					else if (i <= n - 5) {
						if (i < n - 5) {
							string ss3 = s.Substring(i + 3, 3);
							if (s3 != ss3) {
								if (b3[i + 3]) {
									b3[i] = true;
									if (!set.Contains(s3)) {
										set.Add(s3);
									}
								}
							}
						}
						if (b2[i + 3]) {
							b3[i] = true;
							if (!set.Contains(s3)) {
								set.Add(s3);
							}
						}
					}
				}
			}

			Console.WriteLine(set.Count);
			List<string> l = set.ToList();
			l.Sort();
			foreach (string str in l) {
				Console.WriteLine(str);
			}
		}
	}
}


using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Numerics;
using System.Text;

namespace Codeforces
{
    class Program : ProgramBase
    {
        private const long commonMod = 1000000007;
        static void Main(string[] args)
        {
            var p = new Program();
            var x = p.Get();
            p.Out(x);
        }

        object Get()
        {
            checked
            {
                var inp = Read();
                if (inp.Length < 7)
                    return 0;
                var tail = inp.Substring(5);
                var s = Reverse(tail);
                var hash = new HashSet<string>();
                hash.Add(s.Substring(0, 2));
                if (s.Length > 2)
                    hash.Add(s.Substring(0, 3));
                var current = 2;
                var stop = false;
                while (!stop)
                {
                    if (current + 1 < s.Length)
                    {
                        hash.Add(s.Substring(current, 2));
                        if (current + 2 < s.Length)
                            hash.Add(s.Substring(current, 3));
                    }
                    else
                        break;
                    current++;
                }
                return hash.Count + "\n" + hash.Select(x => Reverse(x)).OrderBy(x => x).JoinStrings("\n");

            }
        }

        public static string Reverse(string s)
        {
            char[] charArray = s.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }

        //object Get()
        //{
        //    checked
        //    {
        //        var inp = ReadInts();
        //        var n = inp[0];
        //        var q = inp[1];
        //        var queries = new int[q][];
        //        for (int i = 0; i < q; i++)
        //            queries[i] = ReadInts();
        //        var first = 0;
        //        var second = 1;
        //        foreach (var qq in queries)
        //        {
        //            if (qq[0] == 1)
        //            {
        //                first = (first + qq[1] + n) % n;
        //                second = (second + qq[1] + n) % n;
        //            }
        //            else
        //                if (first % 2 == 0)
        //                {
        //                    first = (first + 1 + n) % n;
        //                    second = (second - 1 + n) % n;
        //                }
        //                else
        //                {
        //                    first = (first - 1 + n) % n;
        //                    second = (second + 1 + n) % n;
        //                }
        //        }
        //        var result = new int[n];
        //        var current = first;
        //        for (int i = 0; i < n; i += 2)
        //            result[(first + i) % n] = i + 1;
        //        for (int i = 0; i < n; i += 2)
        //            result[(second + i) % n] = i + 1 + 1;
        //        return result.Select(x => x.ToString()).JoinStrings(" ");
        //    }
        //}

        class Automata
        {
            bool[] terminals;
            public int sigma;
            public int len;
            public int[,] jumps;

            public void Create()
            {
                var a = ReadInts();
                len = a[0];
                sigma = a[2];
                var ts = ReadInts();
                terminals = new bool[len];
                for (int i = 0; i < ts.Length; i++)
                    terminals[ts[i]] = true;
                jumps = new int[len, sigma];
                for (int i = 0; i < len*sigma; i++)
                {
                    var b = Console.ReadLine().Split(' ');
                    jumps[Convert.ToInt32(b[0]), b[1][0] - 'a'] = Convert.ToInt32(b[2]);
                }
            }
            protected int[] ReadInts()
            {
                return Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToArray();
            }

            public bool IsTerminal(int s)
            {
                return terminals[s];
            }
        }

        public double ProcessPair(long[] a, long[] b, int p)
        {
            return ((double)NumberOfDivs(a, p) * 2000) / Count(a) +
                ((double)NumberOfDivs(b, p) * 2000) / Count(b) -
                ((double)(NumberOfDivs(a, p) * NumberOfDivs(b, p))) * 2000 / (Count(a) * Count(b));
        }

        public long NumberOfDivs(long[] a, int p)
        {
            return a[1] / p - (a[0] - 1) / p;
        }

        public long Count(long[] a)
        {
            return a[1] - a[0] + 1;
        }

        bool DoubleEquals(double a, double b)
        {
            return Math.Abs(a - b) < 0.0000000001;
        }

        bool SameLine(double[] a, double[] b, double[] c)
        {
            var x = a[0];
            var y = a[1];
            var x1 = b[0];
            var y1 = b[1];
            var x2 = c[0];
            var y2 = c[1];
            return DoubleEquals((x - x1) * (y2 - y1), (y - y1) * (x2 - x1));
        }

        object Get7()
        {
            checked
            {
                var m = ReadInt();
                var p = ReadLongs();
                var arr = p.GroupBy(x => x).Select(g => new { g.Key, Count = g.Count() }).ToArray();
                var even = arr.Where(x => (x.Count & 1) == 0).FirstOrDefault();
                if (even != null)
                {
                    var index = Array.IndexOf(arr, even);
                    //arr[index].Count = arr[index].Count / 2;
                }
                long divs = 1;
                long result = 1;
                foreach (var a in arr)
                {
                    var pi = a.Key;
                    var curr = pi;
                    var olddivs = divs;
                    var oldres = result;
                    for (int i = 0; i < a.Count; i++)
                    {
                        result = (result * oldres % commonMod) * FastPow(curr, olddivs, commonMod) % commonMod;
                        curr = curr * pi % commonMod;
                        divs = (divs + olddivs) % (commonMod - 1);
                    }
                }
                return result;
            }
        }

        public long FastPow(long x, BigInteger pow, long mod)
        {
            if (pow == 0)
                return 1;
            if ((pow & 1) == 0)
                return FastPow(x * x % mod, pow / 2, mod);
            return x * FastPow(x, pow - 1, mod) % mod;
        }

        class Cut
        {
            public int a;
            public int b;
            public int line;
        }

        //object Get3()
        //{
        //    FileName = "";
        //    checked
        //    {
        //        var n = ReadInt();
        //        var hor = new List<Cut>();
        //        var ver = new List<Cut>();
        //        for (int i = 0; i < n; i++)
        //        {
        //            var a = ReadInts();
        //            if (a[0] == a[2])
        //                ver.Add(new Cut() { a = Math.Min(a[1], a[3]), b = Math.Max(a[1], a[3]), line = a[0] });
        //            else
        //                hor.Add(new Cut() { a = Math.Min(a[0], a[2]), b = Math.Max(a[0], a[2]), line = a[1] });
        //        }
        //        ver = Merge(ver);
        //        hor = Merge(hor);

        //    }
        //}

        List<Cut> Merge(List<Cut> l)
        {
            var a = l.OrderBy(x => x.line).ThenBy(x => x.a).ToArray();
            Cut previous = null;
            var result = new List<Cut>();
            for (int i = 0; i < a.Length; i++)
                if (previous == null)
                    previous = a[i];
                else
                    if (previous.line == a[i].line && previous.b >= a[i].a)
                        previous.b = Math.Max(previous.b, a[i].b);
                    else
                    {
                        result.Add(previous);
                        previous = a[i];
                    }
            if (previous != null)
                result.Add(previous);
            return result;
        }

    }
    abstract class ProgramBase
    {
        bool? prod = null;
        StreamReader f;
        protected string FileName { private get; set; }

        protected string Read()
        {
            if (string.IsNullOrEmpty(FileName))
                return Console.ReadLine();
            if (f == null)
                f = new StreamReader((GetProd() ? "" : "c:\\dev\\") + FileName);
            return f.ReadLine();
        }

        protected int ReadInt()
        {
            return Convert.ToInt32(Read());
        }
        protected int[] ReadInts()
        {
            return Read().Split(' ').Select(x => Convert.ToInt32(x)).ToArray();
        }

        protected long ReadLong()
        {
            return Convert.ToInt64(Read());
        }

        protected long[] ReadLongs()
        {
            return Read().Split(' ').Select(x => Convert.ToInt64(x)).ToArray();
        }

        public void Out(object r)
        {
            if (string.IsNullOrEmpty(FileName))
                Console.WriteLine(r);
            else if (GetProd())
                //File.WriteAllText(FileName, r.ToString());
                File.WriteAllText("output.txt", r.ToString());
            else
                Console.WriteLine(r);
        }

        private bool GetProd()
        {
            if (!prod.HasValue)
                try
                {
                    prod = Environment.MachineName != "RENADEEN-NB-W7";
                }
                catch (Exception)
                {
                    prod = true;
                }
            return prod.Value;
        }
    }

    public static class Huj
    {
        public static T MinBy<T>(this IEnumerable<T> source, Func<T, double> func) where T : class
        {
            T result = null;
            var min = double.MaxValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (min > current)
                {
                    min = current;
                    result = item;
                }
            }
            return result;
        }

        public static T MaxBy<T>(this IEnumerable<T> source, Func<T, double> func)
        {
            T result = default(T);
            var max = double.MinValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (max < current)
                {
                    max = current;
                    result = item;
                }
            }
            return result;
        }

        public static string JoinStrings(this IEnumerable<string> source, string delimeter)
        {
            return string.Join(delimeter, source.ToArray());
        }
    }
}


using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Numerics;
using System.Text;

namespace Codeforces
{
    class Program : ProgramBase
    {
        private const long commonMod = 1000000007;
        static void Main(string[] args)
        {
            var p = new Program();
            var x = p.Get();
            p.Out(x);
        }

        object Get()
        {
            checked
            {
                var inp = Read();
                if (inp.Length < 7)
                    return 0;
                var s = inp.Substring(5);
                var hash = new HashSet<string>();
                //hash.Add(s.Substring(0, 2));
                //if (s.Length > 2)
                //    hash.Add(s.Substring(0, 3));
                //while (current + 1 < s.Length)
                //{
                //    hash.Add(s.Substring(current, 2));
                //    if (current + 2 < s.Length)
                //        hash.Add(s.Substring(current, 3));
                //    current++;
                //}
                var allowed2 = new bool[s.Length];
                var allowed3 = new bool[s.Length];
                allowed2[s.Length - 1] = false;
                allowed3[s.Length - 1] = false;
                allowed2[s.Length - 2] = true;
                allowed3[s.Length - 2] = false;
                for (int i = s.Length - 3; i >= 0; i--)
                {
                    if (i + 3 == s.Length){
                        allowed2[i] = false;
                        allowed3[i] = true;
                    }
                    else {
                        if (allowed3[i + 2] || allowed2[i + 2] && (s[i] != s[i + 2] || s[i + 1] != s[i + 3]))
                            allowed2[i] = true;
                        else
                            allowed2[i] = false;

                        if (allowed2[i + 3] || allowed3[i + 3] && (s[i] != s[i + 3] || s[i + 1] != s[i + 4] || s[i + 2] != s[i + 5]))
                            allowed3[i] = true;
                        else
                            allowed3[i] = false;
                    }
                }
                for (int i = 0; i < s.Length; i++)
                {
                    if (allowed2[i])
                        hash.Add(s.Substring(i, 2));
                    if (allowed3[i])
                        hash.Add(s.Substring(i, 3));
                }
                return hash.Count + "\n" + hash.OrderBy(x => x).JoinStrings("\n");
            }

        }

        public static string Reverse(string s)
        {
            char[] charArray = s.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }

        //object Get()
        //{
        //    checked
        //    {
        //        var inp = ReadInts();
        //        var n = inp[0];
        //        var q = inp[1];
        //        var queries = new int[q][];
        //        for (int i = 0; i < q; i++)
        //            queries[i] = ReadInts();
        //        var first = 0;
        //        var second = 1;
        //        foreach (var qq in queries)
        //        {
        //            if (qq[0] == 1)
        //            {
        //                first = (first + qq[1] + n) % n;
        //                second = (second + qq[1] + n) % n;
        //            }
        //            else
        //                if (first % 2 == 0)
        //                {
        //                    first = (first + 1 + n) % n;
        //                    second = (second - 1 + n) % n;
        //                }
        //                else
        //                {
        //                    first = (first - 1 + n) % n;
        //                    second = (second + 1 + n) % n;
        //                }
        //        }
        //        var result = new int[n];
        //        var current = first;
        //        for (int i = 0; i < n; i += 2)
        //            result[(first + i) % n] = i + 1;
        //        for (int i = 0; i < n; i += 2)
        //            result[(second + i) % n] = i + 1 + 1;
        //        return result.Select(x => x.ToString()).JoinStrings(" ");
        //    }
        //}

        class Automata
        {
            bool[] terminals;
            public int sigma;
            public int len;
            public int[,] jumps;

            public void Create()
            {
                var a = ReadInts();
                len = a[0];
                sigma = a[2];
                var ts = ReadInts();
                terminals = new bool[len];
                for (int i = 0; i < ts.Length; i++)
                    terminals[ts[i]] = true;
                jumps = new int[len, sigma];
                for (int i = 0; i < len*sigma; i++)
                {
                    var b = Console.ReadLine().Split(' ');
                    jumps[Convert.ToInt32(b[0]), b[1][0] - 'a'] = Convert.ToInt32(b[2]);
                }
            }
            protected int[] ReadInts()
            {
                return Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToArray();
            }

            public bool IsTerminal(int s)
            {
                return terminals[s];
            }
        }

        public double ProcessPair(long[] a, long[] b, int p)
        {
            return ((double)NumberOfDivs(a, p) * 2000) / Count(a) +
                ((double)NumberOfDivs(b, p) * 2000) / Count(b) -
                ((double)(NumberOfDivs(a, p) * NumberOfDivs(b, p))) * 2000 / (Count(a) * Count(b));
        }

        public long NumberOfDivs(long[] a, int p)
        {
            return a[1] / p - (a[0] - 1) / p;
        }

        public long Count(long[] a)
        {
            return a[1] - a[0] + 1;
        }

        bool DoubleEquals(double a, double b)
        {
            return Math.Abs(a - b) < 0.0000000001;
        }

        bool SameLine(double[] a, double[] b, double[] c)
        {
            var x = a[0];
            var y = a[1];
            var x1 = b[0];
            var y1 = b[1];
            var x2 = c[0];
            var y2 = c[1];
            return DoubleEquals((x - x1) * (y2 - y1), (y - y1) * (x2 - x1));
        }

        object Get7()
        {
            checked
            {
                var m = ReadInt();
                var p = ReadLongs();
                var arr = p.GroupBy(x => x).Select(g => new { g.Key, Count = g.Count() }).ToArray();
                var even = arr.Where(x => (x.Count & 1) == 0).FirstOrDefault();
                if (even != null)
                {
                    var index = Array.IndexOf(arr, even);
                    //arr[index].Count = arr[index].Count / 2;
                }
                long divs = 1;
                long result = 1;
                foreach (var a in arr)
                {
                    var pi = a.Key;
                    var curr = pi;
                    var olddivs = divs;
                    var oldres = result;
                    for (int i = 0; i < a.Count; i++)
                    {
                        result = (result * oldres % commonMod) * FastPow(curr, olddivs, commonMod) % commonMod;
                        curr = curr * pi % commonMod;
                        divs = (divs + olddivs) % (commonMod - 1);
                    }
                }
                return result;
            }
        }

        public long FastPow(long x, BigInteger pow, long mod)
        {
            if (pow == 0)
                return 1;
            if ((pow & 1) == 0)
                return FastPow(x * x % mod, pow / 2, mod);
            return x * FastPow(x, pow - 1, mod) % mod;
        }

        class Cut
        {
            public int a;
            public int b;
            public int line;
        }

        //object Get3()
        //{
        //    FileName = "";
        //    checked
        //    {
        //        var n = ReadInt();
        //        var hor = new List<Cut>();
        //        var ver = new List<Cut>();
        //        for (int i = 0; i < n; i++)
        //        {
        //            var a = ReadInts();
        //            if (a[0] == a[2])
        //                ver.Add(new Cut() { a = Math.Min(a[1], a[3]), b = Math.Max(a[1], a[3]), line = a[0] });
        //            else
        //                hor.Add(new Cut() { a = Math.Min(a[0], a[2]), b = Math.Max(a[0], a[2]), line = a[1] });
        //        }
        //        ver = Merge(ver);
        //        hor = Merge(hor);

        //    }
        //}

        List<Cut> Merge(List<Cut> l)
        {
            var a = l.OrderBy(x => x.line).ThenBy(x => x.a).ToArray();
            Cut previous = null;
            var result = new List<Cut>();
            for (int i = 0; i < a.Length; i++)
                if (previous == null)
                    previous = a[i];
                else
                    if (previous.line == a[i].line && previous.b >= a[i].a)
                        previous.b = Math.Max(previous.b, a[i].b);
                    else
                    {
                        result.Add(previous);
                        previous = a[i];
                    }
            if (previous != null)
                result.Add(previous);
            return result;
        }

    }
    abstract class ProgramBase
    {
        bool? prod = null;
        StreamReader f;
        protected string FileName { private get; set; }

        protected string Read()
        {
            if (string.IsNullOrEmpty(FileName))
                return Console.ReadLine();
            if (f == null)
                f = new StreamReader((GetProd() ? "" : "c:\\dev\\") + FileName);
            return f.ReadLine();
        }

        protected int ReadInt()
        {
            return Convert.ToInt32(Read());
        }
        protected int[] ReadInts()
        {
            return Read().Split(' ').Select(x => Convert.ToInt32(x)).ToArray();
        }

        protected long ReadLong()
        {
            return Convert.ToInt64(Read());
        }

        protected long[] ReadLongs()
        {
            return Read().Split(' ').Select(x => Convert.ToInt64(x)).ToArray();
        }

        public void Out(object r)
        {
            if (string.IsNullOrEmpty(FileName))
                Console.WriteLine(r);
            else if (GetProd())
                //File.WriteAllText(FileName, r.ToString());
                File.WriteAllText("output.txt", r.ToString());
            else
                Console.WriteLine(r);
        }

        private bool GetProd()
        {
            if (!prod.HasValue)
                try
                {
                    prod = Environment.MachineName != "RENADEEN-NB-W7";
                }
                catch (Exception)
                {
                    prod = true;
                }
            return prod.Value;
        }
    }

    public static class Huj
    {
        public static T MinBy<T>(this IEnumerable<T> source, Func<T, double> func) where T : class
        {
            T result = null;
            var min = double.MaxValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (min > current)
                {
                    min = current;
                    result = item;
                }
            }
            return result;
        }

        public static T MaxBy<T>(this IEnumerable<T> source, Func<T, double> func)
        {
            T result = default(T);
            var max = double.MinValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (max < current)
                {
                    max = current;
                    result = item;
                }
            }
            return result;
        }

        public static string JoinStrings(this IEnumerable<string> source, string delimeter)
        {
            return string.Join(delimeter, source.ToArray());
        }
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

//using Algorithms.Set_43;

public class Program
{
    private class Tokenizer
    {
        private string currentString = null;

        private string[] tokens = null;

        private int tokenNumber = 0;

        private static readonly char[] Separators = { ' ' };

        public T NextToken<T>(Func<string, T> parser)
        {
            return parser(this.GetNextToken());
        }

        public string NextToken()
        {
            return this.GetNextToken();
        }

        public int NextInt()
        {
            return this.NextToken(int.Parse);
        }

        public long NextLong()
        {
            return this.NextToken(long.Parse);
        }

        private string GetNextToken()
        {
            if (this.currentString == null || this.tokenNumber == this.tokens.Length)
            {
                this.currentString = this.GetNextString();

                while (this.currentString != null && this.currentString.Equals(string.Empty))
                {
                    this.currentString = this.GetNextString();
                }

                if (this.currentString == null)
                {
                    throw new Exception("End of input");
                }

                this.tokens = this.currentString.Split(Separators, StringSplitOptions.RemoveEmptyEntries);
                this.tokenNumber = 0;
            }

            return this.tokens[this.tokenNumber++];
        }

        private string GetNextString()
        {
            string content = Console.ReadLine();
            if (content == null)
            {
                return null;
            }

            return content.Trim();
        }
    }

    class Linguistics
    {
        public static List<string> Solve(string s)
        {
            int n = s.Length;
            bool[] can2 = new bool[n];
            bool[] can3 = new bool[n];

            for (int i = 0; i < n; i++)
            {
                can2[i] = false;
                can3[i] = false;
            }

            can2[n - 2] = true;
            can3[n - 3] = true;

            for (int i = n - 1; i >= 5; i--)
            {
                if (can2[i] == true)
                {
                    can3[i - 3] = true;

                    if (Compare(s, i - 2, i, 2))
                    {
                        can2[i - 2] = true;
                    }
                }

                if (can3[i] == true)
                {
                    can2[i - 2] = true;

                    if (Compare(s, i - 3, i, 3))
                    {
                        can3[i - 3] = true;
                    }
                }
            }

            TrieNode trie = new TrieNode();
            for (int i = 5; i < n; i++)
            {
                if (can2[i])
                {
                    Add(s, i, 2, trie);
                }

                if (can3[i])
                {
                    Add(s, i, 3, trie);
                }
            }

            List<string> list = new List<string>();
            StringBuilder sb = new StringBuilder();
            trie.Visit(sb, list);

            return list;
        }

        private static bool Compare(string s, int start1, int start2, int length)
        {
            for (int i = 0; i < length; i++)
            {
                if (s[start1 + i] != s[start2 + i])
                {
                    return true;
                }
            }

            return false;
        }

        private static void Add(string s, int start, int length, TrieNode rootNode)
        {
            TrieNode currentNode = rootNode;
            for (int i = 0; i < length; i++)
            {
                currentNode = currentNode.GoNext(s[start + i]);
            }

            currentNode.Finish = true;
        }

        private class TrieNode
        {
            private SortedDictionary<char, TrieNode> next;

            public TrieNode()
            {
                this.next = new SortedDictionary<char, TrieNode>();
            }

            public bool Finish { get; set; }

            public TrieNode GoNext(char c)
            {
                if (!this.next.ContainsKey(c))
                {
                    this.next[c] = new TrieNode();
                }

                return this.next[c];
            }

            public void Visit(StringBuilder sb, List<string> list)
            {
                if (this.Finish)
                {
                    list.Add(sb.ToString());
                }

                foreach (var keyValuePair in this.next)
                {
                    sb.Append(keyValuePair.Key);
                    keyValuePair.Value.Visit(sb, list);
                    sb.Remove(sb.Length - 1, 1);
                }
            }
        }
    }

    public static void Main()
    {
        Tokenizer tokenizer = new Tokenizer();

        string s = tokenizer.NextToken();

        List<string> list = Linguistics.Solve(s);
        Console.WriteLine(list.Count);
        foreach (string substring in list)
        {
            Console.WriteLine(substring);
        }
    }
}