Valya and Tolya are an ideal pair, but they quarrel sometimes. Recently, Valya took offense at her boyfriend because he came to her in t-shirt with lettering that differs from lettering on her pullover. Now she doesn't want to see him and Tolya is seating at his room and crying at her photos all day long.

This story could be very sad but fairy godmother (Tolya's grandmother) decided to help them and restore their relationship. She secretly took Tolya's t-shirt and Valya's pullover and wants to make the letterings on them same. In order to do this, for one unit of mana she can buy a spell that can change some letters on the clothes. Your task is calculate the minimum amount of mana that Tolya's grandmother should spend to rescue love of Tolya and Valya.

More formally, letterings on Tolya's t-shirt and Valya's pullover are two strings with same length n consisting only of lowercase English letters. Using one unit of mana, grandmother can buy a spell of form (c_1, c_2) (where c_1 and c_2 are some lowercase English letters), which can arbitrary number of times transform a single letter c_1 to c_2 and vise-versa on both Tolya's t-shirt and Valya's pullover. You should find the minimum amount of mana that grandmother should spend to buy a set of spells that can make the letterings equal. In addition you should output the required set of spells. 


-----Input-----

The first line contains a single integer n (1 ≤ n ≤ 10^5) — the length of the letterings.

The second line contains a string with length n, consisting of lowercase English letters — the lettering on Valya's pullover.

The third line contains the lettering on Tolya's t-shirt in the same format.


-----Output-----

In the first line output a single integer — the minimum amount of mana t required for rescuing love of Valya and Tolya.

In the next t lines output pairs of space-separated lowercase English letters — spells that Tolya's grandmother should buy. Spells and letters in spells can be printed in any order.

If there are many optimal answers, output any.


-----Examples-----
Input
3
abb
dad

Output
2
a d
b a
Input
8
drpepper
cocacola

Output
7
l e
e d
d c
c p
p o
o r
r a



-----Note-----

In first example it's enough to buy two spells: ('a','d') and ('b','a'). Then first letters will coincide when we will replace letter 'a' with 'd'. Second letters will coincide when we will replace 'b' with 'a'. Third letters will coincide when we will at first replace 'b' with 'a' and then 'a' with 'd'.

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Graph algorithms

Graph traversal

String algorithms

Greedy algorithms

Spanning trees


Solutions:
from random import getrandbits
p = []

def get(v):
	nonlocal p
	if p[v] == v:
		return v
	p[v] = get(p[v])
	return p[v]

def unite(u, v):
	nonlocal p
	(u, v) = (get(u), get(v))
	if u == v:
		return False
	if getrandbits(1):
		(u, v) = (v, u)
	p[u] = v
	return True

def main():
	n = int(input())
	nonlocal p
	p = list(range(26))
	s = input()
	t = input()
	ans = []
	for (i, x) in enumerate(zip(s, t)):
		(a, b) = x
		if unite(ord(a) - ord('a'), ord(b) - ord('a')):
			ans.append((a, b))
	print(len(ans))
	for x in ans:
		print(*x)

def __starting_point():
	main()
__starting_point()


num = int(input())
s1 = input().strip('\n')
alp = [{'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, {'g'}, {'h'}, {'i'}, {'j'}, {'k'}, {'l'}, {'m'}, {'n'}, {'o'}, {'p'}, {'q'}, {'r'}, {'s'}, {'t'}, {'u'}, {'v'}, {'w'}, {'x'}, {'y'}, {'z'}]
s2 = input().strip('\n')
tot = 0
l = []
for i in range(0, num):
	x = s1[i]
	y = s2[i]
	xn = ord(x) - 97
	yn = ord(y) - 97
	if not x in alp[yn]:
		tot = tot + 1
		l.append(x + ' ' + y)
		un = alp[xn].union(alp[yn])
		for e in un:
			alp[ord(e) - 97] = un
print(tot)
for i in l:
	print(i)


length = int(input())
s1 = input()
s2 = input()
connect = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}]
tot = 0
spells = []
for i in range(0, length):
	l1 = ord(s1[i]) - 97
	l2 = ord(s2[i]) - 97
	if not l1 in connect[l2]:
		tot = tot + 1
		spells.append(s1[i] + ' ' + s2[i])
		x = connect[l1].union(connect[l2])
		connect[l1] = x
		connect[l2] = x
		for i in connect[l1]:
			connect[i] = connect[i].union(connect[l1])
print(str(tot))
for i in spells:
	print(i)


from collections import defaultdict
from queue import Queue
IS_WAY_CACHE = set()

def read_nums():
	return [int(x) for x in input().split()]

def is_way(char_map, ch1, ch2):
	global IS_WAY_CACHE
	q = Queue()
	q.put(ch1)
	visited = {ch1}
	while not q.empty():
		cur_node = q.get()
		if cur_node == ch2:
			return True
		visited.add(cur_node)
		neighbours = char_map[cur_node]
		for n in neighbours:
			IS_WAY_CACHE.add((ch1, n))
			if n not in visited:
				q.put(n)
	return False

def is_way_cache(ch1, ch2):
	return (ch1, ch2) in IS_WAY_CACHE

def main():
	input()
	(one, two) = (input(), input())
	char_map = defaultdict(set)
	res = []
	for (ch1, ch2) in zip(one, two):
		if ch1 == ch2:
			continue
		if is_way_cache(ch1, ch2):
			continue
		if is_way_cache(ch2, ch1):
			continue
		if is_way(char_map, ch1, ch2):
			continue
		if is_way(char_map, ch2, ch1):
			continue
		res.append((ch1, ch2))
		char_map[ch1].add(ch2)
		char_map[ch2].add(ch1)
	print(len(res))
	for (ch1, ch2) in res:
		print(ch1, ch2)
main()


import math, sys, bisect, heapq, os
from collections import defaultdict, Counter, deque
from itertools import groupby, accumulate
from functools import lru_cache
int1 = lambda x: int(x) - 1

def input():
	return sys.stdin.readline().rstrip('\r\n')
aj = lambda : list(map(int, input().split()))

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def Y(c):
	print(['NO', 'YES'][c])

def y(c):
	print(['no', 'yes'][c])

def Yy(c):
	print(['No', 'Yes'][c])

def solve():

	def find(a):
		if par[a] < 0:
			return a
		par[a] = find(par[a])
		return par[a]

	def merge(a, b):
		if a != b:
			par[a] += par[b]
			par[b] = a
	(n,) = aj()
	s = input()
	t = input()
	par = [-1 for i in range(26)]
	Ans = []
	for (i, j) in zip(s, t):
		if i != j:
			a = ord(i) - ord('a')
			b = ord(j) - ord('a')
			aa = find(a)
			bb = find(b)
			if aa != bb:
				merge(aa, bb)
				Ans.append((i, j))
	print(len(Ans))
	for (i, j) in Ans:
		print(i, j)
try:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
except:
	pass
solve()


import sys, os, io
from sys import stdin
from math import log, gcd, ceil
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import math
alphabets = list('abcdefghijklmnopqrstuvwxyz')

def isPrime(x):
	for i in range(2, x):
		if i * i > x:
			break
		if x % i == 0:
			return False
	return True

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(int(i))
			n = n / i
	if n > 2:
		l.append(n)
	return list(set(l))

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime

def countdig(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def si():
	return input()

def prefix_sum(arr):
	r = [0] * (len(arr) + 1)
	for (i, el) in enumerate(arr):
		r[i + 1] = r[i] + el
	return r

def divideCeil(n, x):
	if n % x == 0:
		return n // x
	return n // x + 1

def ii():
	return int(input())

def li():
	return list(map(int, input().split()))

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')

def power_set(L):
	cardinality = len(L)
	n = 2 ** cardinality
	powerset = []
	for i in range(n):
		a = bin(i)[2:]
		subset = []
		for j in range(len(a)):
			if a[-j - 1] == '1':
				subset.append(L[j])
		powerset.append(subset)
	powerset_orderred = []
	for k in range(cardinality + 1):
		for w in powerset:
			if len(w) == k:
				powerset_orderred.append(w)
	return powerset_orderred

def fastPlrintNextLines(a):
	print('\n'.join(map(str, a)))
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
t = 1
for _ in range(t):
	n = ii()
	v = list(si())
	tv = list(si())
	for i in range(n):
		v[i] = alphabets.index(v[i])
		tv[i] = alphabets.index(tv[i])
	parent = [i for i in range(26)]
	ans = []
	cnt = 0
	for i in range(n):
		if v[i] != tv[i]:
			pa = parent[v[i]]
			pb = parent[tv[i]]
			while parent[pa] != pa:
				pa = parent[pa]
			while parent[pb] != pb:
				pb = parent[pb]
			if pa == pb:
				continue
			else:
				ans.append([pa, pb])
				parent[pa] = pb
	print(len(ans))
	for i in ans:
		print(chr(i[0] + 97), chr(i[1] + 97))


class Union_Find:

	def __init__(self, value):
		self.parents = None
		self.value = None

	def find_parents(self):
		if self.parents == None:
			return self
		else:
			self.parents = self.parents.find_parents()
			return self.parents
n = int(input().strip())
s1 = input().strip()
s2 = input().strip()
dp = dict()
for i in s1:
	if i not in dp:
		dp[i] = Union_Find(i)
for (i, v) in enumerate(s2):
	if v not in dp:
		dp[v] = Union_Find(v)
	fr = dp[v].find_parents()
	to = dp[s1[i]].find_parents()
	if fr != to:
		fr.parents = to
ans = dict()
cnt = 0
for i in dp:
	now = dp[i].find_parents()
	if now in ans:
		ans[now].append(i)
		cnt += 1
	else:
		ans[now] = [i]
print(cnt)
for i in ans:
	for j in range(1, len(ans[i])):
		print(ans[i][j - 1], ans[i][j])


def find(u):
	if parent[u] == u:
		return u
	parent[u] = find(parent[u])
	return parent[u]

def union(a, b):
	u = parent[a]
	v = parent[b]
	if size[u] > size[v]:
		parent[v] = u
		size[u] += size[v]
	else:
		parent[u] = v
		size[v] += size[u]
n = int(input())
s = input()
t = input()
parent = [i for i in range(27)]
size = [1 for i in range(27)]
ans = 0
res = []
for j in range(n):
	(u, v) = (ord(s[j]) - 97, ord(t[j]) - 97)
	if find(u) != find(v):
		res.append([s[j], t[j]])
		ans += 1
		union(u, v)
print(ans)
for j in res:
	print(*j)


import sys
sys.setrecursionlimit(10 ** 9)

def dfs(edges, visited, ans, node):
	if node not in visited:
		visited.add(node)
		for kid in edges[node]:
			if kid not in visited:
				ans.append((node, kid))
				dfs(edges, visited, ans, kid)

def solve(edges):
	visited = set()
	ans = []
	for i in range(26):
		if chr(97 + i) not in visited:
			dfs(edges, visited, ans, chr(97 + i))
	return ans

def main():
	n = int(input())
	s1 = input()
	s2 = input()
	edges = {}
	for i in range(26):
		edges[chr(97 + i)] = []
	for i in range(n):
		if s1[i] != s2[i]:
			edges[s1[i]].append(s2[i])
			edges[s2[i]].append(s1[i])
	ans = solve(edges)
	print(len(ans))
	for i in ans:
		print(i[0], i[1])
main()


def getfather(x):
	if x == fa[x]:
		return x
	fa[x] = getfather(fa[x])
	return fa[x]
n = int(input())
s = list(input())
t = list(input())
fa = [_ for _ in range(26)]
ans = []
tot = 0
for i in range(n):
	x = ord(s[i]) - 97
	y = ord(t[i]) - 97
	fx = getfather(x)
	fy = getfather(y)
	if fx != fy:
		fa[fx] = fy
		tot += 1
		ans.append((chr(x + 97), chr(y + 97)))
print(tot)
for i in ans:
	print(i[0] + ' ' + i[1])


n = int(input())
s1 = input()
s2 = input()
l = len(s1)
c = 0
d = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
sit = [{'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, {'g'}, {'h'}, {'i'}, {'j'}, {'k'}, {'l'}, {'m'}, {'n'}, {'o'}, {'p'}, {'q'}, {'r'}, {'s'}, {'t'}, {'u'}, {'v'}, {'w'}, {'x'}, {'y'}, {'z'}]
pairs = []
for i in range(l):
	x = s1[i]
	y = s2[i]
	v1 = d[x]
	v2 = d[y]
	if x not in sit[v2] or y not in sit[v1]:
		temp = sit[v1].union(sit[v2])
		sit[v1] = temp
		sit[v2] = temp
		st = x + ' ' + y
		if st not in pairs:
			pairs.append(st)
		c = c + 1
		for letter in sit[v1]:
			v3 = d[letter]
			temp2 = sit[v1].union(sit[v3])
			sit[v3] = temp2
print(str(c))
for i in pairs:
	print(i)


class Node(object):

	def __init__(self, label):
		self.label = label
		self.par = self
		self.rank = 0

class DisjointSet(object):

	def __init__(self, n):
		self.n = n
		self.nodes = [Node(i) for i in range(n)]

	def find(self, u):
		if u == u.par:
			return u
		return self.find(u.par)

	def union(self, u, v):
		(u, v) = (self.find(u), self.find(v))
		if u == v:
			return False
		if u.rank > v.rank:
			(u, v) = (v, u)
		u.par = v
		if u.rank == v.rank:
			v.rank += 1
		return True

	def get_all_components(self):
		comps = [[] for _ in range(self.n)]
		for node in self.nodes:
			comps[self.find(node).label].append(node.label)
		comps = [i for i in comps if i]
		return comps

def solve(n, a, b):
	dsu = DisjointSet(26)
	for i in range(n):
		n1 = dsu.nodes[ord(a[i]) - ord('a')]
		n2 = dsu.nodes[ord(b[i]) - ord('a')]
		dsu.union(n1, n2)
	comps = dsu.get_all_components()
	ans = 26 - len(comps)
	rules = []
	for i in comps:
		if len(i) > 1:
			for j in range(1, len(i)):
				rules.append((chr(ord('a') + i[0]), chr(ord('a') + i[j])))
	return (ans, rules)
n = int(input())
a = input()
b = input()
(ans, rules) = solve(n, a, b)
print(ans)
for i in rules:
	(c1, c2) = i
	print(c1, c2)


from collections import defaultdict
adj_matrix = defaultdict(list)
n = int(input())
s1 = input()
s2 = input()
for i in range(n):
	if s1[i] != s2[i]:
		adj_matrix[s1[i]].append(s2[i])
		adj_matrix[s2[i]].append(s1[i])
visited = set()
mst = []
count = 0

def dfs_util(vertices):
	nonlocal count
	for vertex in adj_matrix[vertices]:
		if vertex not in visited:
			count += 1
			mst.append((vertices, vertex))
			visited.add(vertex)
			dfs_util(vertex)
for vertices in adj_matrix:
	if vertices not in visited:
		visited.add(vertices)
		dfs_util(vertices)
print(count)
for finds in mst:
	print(finds[0], finds[1])


def find_set(v):
	if v == pa[v]:
		return v
	pa[v] = find_set(pa[v])
	return pa[v]
n = int(input())
s1 = input()
s2 = input()
pa = [0] * 26
for i in range(26):
	pa[i] = i
ans1 = []
ans = 0
for i in range(n):
	a = find_set(ord(s1[i]) - 97)
	b = find_set(ord(s2[i]) - 97)
	if a != b:
		ans += 1
		ans1.append([chr(a + 97), chr(b + 97)])
		pa[b] = a
print(ans)
for i in ans1:
	print(*i)


def f(x):
	if data[x] != x:
		data[x] = f(data[x])
		return data[x]
	return x
n = int(input())
s = input()
t = input()
data = [i for i in range(26)]
for i in range(n):
	(a, b) = (f(ord(s[i]) - ord('a')), f(ord(t[i]) - ord('a')))
	if a != b:
		data[a] = b
ans = 0
for i in range(26):
	f(i)
for i in range(26):
	ans += max(0, data.count(i) - 1)
print(ans)
for i in range(26):
	ans = []
	for j in range(26):
		if data[j] == i:
			ans.append(chr(j + ord('a')))
	for j in range(len(ans) - 1):
		print(ans[j], ans[j + 1])


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

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		group_members = defaultdict(list)
		for member in range(self.n):
			group_members[self.find(member)].append(member)
		return group_members
n = int(input())
s = list(input().rstrip())
t = list(input().rstrip())
uf = UnionFind(26)
spell = []
for i in range(n):
	a = ord(s[i]) - ord('a')
	b = ord(t[i]) - ord('a')
	if not uf.same(a, b):
		spell.append([s[i], t[i]])
		uf.union(a, b)
print(len(spell))
for x in spell:
	print(*x)


n = int(input())
v = input()
t = input()
rank = [0] * 26
par = [i for i in range(26)]

def find(x):
	if par[x] == x:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def unite(x, y):
	x = find(x)
	y = find(y)
	if x == y:
		return
	if rank[x] > rank[y]:
		par[y] = x
	else:
		par[x] = y
		if rank[x] == rank[y]:
			rank[y] += 1

def same(x, y):
	return find(x) == find(y)
rec = []
num = 0
for i in range(n):
	(a, b) = (ord(v[i]) - ord('a'), ord(t[i]) - ord('a'))
	if not same(a - 1, b - 1):
		unite(a - 1, b - 1)
		rec.append((v[i], t[i]))
		num += 1
print(num)
for (p, q) in rec:
	print(p, q)


n = int(input())
(first, second) = (input(), input())
letters = {i: i for i in map(lambda i: chr(i), range(ord('a'), ord('z') + 1))}
for i in range(n):
	(s1, s2) = (first[i], second[i])
	if letters[s1] == letters[s2]:
		continue
	if s1 > s2:
		(s1, s2) = (s2, s1)
	(frm, to) = (letters[s2], letters[s1])
	for key in letters:
		if letters[key] == frm:
			letters[key] = to
result = []
for (k, v) in letters.items():
	if k != v:
		result.append((k, v))
print(len(result))
for r in result:
	print(f'{r[0]} {r[1]}')


from itertools import permutations as perm
from collections import *
from sys import stdin
from bisect import *
from heapq import *
from math import *
g = lambda : stdin.readline().strip()
gl = lambda : g().split()
gil = lambda : [int(var) for var in gl()]
gfl = lambda : [float(var) for var in gl()]
gcl = lambda : list(g())
gbs = lambda : [int(var) for var in g()]
mod = int(1000000000.0) + 7
inf = float('inf')
(n,) = gil()
(a, b) = (g(), g())
edges = set()
for i in range(n):
	if a[i] != b[i]:
		edges.add((a[i], b[i]))
		edges.add((b[i], a[i]))
dsu = list(range(26))
cnt = [1] * 26
ans = []

def getParent(x):
	while dsu[x] != x:
		x = dsu[x]
	return x
while edges:
	(ai, bi) = edges.pop()
	edges.remove((bi, ai))
	(x, y) = (ord(ai) - 97, ord(bi) - 97)
	(px, py) = (getParent(x), getParent(y))
	if px == py:
		continue
	ans.append((ai, bi))
	if cnt[px] >= cnt[py]:
		cnt[px] += cnt[py]
		dsu[py] = px
	else:
		cnt[py] += cnt[px]
		dsu[px] = py
print(len(ans))
if ans:
	for r in ans:
		print(*r)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from collections import Counter
import heapq
from collections import Counter
n = int(input())
parent = [-1] * 26

def find_parent(s):
	if parent[s] == -1:
		return s
	else:
		return find_parent(parent[s])
ans = []
s = input()
t = input()
for i in range(n):
	x_root = find_parent(ord(s[i]) - ord('a'))
	y_root = find_parent(ord(t[i]) - ord('a'))
	if x_root == y_root:
		continue
	else:
		parent[x_root] = y_root
		ans.append((s[i], t[i]))
print(len(ans))
for i in ans:
	print(*i)


from collections import defaultdict
n = int(input())
s1 = input().strip()
s2 = input().strip()
g = defaultdict(list)
tq = []
for i in range(n):
	ord1 = ord(s1[i]) - ord('a')
	ord2 = ord(s2[i]) - ord('a')
	g[ord1].append(ord2)
	tq.append(ord1)
	g[ord2].append(ord1)
vis = [0] * 26
ans = []
for i in tq:
	if vis[i] == 0:
		vis[i] = 1
		q = [i]
		while q:
			t = q.pop(0)
			for i in g[t]:
				if vis[i] == 0:
					vis[i] = 1
					ans.append((chr(t + 97), chr(i + 97)))
					q.append(i)
print(len(ans))
for i in ans:
	print(*i)


parent = [i for i in range(200)]

def fin(x):
	if parent[x] == x:
		return x
	x = parent[x]
	parent[x] = fin(x)
	return parent[x]
n = int(input())
a = input()
b = input()
lst = []
for i in range(0, n):
	x = ord(a[i]) - 48
	y = ord(b[i]) - 48
	u = fin(x)
	v = fin(y)
	if u != v:
		lst.append((ord(a[i]) - 48, ord(b[i]) - 48))
		parent[u] = v
print(len(lst))
for (i, j) in lst:
	print(chr(i + 48), chr(j + 48))


links = [{i} for i in range(26)]
spells = []
count = 0
n = int(input())
s1 = input()
s2 = input()
for i in range(0, n):
	n1 = ord(s1[i]) - 97
	n2 = ord(s2[i]) - 97
	if n1 != n2 and (not n2 in links[n1]):
		links[n1] = links[n1].union(links[n2])
		links[n2] = links[n2].union(links[n1])
		for j in links[n1]:
			if j != n1:
				links[j] = links[n1].union(links[j])
		count = count + 1
		spells.append(chr(97 + n1) + ' ' + chr(97 + n2))
print(count)
for i in spells:
	print(i)


n = int(input())
S = set()
Slovar = []
sviter = input()
futbol = input()
res = 0
Ans = []
for i in range(n):
	if sviter[i] != futbol[i]:
		if sviter[i] not in S and futbol[i] not in S:
			Slovar.append(sviter[i] + futbol[i])
			S.add(sviter[i])
			S.add(futbol[i])
			res += 1
			Ans.append([sviter[i], futbol[i]])
		elif sviter[i] in S and futbol[i] not in S:
			S.add(futbol[i])
			for j in range(len(Slovar)):
				if sviter[i] in Slovar[j]:
					Slovar[j] += futbol[i]
					res += 1
					Ans.append([sviter[i], futbol[i]])
					break
		elif sviter[i] not in S and futbol[i] in S:
			S.add(sviter[i])
			for j in range(len(Slovar)):
				if futbol[i] in Slovar[j]:
					Slovar[j] += sviter[i]
					res += 1
					Ans.append([sviter[i], futbol[i]])
					break
		elif sviter[i] in S and futbol[i] in S:
			for j in range(len(Slovar)):
				if futbol[i] in Slovar[j]:
					a = j
				if sviter[i] in Slovar[j]:
					b = j
			if a != b:
				Slovar[a] = Slovar[a] + Slovar[b]
				Slovar[b] = ''
				res += 1
				Ans.append([sviter[i], futbol[i]])
print(res)
for i in range(res):
	print(*Ans[i])


alph = __import__('string').ascii_lowercase
n = int(input())
s = input()
t = input()
dsu = {}
id = {}
ans = []
for i in range(26):
	id[alph[i]] = i
	dsu[i] = alph[i]

def unite(a, b):
	for i in dsu.pop(id[b]):
		id[i] = id[a]
		dsu[id[a]] += i

def cant(a, b):
	return id[a] != id[b]
for i in range(n):
	if cant(s[i], t[i]):
		ans.append((s[i], t[i]))
		unite(s[i], t[i])
print(len(ans))
for i in ans:
	print(*i)


n = int(input())
s1 = list(input())
s2 = list(input())
ans = []
for i in range(n):
	a = s1[i]
	b = s2[i]
	if a != b:
		ans.append([a, b])
		for i in range(n):
			if s1[i] == a:
				s1[i] = b
			if s2[i] == a:
				s2[i] = b
print(len(ans))
for i in ans:
	print(*i)


def initialize(arr, n):
	for i in range(n):
		arr.append(i)
	return arr

def root(arr, n):
	while arr[n] != n:
		n = arr[n]
	return n

def union(arr, a, b):
	arr[a] = arr[b]
n = int(input())
a = input()
b = input()
arr = initialize([], 26)
cnt = 0
ans = []
for i in range(n):
	a1 = ord(a[i]) - 97
	b1 = ord(b[i]) - 97
	x = root(arr, a1)
	y = root(arr, b1)
	if x != y:
		cnt += 1
		union(arr, x, y)
		ans.append([a[i], b[i]])
print(cnt)
for i in ans:
	print(i[0], i[1])


def find(x, parent, rank):
	if parent[x] != x:
		parent[x] = find(parent[x], parent, rank)
	return parent[x]

def union(x, y, parent, rank):
	xroot = parent[x]
	yroot = parent[y]
	if rank[xroot] < rank[yroot]:
		parent[xroot] = yroot
	elif rank[xroot] > rank[yroot]:
		parent[yroot] = xroot
	else:
		parent[yroot] = xroot
		rank[xroot] += 1
n = int(input())
str1 = input()
str2 = input()
hashd = dict()
rev = dict()
i = 0
k = 0
while i < len(str1):
	if str1[i] not in hashd:
		hashd[str1[i]] = k
		rev[k] = str1[i]
		k += 1
	i += 1
i = 0
while i < len(str2):
	if str2[i] not in hashd:
		hashd[str2[i]] = k
		rev[k] = str2[i]
		k += 1
	i += 1
rank = [0 for x in range(k)]
parent = [x for x in range(k)]
sums = 0
i = 0
arr1 = []
arr2 = []
while i < n:
	if find(hashd[str1[i]], parent, rank) != find(hashd[str2[i]], parent, rank):
		sums += 1
		union(hashd[str1[i]], hashd[str2[i]], parent, rank)
		arr1.append(str1[i])
		arr2.append(str2[i])
	i += 1
print(sums)
i = 0
while i < len(arr1):
	print(arr1[i] + ' ' + arr2[i])
	i += 1


from collections import defaultdict
length = int(input().strip())
s1 = input().strip()
s2 = input().strip()
adj = defaultdict(list)
nodes = set()
for (c1, c2) in zip(s1, s2):
	if c1 != c2:
		adj[c1].append(c2)
		adj[c2].append(c1)
		nodes.add(c1)
		nodes.add(c2)
v = set()
st = []

def dfs(n):
	v.add(n)
	for neighbor in adj[n]:
		if neighbor not in v:
			st.append((n, neighbor))
			dfs(neighbor)
for n in nodes:
	if n not in v:
		dfs(n)
print(len(st))
for pair in st:
	print(*pair)


class DisjSet:

	def __init__(self, n):
		self.rank = [1] * n
		self.parent = [i for i in range(n)]

	def find(self, x):
		if self.parent[x] != x:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def Union(self, x, y):
		xset = self.find(x)
		yset = self.find(y)
		if xset == yset:
			return
		if self.rank[xset] < self.rank[yset]:
			self.parent[xset] = yset
		elif self.rank[xset] > self.rank[yset]:
			self.parent[yset] = xset
		else:
			self.parent[yset] = xset
			self.rank[xset] = self.rank[xset] + 1
n = int(input())
a = input()
b = input()
m = {}
counter = 0
for i in range(n):
	if a[i] not in m:
		m[a[i]] = counter
		counter += 1
	if b[i] not in m:
		m[b[i]] = counter
		counter += 1
le = counter
m_r = {v: k for (k, v) in m.items()}
obj = DisjSet(le)
g = {}
for i in range(n):
	obj.Union(m[a[i]], m[b[i]])
for i in range(le):
	p = obj.find(i)
	if p not in g:
		g[p] = []
	g[p].append(i)
total = 0
for i in g:
	total = total + len(g[i]) - 1
print(total)
for i in g:
	for k in g[i]:
		if k != i:
			print(m_r[k], m_r[i])


N = int(input())
s1 = input()
l1 = list(str(s1))
s2 = input()
l2 = list(str(s2))
K = 0
l3 = list()
for i in range(N):
	if l1[i] != l2[i]:
		K += 1
		a = l1[i]
		b = l2[i]
		l3.append(a)
		l3.append(b)
		for k in range(i, N):
			if l1[k] == a:
				l1[k] = b
			if l2[k] == a:
				l2[k] = b
print(K)
for i in range(K):
	print(l3[2 * i], l3[2 * i + 1])


import sys
input = sys.stdin.readline
s = 'abcdefghijklmnopqrstuvwxyz'
rank = [0 for i in range(27)]

def find(a, i):
	if a[i] == i:
		return i
	else:
		a[i] = find(a, a[i])
		return a[i]

def union(a, x, y):
	xs = find(a, x)
	ys = find(a, y)
	if xs != ys:
		if rank[ys] > rank[xs]:
			(xs, ys) = (ys, xs)
		rank[xs] += 1
		a[ys] = xs
n = int(input())
a = list(input().rstrip())
b = list(input().rstrip())

def bo(i):
	return ord(i) - ord('a')
dsu = [i for i in range(27)]
for i in range(n):
	if a[i] != b[i]:
		union(dsu, bo(a[i]), bo(b[i]))
for i in range(27):
	dsu[i] = find(dsu, i)
f = {}
for i in range(27):
	if dsu[i] not in f:
		f[dsu[i]] = [i]
	else:
		f[dsu[i]].append(i)
g = []
for i in f:
	for j in f[i]:
		if j != i:
			g.append([s[j], s[i]])
print(len(g))
for i in g:
	print(*i)


n = int(input())
s1 = input()
s2 = input()
seps = [i for i in range(26)]
ranks = [1 for i in range(26)]
outs = []

def parent(a):
	global seps
	na = a
	while seps[na] != na:
		na = seps[na]
	na2 = a
	while seps[na2] != na2:
		(na2, seps[na2]) = (seps[na2], na)
	return na

def cons(a, b):
	return parent(a) == parent(b)

def union(a, b):
	global seps, ranks
	if cons(a, b):
		return
	(pa, pb) = (parent(a), parent(b))
	if ranks[pa] == ranks[pb]:
		ranks[pa] += 1
		seps[pb] = pa
	elif ranks[pa] < ranks[pb]:
		seps[pa] = pb
	else:
		seps[pb] = pa
i = 0
while i < n:
	if cons(ord(s1[i]) - 97, ord(s2[i]) - 97):
		i += 1
		continue
	else:
		outs.append((s1[i], s2[i]))
		union(ord(s1[i]) - 97, ord(s2[i]) - 97)
		i += 1
print(len(outs))
for u in outs:
	print(u[0], u[1])


(n, a, b) = (int(input()), list(input()), list(input()))
ans = []
count = 0
for i in range(n):
	if a[i] != b[i]:
		ans.append((a[i], b[i]))
		count += 1
		for j in range(i + 1, n):
			if a[j] == a[i]:
				a[j] = b[i]
			if b[j] == a[i]:
				b[j] = b[i]
print(count)
for each in ans:
	print(*each)


_ = input()
s = input()
t = input()
par = [i for i in range(26)]

def find(x):
	if par[x] != x:
		par[x] = find(par[x])
		return par[x]
	else:
		return x
for i in range(len(s)):
	(a, b) = (find(ord(s[i]) - 97), find(ord(t[i]) - 97))
	if a != b:
		par[a] = b
res = 0
for i in range(26):
	find(i)
for i in range(26):
	res += max(0, par.count(i) - 1)
print(res)
for i in range(26):
	d = []
	for j in range(26):
		if par[j] == i:
			d.append(chr(j + 97))
	for j in range(len(d) - 1):
		print(d[j], d[j + 1])


class Graph:

	def __init__(self):
		self.edges = {chr(i): [] for i in range(ord('a'), ord('z') + 1)}

	def addEdge(self, u, v):
		self.edges[u].append(v)
		self.edges[v].append(u)

	def dfs(self, u, visited, vertices):
		vertices.append(u)
		visited[ord(u) - ord('a')] = True
		for v in self.edges[u]:
			if visited[ord(v) - ord('a')] is False:
				self.dfs(v, visited, vertices)
		return vertices

	def connectedComponents(self):
		visited = [False] * 26
		cc = []
		for u in self.edges:
			if visited[ord(u) - ord('a')] is False and len(self.edges[u]):
				cc.append(self.dfs(u, visited, []))
		return cc

def cost(str1, str2):
	g = Graph()
	for i in range(len(str1)):
		if str1[i] != str2[i]:
			g.addEdge(str1[i], str2[i])
	ccs = g.connectedComponents()
	num_ccs = len(ccs)
	vertices = 0
	for i in range(num_ccs):
		vertices += len(ccs[i])
	print(vertices - num_ccs)
	for cc in ccs:
		for i in range(len(cc) - 1):
			print(cc[i], cc[i + 1])
n = int(input())
str1 = input()
str2 = input()
cost(str1, str2)


n = int(input())
s1 = input()
s2 = input()
from collections import defaultdict
g = defaultdict(list)
for i in s1:
	if i not in g:
		g[i] = []
for i in s2:
	if i not in g:
		g[i] = []

def fun(x1, x2):
	global flag
	visited[ord(x1) - ord('a')] = True
	if x1 == x2:
		flag = 1
		return
	else:
		for i in g[x1]:
			if visited[ord(i) - ord('a')] == False:
				fun(i, x2)
cnt = 0
final = []
for i in range(len(s1)):
	if s1[i] != s2[i]:
		flag = 0
		visited = [False for i in range(26)]
		fun(s1[i], s2[i])
		if flag == 0:
			g[s1[i]].append(s2[i])
			g[s2[i]].append(s1[i])
			final.append([s1[i], s2[i]])
			cnt = cnt + 1
print(cnt)
for i in final:
	print(*i)


def getAdjacencyDict(str1, str2):
	adjacencyDict = {}
	for i in range(len(str1)):
		if str1[i] == str2[i]:
			continue
		if str1[i] in adjacencyDict:
			adjacencyDict[str1[i]].append(str2[i])
		else:
			adjacencyDict[str1[i]] = [str2[i]]
		if str2[i] in adjacencyDict:
			adjacencyDict[str2[i]].append(str1[i])
		else:
			adjacencyDict[str2[i]] = [str1[i]]
	return adjacencyDict

def dfs(adjacencyDict, vertexes, prev, currVertex, visitedVertex, spells):
	visitedVertex.append(currVertex)
	vertexes.remove(currVertex)
	for neighbour in adjacencyDict[currVertex]:
		if neighbour != prev and neighbour not in visitedVertex:
			spells.append((currVertex, neighbour))
			dfs(adjacencyDict, vertexes, currVertex, neighbour, visitedVertex, spells)
	return spells

def spellsRequired(str1, str2):
	adjacencyDict = getAdjacencyDict(str1, str2)
	vertexes = list(adjacencyDict)
	spells = []
	visitedVertex = []
	while len(vertexes) != 0:
		dfs(adjacencyDict, vertexes, None, vertexes[0], visitedVertex, spells)
	return spells

def main():
	lenOfStr = int(input())
	str1 = input()
	str2 = input()
	spells = spellsRequired(str1, str2)
	print(len(spells))
	for (i, j) in spells:
		print(i, j)
main()


n = int(input())
a = input()
b = input()
vis = [0] * 26
edges = {}
for i in range(n):
	if a[i] != b[i]:
		if a[i] not in edges:
			edges[a[i]] = [b[i]]
		else:
			edges[a[i]].append(b[i])
		if b[i] not in edges:
			edges[b[i]] = [a[i]]
		else:
			edges[b[i]].append(a[i])
		vis[ord(a[i]) - ord('a')] = 1
		vis[ord(b[i]) - ord('a')] = 1
from collections import deque
ans = []
for i in edges.keys():
	if vis[ord(i) - ord('a')]:
		vis[ord(i) - ord('a')] = 0
		tans = [i]
		q = deque(i)
		while len(q):
			j = q.popleft()
			for k in edges[j]:
				if vis[ord(k) - ord('a')]:
					q.append(k)
					tans.append(k)
					vis[ord(k) - ord('a')] = 0
		for i in range(1, len(tans)):
			ans.append((tans[i], tans[i - 1]))
print(len(ans))
for i in ans:
	print(*i)


k = int(input())
dr = input()
mr = input()
aka = []
spell = 0
spellbook = []
for u in range(0, 26):
	aka.append({u})
for t in range(0, k):
	a = ord(dr[t]) - 97
	b = ord(mr[t]) - 97
	if aka[a] != aka[b]:
		spell = spell + 1
		spellbook.append(dr[t] + ' ' + mr[t])
		aka[a] = aka[a].union(aka[b])
		aka[b] = aka[a].union(aka[b])
		for i in aka[a]:
			aka[i] = aka[i].union(aka[a])
print(str(spell))
for i in range(0, len(spellbook)):
	print(spellbook[i])


n = int(input())
Valya = input()
Tolya = input()
spells = []
matches = []
alpha = {'a': {0}, 'b': {1}, 'c': {2}, 'd': {3}, 'e': {4}, 'f': {5}, 'g': {6}, 'h': {7}, 'i': {8}, 'j': {9}, 'k': {10}, 'l': {11}, 'm': {12}, 'n': {13}, 'o': {14}, 'p': {15}, 'q': {16}, 'r': {17}, 's': {18}, 't': {19}, 'u': {20}, 'v': {21}, 'w': {22}, 'x': {23}, 'y': {24}, 'z': {25}}
c = 0
c = 0
alp = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}]
for i in range(0, n):
	if Valya[i] != Tolya[i]:
		if ord(Valya[i]) - 97 not in alp[ord(Tolya[i]) - 97] and ord(Tolya[i]) - 97 not in alp[ord(Valya[i]) - 97]:
			d = alp[ord(Valya[i]) - 97].union(alp[ord(Tolya[i]) - 97])
			alp[ord(Valya[i]) - 97].clear()
			alp[ord(Valya[i]) - 97].update(d)
			alp[ord(Tolya[i]) - 97].clear()
			alp[ord(Tolya[i]) - 97].update(d)
			for j in alp[ord(Valya[i]) - 97]:
				if j != ord(Valya[i]) - 97:
					alp[j].clear()
					alp[j].update(alp[ord(Valya[i]) - 97])
			c = c + 1
			spells.append('' + Valya[i] + ' ' + Tolya[i])
print(c)
for k in range(0, len(spells)):
	print(spells[k])


def dfs(x):
	for s in range(1, cnt[x] + 1):
		if label[alp2[x][s]] == 0:
			label[alp2[x][s]] = label[x]
			dfs(alp2[x][s])
n = int(input())
a = input()
b = input()
l = n
alp = [0] * 27
alp2 = [0] * 27
cnt = [0] * 27
label = [-1] * 27
for i in range(27):
	alp[i] = [0] * 27
	alp2[i] = [0] * 27
for i in range(l):
	label[ord(a[i]) - ord('a') + 1] = 0
	label[ord(b[i]) - ord('a') + 1] = 0
cntlet = 0
for i in range(27):
	if label[i] == 0:
		cntlet += 1
for i in range(l):
	alp[ord(a[i]) - ord('a') + 1][ord(b[i]) - ord('a') + 1] = 1
	alp[ord(b[i]) - ord('a') + 1][ord(a[i]) - ord('a') + 1] = 1
for i in range(27):
	for j in range(i + 1, 27):
		if alp[i][j] == 1:
			cnt[i] += 1
			cnt[j] += 1
			alp2[i][cnt[i]] = j
			alp2[j][cnt[j]] = i
con = 0
for i in range(1, 27):
	if label[i] == 0:
		con += 1
		label[i] = con
		dfs(i)
print(cntlet - con)
for i in range(1, con + 1):
	for j in range(1, 27):
		if label[j] == i:
			break
	for k in range(j + 1, 27):
		if label[k] == i:
			print(chr(j - 1 + ord('a')), chr(k - 1 + ord('a')))


n = int(input())
string1 = input()
string2 = input()
pr = {}
ans = []
for i in range(0, 26):
	pr[i] = i

def find_set(v):
	if pr[v] == v:
		return v
	pr[v] = find_set(pr[v])
	return pr[v]

def union_set(x, y):
	pr[x] = y
	ans.append((x, y))
for i in range(len(string1)):
	connected_a = find_set(ord(string1[i]) - 97)
	connected_b = find_set(ord(string2[i]) - 97)
	if connected_a == connected_b:
		continue
	union_set(connected_a, connected_b)
print(len(ans))
for i in ans:
	print(chr(97 + i[0]), chr(97 + i[1]))


from sys import stdin, stdout
n = int(input())
a = input()
b = input()
adj = [set() for _ in range(26)]
for i in range(n):
	if a[i] == b[i]:
		continue
	x = ord(a[i]) - ord('a')
	y = ord(b[i]) - ord('a')
	adj[x].add(y)
	adj[y].add(x)
visit = [False] * 26

def dfs(u, res):
	if visit[u]:
		return
	visit[u] = True
	res.append(u)
	for v in adj[u]:
		if not visit[v]:
			dfs(v, res)
ans = []
for u in range(26):
	if not visit[u]:
		res = []
		dfs(u, res)
		for i in range(1, len(res)):
			x = chr(res[0] + ord('a'))
			y = chr(res[i] + ord('a'))
			ans.append((x, y))
print(len(ans))
for tu in ans:
	print(*tu)


from collections import defaultdict, deque

def Check_Path(a, b, G):
	visited = defaultdict(bool)
	queue = deque()
	queue.append(a)
	visited[a] = True
	while queue:
		n = queue.popleft()
		if n == b:
			return True
		for i in list(G[n]):
			if visited[i] == False:
				queue.append(i)
				visited[i] = True
	return False

def fun(s1, s2, G):
	name = defaultdict(bool)
	count = 0
	for i in range(x):
		a = s1[i]
		b = s2[i]
		if a in G and b not in G and (a != b):
			G[a].append(b)
			G[b].append(a)
			count += 1
		elif b in G and a not in G and (a != b):
			G[b].append(a)
			G[a].append(b)
			count += 1
		elif a not in G and b not in G and (a != b):
			G[a].append(b)
			G[b].append(a)
			count += 1
		elif not Check_Path(a, b, G) and a != b:
			G[a].append(b)
			G[b].append(a)
			count += 1
	print(count)
	Print_Vetices(G)

def Print_Vetices(G):
	check = defaultdict(bool)
	vertex = []
	for v in list(G):
		for c in G[v]:
			if check[v, c] == False and check[c, v] == False:
				vertex.append((v, c))
				check[v, c] = True
	for (i, j) in vertex:
		print(i, j)
x = int(input())
s1 = input()
s2 = input()
G = defaultdict(list)
fun(s1, s2, G)


from collections import defaultdict
d = defaultdict(list)
n = int(input())
s1 = input()
s2 = input()
for i in range(n):
	a = s1[i]
	b = s2[i]
	d[a].append(b)
	d[b].append(a)
vis = [0] * 26
ans = []
cnt = 0
for i in range(26):
	curr = chr(i + 97)
	if not vis[i]:
		q = [curr]
		vis[i] = 1
		comp = [curr]
		while q:
			t = q.pop(0)
			for adj in d[t]:
				if not vis[ord(adj) - 97]:
					vis[ord(adj) - 97] = 1
					comp.append(adj)
					q.append(adj)
		now = len(comp) - 1
		cnt += now
		if len(comp) > 1:
			for i in range(len(comp) - 1):
				ans.append([comp[i], comp[i + 1]])
print(cnt)
for i in range(cnt):
	print(*ans[i])


def wordcount(a, b):
	c = 0
	for i in range(0, len(a)):
		if b == a[i]:
			c = c + 1
	return c

def applyChange(a, ar):
	news = ''
	for i in range(0, len(a)):
		if a[i] == ar[0]:
			news = news + ar[1]
		else:
			news = news + a[i]
	return news
n = int(input())
Valya = input()
Tolya = input()
spells = []
for i in range(0, n):
	if Valya[i] != Tolya[i]:
		v = wordcount(Valya, Valya[i])
		t = wordcount(Tolya, Tolya[i])
		if v >= t:
			u = [Valya[i], Tolya[i]]
			spells.append(u)
			Valya = applyChange(Valya, u)
			Tolya = applyChange(Tolya, u)
		else:
			w = [Tolya[i], Valya[i]]
			spells.append(w)
			Valya = applyChange(Valya, w)
			Tolya = applyChange(Tolya, w)
print(len(spells))
for j in range(0, len(spells)):
	print(str(spells[j][0]) + ' ' + str(spells[j][1]))


def bfs(g, u, v):
	l = len(g)
	visited = [0] * 26
	q = []
	q.append(u)
	visited[u] = 1
	while q:
		t = q.pop(0)
		if t == v:
			return True
		for j in g[t]:
			if visited[j] == 0:
				q.append(j)
				visited[j] = 1
	return False
from collections import defaultdict as dd
n = int(input())
s1 = input()
s2 = input()
g = dd(list)
d1 = dict()
d2 = dict()
drr = []
frr = []
arr = 'abcdefghijklmnopqrstuvwxyz'
for i in range(26):
	d1[i] = arr[i]
for i in range(26):
	d2[arr[i]] = i
for i in range(n):
	if s1[i] != s2[i]:
		a = s1[i]
		b = s2[i]
		u = d2[a]
		v = d2[b]
		if bfs(g, u, v):
			continue
		else:
			g[u].append(v)
			g[v].append(u)
			drr.append(a)
			drr.append(b)
			frr.append(drr)
			drr = []
print(len(frr))
for i in frr:
	print(i[0], i[1])


N = int(input())
S = input().rstrip()
T = input().rstrip()

class DSU:

	def __init__(self, N):
		self.p = [i for i in range(N)]

	def find(self, u):
		if u == self.p[u]:
			return u
		self.p[u] = self.find(self.p[u])
		return self.p[u]

	def join(self, u, v):
		u = self.find(u)
		v = self.find(v)
		self.p[v] = u

	def same(self, u, v):
		return self.find(u) == self.find(v)
dsu = DSU(26)
ans = []
for (s, t) in zip(S, T):
	si = ord(s) - ord('a')
	ti = ord(t) - ord('a')
	if dsu.same(si, ti):
		continue
	dsu.join(si, ti)
	ans.append((s, t))
print(len(ans))
print('\n'.join(map(lambda x: f'{x[0]} {x[1]}', ans)))


n = int(input())
a = input()
b = input()
alpha = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
beta = [{'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, {'g'}, {'h'}, {'i'}, {'j'}, {'k'}, {'l'}, {'m'}, {'n'}, {'o'}, {'p'}, {'q'}, {'r'}, {'s'}, {'t'}, {'u'}, {'v'}, {'w'}, {'x'}, {'y'}, {'z'}]
arr = []
counter = 0
for i in range(n):
	x = a[i]
	y = b[i]
	d1 = alpha[x]
	d2 = alpha[y]
	if x not in beta[d2] or y not in beta[d1]:
		temp = beta[d2].union(beta[d1])
		beta[d1] = temp
		beta[d2] = temp
		s = x + ' ' + y
		if s not in arr:
			arr.append(s)
		counter = counter + 1
		for letter in beta[d1]:
			d3 = alpha[letter]
			temp2 = beta[d1].union(beta[d3])
			beta[d3] = temp2
print(str(counter))
for i in arr:
	print(i)


n = int(input())
a = input()
b = input()
f = lambda c: ord(c) - 97
g = lambda x: chr(97 + x)
fa = [i for i in range(26)]
get_fa = lambda x: x if fa[x] == x else get_fa(fa[x])
for i in range(n):
	child = f(b[i])
	father = get_fa(child)
	while child != father:
		child = fa[child]
	fa[child] = get_fa(f(a[i]))
print(sum((i != get_fa(i) for i in range(26))))
for i in range(26):
	l = i
	r = fa[i]
	if l != r:
		print(g(l), g(r))


n = int(input())
a = input()
b = input()
diff = []
for i in range(n):
	if a[i] != b[i]:
		posai = -1
		posbi = -1
		for j in range(len(diff)):
			if a[i] in diff[j]:
				posai = j
			if b[i] in diff[j]:
				posbi = j
		if posbi != -1 and posai != -1:
			if posbi == posai:
				pass
			else:
				diff[posai] = diff[posai].union(diff[posbi])
				del diff[posbi]
		elif posbi != -1:
			diff[posbi].add(a[i])
		elif posai != -1:
			diff[posai].add(b[i])
		else:
			diff.append({a[i], b[i]})
diff2 = []
for i in diff:
	diff2.append([])
	for j in i:
		diff2[-1].append(j)
ans = 0
for i in diff2:
	ans += len(i) - 1
print(ans)
for i in diff2:
	for j in range(1, len(i)):
		print(i[j - 1], i[j])


A = 'abcdefghijklmnopqrstuvwxyz'
n = int(input())
q = {}
d = {}
z = []
for i in range(26):
	d[A[i]] = i
	q[i] = A[i]
for (a, b) in zip(input(), input()):
	if d[a] != d[b]:
		z += ((a, b),)
		for i in q.pop(d[b]):
			d[i] = d[a]
			q[d[a]] += i
print(len(z))
for i in z:
	print(*i)


length = int(input())
VString = input()
TString = input()
spells = []
links = [{i} for i in range(26)]
mana = 0
for i in range(length):
	temp1 = ord(VString[i]) - 97
	temp2 = ord(TString[i]) - 97
	if temp1 != temp2 and (not temp2 in links[temp1]):
		links[temp1] = links[temp1].union(links[temp2])
		links[temp2] = links[temp2].union(links[temp1])
		for i2 in links[temp1]:
			if i2 != temp1:
				links[i2] = links[temp1].union(links[i2])
		mana = mana + 1
		spells.append(chr(temp1 + 97) + ' ' + chr(temp2 + 97))
print(mana)
for i in range(len(spells)):
	print(spells[i])


from collections import defaultdict

class Unionfind:

	def __init__(self, n):
		self.par = [-1] * n
		self.rank = [1] * n

	def root(self, x):
		p = x
		while not self.par[p] < 0:
			p = self.par[p]
		while x != p:
			tmp = x
			x = self.par[x]
			self.par[tmp] = p
		return p

	def unite(self, x, y):
		(rx, ry) = (self.root(x), self.root(y))
		if rx == ry:
			return False
		if self.rank[rx] < self.rank[ry]:
			(rx, ry) = (ry, rx)
		self.par[rx] += self.par[ry]
		self.par[ry] = rx
		if self.rank[rx] == self.rank[ry]:
			self.rank[rx] += 1

	def is_same(self, x, y):
		return self.root(x) == self.root(y)

	def count(self, x):
		return -self.par[self.root(x)]
n = int(input())
s = input()
t = input()
alpha = 'abcdefghijklmnopqrstuvwxyz'
nd = defaultdict(int)
cnt = 0
for alpha_i in alpha:
	nd[alpha_i] = cnt
	cnt += 1
uf = Unionfind(26)
ans = []
for i in range(n):
	u = nd[s[i]]
	v = nd[t[i]]
	if not uf.is_same(u, v):
		ans.append((s[i], t[i]))
		uf.unite(u, v)
print(len(ans))
for (si, ti) in ans:
	print(si, ti)


n = int(input())
a = input()
b = input()
d = set()
for i in a:
	d.add(i)
for i in b:
	d.add(i)
ans = dict()
j = 0
for i in d:
	ans[j] = set()
	ans[j].add(i)
	j += 1
for i in range(n):
	if a[i] != b[i]:
		ind_a = -1
		ind_b = -1
		for j in ans:
			if a[i] in ans[j]:
				ind_a = j
			if b[i] in ans[j]:
				ind_b = j
		if ind_a != ind_b:
			ans[ind_a] |= ans[ind_b]
			del ans[ind_b]
answer = 0
for i in ans:
	answer += len(ans[i]) - 1
print(answer)
for i in ans:
	if len(ans[i]) > 1:
		x = list(ans[i])
		for kek in range(len(x) - 1):
			print(x[kek], x[kek + 1])


def find(list, v):
	if list[v] != v:
		list[v] = find(list, list[v])
	return list[v]

def union(list, a, b):
	list[a] = b
d = [i for i in range(26)]
ans = []
n = int(input())
s1 = input()
s2 = input()
for i in range(n):
	a = find(d, ord(s1[i]) - ord('a'))
	b = find(d, ord(s2[i]) - ord('a'))
	if a == b:
		continue
	union(d, a, b)
	ans.append((chr(ord('a') + a), chr(ord('a') + b)))
print(len(ans))
for (a, b) in ans:
	print(a, b)


from collections import defaultdict

class Graph:

	def __init__(self, vertices):
		self.V = vertices
		self.graph = defaultdict(set)
		self.dd = []

	def addEdge(self, u, v):
		self.graph[u].add(v)
		self.graph[v].add(u)

	def DFSUtil(self, v, visited):
		visited[v] = True
		self.dd[-1].append(v)
		for i in self.graph[v]:
			if visited[i] == False:
				self.DFSUtil(i, visited)

	def fillOrder(self, v, visited, stack):
		visited[v] = True
		for i in self.graph[v]:
			if visited[i] == False:
				self.fillOrder(i, visited, stack)
		stack = stack.append(v)

	def getTranspose(self):
		g = Graph(self.V)
		for i in self.graph:
			for j in self.graph[i]:
				g.addEdge(j, i)
		return g

	def printSCCs(self):
		stack = []
		visited = [False] * self.V
		for i in range(self.V):
			if visited[i] == False:
				self.fillOrder(i, visited, stack)
		gr = self.getTranspose()
		visited = [False] * self.V
		while stack:
			i = stack.pop()
			if visited[i] == False:
				gr.dd.append([])
				gr.DFSUtil(i, visited)
		ans = 0
		for i in gr.dd:
			ans += len(i) - 1
		print(ans)
		for i in gr.dd:
			if len(i) > 1:
				for j in range(len(i) - 1):
					print(chr(i[j] + 97), chr(i[j + 1] + 97))
n = int(input())
a = input()
b = input()
c = set()
d = []
g = Graph(26)
for i in range(n):
	g.addEdge(ord(a[i]) - 97, ord(b[i]) - 97)
g.printSCCs()


class DSet:

	def __init__(self, n):
		self.parents = [-1 for i in range(n)]
		self.rank = [0 for i in range(n)]

	def find(self, n):
		if self.parents[n] is -1:
			return n
		ret = self.find(self.parents[n])
		self.parents[n] = ret
		return ret

	def union(self, a, b):
		if a is -1 or b is -1:
			return False
		(x, y) = (self.find(a), self.find(b))
		if self.find(a) == self.find(b) and x is not -1:
			return False
		if self.rank[x] == self.rank[y]:
			self.parents[x] = y
			self.rank[x] = self.rank[y] = self.rank[x] + 1
		elif self.rank[x] > self.rank[y]:
			self.parents[y] = x
			self.rank[y] = self.rank[x]
		else:
			self.parents[x] = y
			self.rank[x] = self.rank[y]
		return True
ds = DSet(2 * int(input()))
(str1, str2) = (input(), input())
alphaHash = [-1 for i in range(26)]
for i in range(len(str1)):
	ds.union(i, alphaHash[ord(str1[i]) - ord('a')])
	alphaHash[ord(str1[i]) - ord('a')] = i
	ds.union(len(str1) + i, alphaHash[ord(str2[i]) - ord('a')])
	alphaHash[ord(str2[i]) - ord('a')] = len(str1) + i
ans = []
for i in range(len(str1)):
	if ds.union(i, len(str1) + i):
		ans.append((str1[i], str2[i]))
print(len(ans))
for x in ans:
	print(x[0] + ' ' + x[1])


n = int(input())
a = list(input())
b = list(input())
a = [ord(i) - 97 for i in a]
b = [ord(i) - 97 for i in b]
parent = [i for i in range(26)]
cnt = 0
ans = []
for i in range(n):
	if a[i] != b[i]:
		pa = a[i]
		while parent[pa] != pa:
			pa = parent[pa]
		pb = b[i]
		while parent[pb] != pb:
			pb = parent[pb]
		if pa != pb:
			parent[pb] = pa
			cnt += 1
			ans.append([pb, pa])
print(cnt)
for i in range(len(ans)):
	print(chr(ans[i][0] + 97), chr(ans[i][1] + 97))


def main():
	p = [i for i in range(26)]

	def find(v):
		if p[v] != v:
			p[v] = find(p[v])
		return p[v]
	n = int(input())
	s1 = input()
	s2 = input()
	ans = []
	for i in range(n):
		a = find(ord(s1[i]) - ord('a'))
		b = find(ord(s2[i]) - ord('a'))
		if a != b:
			p[a] = b
			ans.append((chr(ord('a') + a), chr(ord('a') + b)))
	print(len(ans))
	for (a, b) in ans:
		print(a, b)
main()


n = int(input())
t = input()
v = input()
s = list(set(list(t)).union(set(list(v))))
uf = [i for i in range(len(s))]

def find(uf, i):
	p = uf[i]
	return p if i == p else find(uf, p)

def union(uf, i, j):
	uf[find(uf, i)] = find(uf, j)
res = []
for i in range(n):
	ti = s.index(t[i])
	vi = s.index(v[i])
	if find(uf, ti) != find(uf, vi):
		union(uf, ti, vi)
		res.append((t[i], v[i]))
print(len(res))
for i in range(len(res)):
	print(res[i][0], res[i][1])


parent = [-1 for i in range(26)]
size = [1 for i in range(26)]

def root(a):
	a = ord(a) - 97
	while parent[a] != -1:
		a = parent[a]
	return a

def union(a, b):
	root_a = root(a)
	root_b = root(b)
	if root_a == root_b:
		return 0
	if size[root_a] > size[root_b]:
		parent[root_b] = root_a
		size[root_a] += size[root_b]
	else:
		parent[root_a] = root_b
		size[root_b] += size[root_a]
	return 1
n = int(input())
s1 = input()
s2 = input()
ans = []
for i in range(n):
	if s1[i] != s2[i]:
		temp = union(s1[i], s2[i])
		if temp == 1:
			ans.append((s1[i], s2[i]))
print(len(ans))
for i in ans:
	print(*i)


from collections import defaultdict
n = int(input())
s1 = input()
s2 = input()

def find_parent(u):
	if par[u] != u:
		par[u] = find_parent(par[u])
	return par[u]
ka = []
yo = 97
par = defaultdict(int)
for i in range(26):
	par[yo] = yo
	yo += 1
ans = 0
for i in range(n):
	(a, b) = (ord(s1[i]), ord(s2[i]))
	(z1, z2) = (find_parent(a), find_parent(b))
	if z1 != z2:
		par[z1] = z2
		ans += 1
print(ans)
for i in par:
	if par[i] != i:
		print(chr(i), chr(par[i]))


n = int(input())
s = input()
t = input()
gr = {i: set() for i in 'qazwsxedcrfvtgbyhnujmiklop'}
for i in range(n):
	gr[s[i]].add(t[i])
	gr[t[i]].add(s[i])
used = set()
lol = []
for v in gr:
	if v not in used:
		used.add(v)
		q = [v]
		while q:
			g = q.pop()
			for w in gr[g]:
				if w not in used:
					used.add(w)
					lol.append((g, w))
					q.append(w)
print(len(lol))
for (a, b) in lol:
	print(a, b)


n = int(input())
str1 = input()
str2 = input()

class Node:

	def __init__(self, val):
		self.val = val
		self.parent = self
		self.rank = 1

class UnionFind:

	def __init__(self):
		self.map = {}

	def find(self, node):
		if node.val not in self.map:
			self.map[node.val] = node
		elif node.parent != node:
			node = self.find(node.parent)
		return node

	def merge(self, node1, node2):
		(parent1, parent2) = (self.find(node1), self.find(node2))
		if parent1 != parent2:
			if parent1.rank > parent2.rank:
				parent2.parent = parent1
			elif parent2.rank > parent1.rank:
				parent1.parent = parent2
			else:
				parent1.parent = parent2
				parent2.rank += 1

def solve():
	unionFind = UnionFind()
	ans = []
	for (ch1, ch2) in zip(str1, str2):
		if ch1 != ch2:
			node1 = unionFind.map[ch1] if ch1 in unionFind.map else Node(ch1)
			node2 = unionFind.map[ch2] if ch2 in unionFind.map else Node(ch2)
			if unionFind.find(node1) != unionFind.find(node2):
				unionFind.merge(node1, node2)
				ans.append((ch1, ch2))
	print(len(ans))
	for (ch1, ch2) in ans:
		print(ch1, ch2)
solve()


n = int(input())
a = input()
b = input()
pr = {}
ans = []
for i in range(0, 26):
	pr[i] = i

def find_set(v):
	if pr[v] == v:
		return v
	pr[v] = find_set(pr[v])
	return pr[v]

def union_set(x, y):
	pr[x] = y
	ans.append((x, y))
for i in range(len(a)):
	pa = find_set(ord(a[i]) - 97)
	pb = find_set(ord(b[i]) - 97)
	if pa == pb:
		continue
	union_set(pa, pb)
print(len(ans))
for i in ans:
	print(chr(97 + i[0]), chr(97 + i[1]))


import collections
import heapq

def do():
	n = int(input())
	s1 = input()
	s2 = input()
	al = set(s1 + s2)
	N = len(al)
	g = collections.defaultdict(set)
	nodes = set()
	for i in range(n):
		if s1[i] != s2[i]:
			g[s1[i]].add((1, s1[i], s2[i]))
			g[s2[i]].add((1, s2[i], s1[i]))
	seen = set()
	res = []
	for st in al:
		if st not in seen:
			usable = list(g[st])
			seen.add(st)
			heapq.heapify(usable)
			while usable and len(seen) < N:
				(w, s, e) = heapq.heappop(usable)
				if e not in seen:
					res.append(s + ' ' + e)
					seen.add(e)
					for nei in g[e]:
						if nei[2] not in seen:
							heapq.heappush(usable, nei)
	print(len(res))
	for _ in res:
		print(_)
	return 0
do()


n = int(input())
t = list(input())
v = list(input())
main = []
extra = []
ans = 0
j = 0

def find(a):
	for i in range(len(main)):
		if a in main[i]:
			return i
	else:
		return -1
while j < n:
	if t[j] != v[j]:
		flag = True
		x = find(t[j])
		y = find(v[j])
		if x == -1 and y == -1:
			main.append([t[j], v[j]])
			ans += 1
		elif x == -1 and y != -1:
			main[y].append(t[j])
			ans += 1
		elif y == -1 and x != -1:
			main[x].append(v[j])
			ans += 1
		elif y != -1 and x != -1 and (x != y):
			for i in main[x]:
				main[y].append(i)
			del main[x]
			ans += 1
	j += 1
print(ans)
for i in range(len(main)):
	for j in range(1, len(main[i])):
		print(main[i][0], main[i][j])


alphabet = 'abcdefghijklmnopqrstuvwxyz'
x = []
for i in range(0, 26):
	aa = {i}
	x.append(aa)
n = int(input().strip('\n'))
a = list(input().strip('\n'))
b = list(input().strip('\n'))
count = 0
output = []
for i in range(0, n):
	indexa = alphabet.index(a[i])
	indexb = alphabet.index(b[i])
	if indexb not in x[indexa]:
		output.append(a[i] + ' ' + b[i])
		count = count + 1
		x[indexa] = x[indexa].union(x[indexb])
		x[indexb] = x[indexa].union(x[indexb])
		for j in x[indexa]:
			x[j] = x[indexa].union(x[indexb])
		for j in x[indexb]:
			x[j] = x[indexa].union(x[indexb])
print(count)
for xx in output:
	print(xx)


from sys import stdin

def dfs(x, res):
	if vis[x]:
		return
	vis[x] = True
	res.append(x)
	for y in g[x]:
		dfs(y, res)
n = int(stdin.readline())
s = stdin.readline()
t = stdin.readline()
vis = [False] * 26
g = [set() for _ in range(26)]
for i in range(n):
	if s[i] == t[i]:
		continue
	x = ord(s[i]) - ord('a')
	y = ord(t[i]) - ord('a')
	g[x].add(y)
	g[y].add(x)
ans = []
for x in range(26):
	if not vis[x]:
		res = []
		dfs(x, res)
		for i in range(1, len(res)):
			x = chr(res[0] + ord('a'))
			y = chr(res[i] + ord('a'))
			ans.append((x, y))
print(len(ans))
for i in ans:
	print(*i)


class UnionFind:

	def __init__(self, n):
		self.par = [-1] * n
		self.rank = [0] * n

	def Find(self, x):
		if self.par[x] < 0:
			return x
		else:
			self.par[x] = self.Find(self.par[x])
			return self.par[x]

	def Unite(self, x, y):
		x = self.Find(x)
		y = self.Find(y)
		if x != y:
			if self.rank[x] < self.rank[y]:
				self.par[y] += self.par[x]
				self.par[x] = y
			else:
				self.par[x] += self.par[y]
				self.par[y] = x
				if self.rank[x] == self.rank[y]:
					self.rank[x] += 1

	def Same(self, x, y):
		return self.Find(x) == self.Find(y)

	def Size(self, x):
		return -self.par[self.Find(x)]
n = int(input())
s = list(str(input()))
t = list(str(input()))
s = [ord(c) - ord('a') for c in s]
t = [ord(c) - ord('a') for c in t]
uf = UnionFind(26)
ans = []
for (u, v) in zip(s, t):
	if not uf.Same(u, v):
		ans.append((u, v))
		uf.Unite(u, v)
print(len(ans))
for (u, v) in ans:
	u = chr(u + ord('a'))
	v = chr(v + ord('a'))
	print(u, v)


n = int(input())
a = input()
b = input()
dic = {}
for i in range(26):
	dic[chr(ord('a') + i)] = chr(ord('a') + i)

def find(a):
	global dic
	if dic[a] != a:
		dic[a] = find(dic[a])
	return dic[a]

def union(a, b):
	global dic
	if find(a) != find(b):
		dic[find(a)] = find(b)
sol = []

def solve():
	global sol
	global dic
	for i in dic:
		for j in range(6):
			find(i)
	for i in dic:
		if i != dic[i]:
			sol.append((i, dic[i]))
	print(len(sol))
	for i in sol:
		print('{} {}'.format(i[0], i[1]))
for i in range(n):
	if a[i] != b[i]:
		union(a[i], b[i])
solve()