Note that the only difference between String Transformation 1 and String Transformation 2 is in the move Koa does. In this version the letter y Koa selects must be strictly greater alphabetically than x (read statement for better understanding). You can make hacks in these problems independently.

Koa the Koala has two strings A and B of the same length n (|A|=|B|=n) consisting of the first 20 lowercase English alphabet letters (ie. from a to t).

In one move Koa:

  1. selects some subset of positions p_1, p_2, …, p_k (k ≥ 1; 1 ≤ p_i ≤ n; p_i ≠ p_j if i ≠ j) of A such that A_{p_1} = A_{p_2} = … = A_{p_k} = x (ie. all letters on this positions are equal to some letter x).

  2. selects a letter y (from the first 20 lowercase letters in English alphabet) such that y>x (ie. letter y is strictly greater alphabetically than x).

  3. sets each letter in positions p_1, p_2, …, p_k to letter y. More formally: for each i (1 ≤ i ≤ k) Koa sets A_{p_i} = y.

Note that you can only modify letters in string A.




Koa wants to know the smallest number of moves she has to do to make strings equal to each other (A = B) or to determine that there is no way to make them equal. Help her!

Input

Each test contains multiple test cases. The first line contains t (1 ≤ t ≤ 10) — the number of test cases. Description of the test cases follows.

The first line of each test case contains one integer n (1 ≤ n ≤ 10^5) — the length of strings A and B.

The second line of each test case contains string A (|A|=n).

The third line of each test case contains string B (|B|=n).

Both strings consists of the first 20 lowercase English alphabet letters (ie. from a to t).

It is guaranteed that the sum of n over all test cases does not exceed 10^5.

Output

For each test case:

Print on a single line the smallest number of moves she has to do to make strings equal to each other (A = B) or -1 if there is no way to make them equal.

Example

Input


5
3
aab
bcc
4
cabc
abcb
3
abc
tsr
4
aabd
cccd
5
abcbd
bcdda


Output


2
-1
3
2
-1

Note

  * In the 1-st test case Koa: 
    1. selects positions 1 and 2 and sets A_1 = A_2 =  b (\color{red}{aa}b → \color{blue}{bb}b). 
    2. selects positions 2 and 3 and sets A_2 = A_3 =  c (b\color{red}{bb} → b\color{blue}{cc}). 

  * In the 2-nd test case Koa has no way to make string A equal B.

  * In the 3-rd test case Koa: 
    1. selects position 1 and sets A_1 =  t (\color{red}{a}bc → \color{blue}{t}bc). 
    2. selects position 2 and sets A_2 =  s (t\color{red}{b}c → t\color{blue}{s}c). 
    3. selects position 3 and sets A_3 =  r (ts\color{red}{c} → ts\color{blue}{r}).

Difficulty: MEDIUM_HARD
Tags: Graph algorithms

String algorithms

Sorting

Amortized analysis

Greedy algorithms

Tree algorithms

Spanning trees
Skill types: Sorting

Amortized analysis

Greedy algorithms

Starter code:

Solutions:
from sys import maxsize

def compare(a, b):
	for i in range(len(a)):
		if a[i] != b[i]:
			return False
	return True
for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	cnt = 0
	for i in range(20):
		c = chr(97 + i)
		mn = maxsize
		f = False
		for j in range(n):
			if a[j] != b[j] and a[j] == c and (ord(b[j]) - 97 >= i):
				mn = min(mn, ord(b[j]))
		for j in range(n):
			if a[j] != b[j] and a[j] == c and (ord(b[j]) - 97 >= i):
				a[j] = chr(mn)
				f = True
		cnt += f
	if a == b:
		print(cnt)
	else:
		print(-1)


t = int(input())
for _ in range(t):
	n = int(input())
	a = list(input())
	b = list(input())
	valid = True
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			valid = False
			break
	if valid:
		ans = 0
		for i in range(97, 97 + 20):
			li = []
			y = chr(117)
			length = 0
			for j in range(n):
				if a[j] == chr(i) and b[j] > chr(i):
					li.append(j)
					y = min(y, b[j])
					length += 1
			if length != 0:
				ans += 1
				for k in range(length):
					a[li[k]] = y
		print(ans)


from sys import stdin, stdout, setrecursionlimit
from math import floor, gcd, fabs, factorial, fmod, sqrt, inf, log, log2
from random import seed, randint
from datetime import datetime
from collections import defaultdict as dd, deque
from heapq import merge, heapify, heappop, heappush, nsmallest
from bisect import bisect_left as bl, bisect_right as br, bisect
from collections import defaultdict as dd
mod = pow(10, 9) + 7
mod2 = 998244353

def inp():
	return stdin.readline().strip()

def iinp():
	return int(inp())

def out(var, end='\n'):
	stdout.write(str(var) + '\n')

def outa(*var, end='\n'):
	stdout.write(' '.join(map(str, var)) + end)

def lmp():
	return list(mp())

def mp():
	return map(int, inp().split())

def smp():
	return map(str, inp().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(m, val) for j in range(n)]

def remadd(x, y):
	return 1 if x % y else 0

def ceil(a, b):
	return (a + b - 1) // b

def def_value():
	return 0

def def_inf():
	return inf

def atoi(s):
	return ord(s) - ord('a')

def inc(s, n=1):
	return chr((ord(s) - ord('a') + n) % 26 + ord('a'))

class XY:

	def __init__(self, x, y):
		self.x = x
		self.y = y

def rotate(a, b, c):
	ang = (b.y - a.y) * (c.x - b.x) - (b.x - a.x) * (c.y - b.y)
	if ang == 0:
		return 0
	else:
		return ang / abs(ang)

def phi(n):
	(res, p) = (n, 2)
	while p * p <= n:
		if n % p == 0:
			while n % p == 0:
				n = n // p
			res -= res // p
		p += 1
	if n > 1:
		res -= res // n
	return res
for i in range(iinp()):
	n = iinp()
	a = inp()
	b = inp()
	flg = True
	adj = [[] for i in range(20)]
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			flg = False
			break
		elif ord(a[i]) < ord(b[i]):
			adj[atoi(a[i])].append(atoi(b[i]))
			adj[atoi(b[i])].append(atoi(a[i]))
	mrk = l1d(20, False)
	cnt = 0
	for i in range(20):
		if mrk[i] == False:
			cnt += 1
			q = [i]
			mrk[i] = True
			while len(q) > 0:
				x = q.pop()
				for y in adj[x]:
					if mrk[y] == False:
						mrk[y] = True
						q.append(y)
	if flg:
		print(20 - cnt)
	else:
		print(-1)


import sys
import math
import heapq
import bisect
from collections import Counter
from collections import defaultdict
from io import BytesIO, IOBase
import string

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		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
		self.BUFSIZE = 8192

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, self.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 = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, self.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:
			self.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')

def get_int():
	return int(input())

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

def get_int_grid(n):
	return [get_ints() for _ in range(n)]

def get_str():
	return input().split(' ')

def yes_no(b):
	if b:
		return 'YES'
	else:
		return 'NO'

def binary_search(good, left, right, delta=1, right_true=False):
	limits = [left, right]
	while limits[1] - limits[0] > delta:
		if delta == 1:
			mid = sum(limits) // 2
		else:
			mid = sum(limits) / 2
		if good(mid):
			limits[int(right_true)] = mid
		else:
			limits[int(~right_true)] = mid
	if good(limits[int(right_true)]):
		return limits[int(right_true)]
	else:
		return False

def prefix_sums(a, drop_zero=False):
	p = [0]
	for x in a:
		p.append(p[-1] + x)
	if drop_zero:
		return p[1:]
	else:
		return p

def prefix_mins(a, drop_zero=False):
	p = [float('inf')]
	for x in a:
		p.append(min(p[-1], x))
	if drop_zero:
		return p[1:]
	else:
		return p

class DSU:

	def __init__(self, nodes):
		self.p = {i: i for i in nodes}
		self.r = {i: 0 for i in nodes}
		self.s = {i: 1 for i in nodes}

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

	def union(self, u, v):
		u = self.get(u)
		v = self.get(v)
		if u != v:
			if self.r[u] > self.r[v]:
				(u, v) = (v, u)
			self.p[u] = v
			if self.r[u] == self.r[v]:
				self.r[v] += 1
			self.s[v] += self.s[u]

def solve():
	n = get_int()
	s1 = input().strip()
	s2 = input().strip()
	G = defaultdict(list)
	for letter in list(string.ascii_lowercase)[:20]:
		top_set = set((s2[i] for i in range(n) if s1[i] == letter))
		if len(top_set) == 0:
			pass
		else:
			for item in top_set:
				if item < letter:
					return -1
				elif item > letter:
					G[item].append(letter)
					G[letter].append(item)
	dsu = DSU(G.keys())
	for x in G:
		for y in G[x]:
			dsu.union(x, y)
	S = 0
	for x in G:
		if dsu.p[x] == x:
			S += dsu.s[x] - 1
	return S
t = get_int()
for _ in range(t):
	print(solve())


from collections import defaultdict
for _ in range(int(input())):
	input()
	a = input()
	b = input()
	(posa, ans) = (defaultdict(list), 0)
	if any((x > y for (x, y) in zip(a, b))):
		print(-1)
		continue
	for (i, x) in enumerate(a):
		posa[x].append(i)
	for c in sorted(set(a) | set(b)):
		(m, n) = ('t', [])
		for i in posa[c]:
			if b[i] == c:
				continue
			m = min(m, b[i])
			n.append(i)
		if n:
			posa[m].extend(n)
			ans += 1
	print(ans)


def findmin(arr1, arr2):
	mn1 = mn2 = 10 ** 9
	for i in range(len(arr1)):
		if arr1[i] < arr2[i]:
			if arr1[i] < mn1:
				mn1 = min(arr1[i], mn1)
				mn2 = s2[i]
			elif arr1[i] == mn1:
				mn2 = min(arr2[i], mn2)
		else:
			continue
	if mn1 == mn2 == 10 ** 9:
		return (False, False)
	else:
		return (mn1, mn2)
from collections import Counter, defaultdict
for i in range(int(input())):
	n = int(input())
	s1 = [ord(i) - ord('a') for i in input()]
	s2 = [ord(i) - ord('a') for i in input()]
	step = 0
	while True:
		(mn1, mn2) = findmin(s1, s2)
		if mn1 == False and mn2 == False:
			break
		for i in range(len(s1)):
			if s1[i] < s2[i] and s1[i] == mn1:
				s1[i] = mn2
		step += 1
	if s1 == s2:
		print(step)
	else:
		print(-1)


from collections import defaultdict
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	arr = []
	for i in a:
		arr.append(i)
	f = 0
	for i in range(n):
		if a[i] > b[i]:
			f = 1
			break
	if f == 1:
		print(-1)
	else:
		ans = 0
		for i in range(20):
			cur = chr(ord('a') + i)
			d = defaultdict(int)
			for j in range(n):
				if b[j] == cur and arr[j] != cur:
					d[arr[j]] += 1
			s = len(d)
			ans += s
			for j in range(n):
				if d[arr[j]] > 0:
					arr[j] = cur
		print(ans)


t = int(input())
while t:
	t = t - 1
	n = int(input())
	a = list(input())
	b = input()
	cnt = 0
	mf = 0
	for i in range(n):
		if a[i] > b[i]:
			mf = 1
			break
	if mf:
		print(-1)
		continue
	for i in range(97, 97 + 20):
		l = []
		ind = []
		x = chr(i)
		for j in range(n):
			if a[j] != b[j] and a[j] == x:
				ind.append(j)
				l.append(b[j])
		flag = 0
		if len(l) != 0:
			m = min(l)
			for j in ind:
				a[j] = m
				flag = 1
		if flag:
			cnt += 1
	print(cnt)


T = int(input())
for _ in range(T):
	n = int(input())
	a = input()
	b = input()
	flag = 0
	for i in range(n):
		if a[i] > b[i]:
			flag = 1
			break
	if flag == 1:
		print(-1)
	else:
		G = {}
		for i in range(97, 97 + 20):
			G[chr(i)] = []
		for i in range(n):
			if a[i] != b[i]:
				G[a[i]].append(b[i])
				G[b[i]].append(a[i])
		v = 0
		vis = [-1 for i in range(20)]
		for i in range(20):
			if vis[i] == -1:
				A = [chr(97 + i)]
				T1 = []
				while len(A) != 0:
					a = A.pop()
					vis[ord(a) - 97] = 0
					T1.append(a)
					for i in G[a]:
						if vis[ord(i) - 97] == -1:
							vis[ord(i) - 97] = 0
							A.append(i)
				v = v + len(T1) - 1
		print(v)


def main():
	t = int(input())
	from collections import Counter
	for _ in range(t):
		n = int(input())
		A = list(str(input()))
		B = list(str(input()))
		A = [ord(a) - ord('a') for a in A]
		B = [ord(b) - ord('a') for b in B]
		flag = True
		for i in range(n):
			if A[i] > B[i]:
				print(-1)
				flag = False
				break
		if not flag:
			continue
		X = []
		for i in range(19):
			for j in range(i + 1, 20):
				X.append((i, j))
		ans = 0
		for (i, j) in X:
			flag = False
			for k in range(n):
				if A[k] == i and B[k] == j:
					A[k] = j
					flag = True
			if flag:
				for k in range(n):
					if A[k] == i:
						A[k] = j
				ans += 1
		print(ans)
main()


import math
import collections
from sys import stdin, stdout, setrecursionlimit
from bisect import bisect_left as bsl
from bisect import bisect_right as bsr
import heapq as hq
setrecursionlimit(2 ** 20)
t = 1
t = int(stdin.readline())
for _ in range(t):
	n = int(stdin.readline())
	a = stdin.readline().strip('\n')
	b = stdin.readline().strip('\n')
	chk = False
	d = {}
	l = []
	var = 'abcdefghijklmnopqrst'
	for i in range(n):
		if a[i] > b[i]:
			chk = True
			break
		if a[i] == b[i]:
			continue
		if a[i] not in d:
			d[a[i]] = {}
		d[a[i]][b[i]] = True
		l.append((a[i], b[i]))
	if chk:
		print(-1)
	else:
		ans = 0
		l1 = list(d.keys())
		l1.sort()
		for i in var:
			if i in d:
				if len(d[i]) > 0:
					ans += 1
				mi = 'u'
				for j in d[i]:
					if mi > j:
						mi = j
				if mi not in d:
					d[mi] = {}
				for k in d[i]:
					if k != mi:
						d[mi][k] = True
		print(ans)


t = int(input())
for _ in range(t):
	n = int(input())
	str1 = input()
	str2 = input()
	res = {chr(97 + i): set() for i in range(20)}
	count = 0
	invalid = False
	for i in range(n):
		if str1[i] != str2[i]:
			res[str1[i]].add(str2[i])
	for i in range(20):
		key = chr(97 + i)
		curr_set = res[key]
		if not curr_set:
			continue
		min_char = min(curr_set)
		if min_char < key:
			invalid = True
			break
		if min_char == key:
			continue
		curr_set.remove(min_char)
		res[min_char] = res[min_char].union(curr_set)
		count += 1
	print(-1) if invalid else print(count)


import sys
input = sys.stdin.readline

def stringTrans(n, s1, s2):
	s1 = list(s1)
	checkList = {}
	for char in s1:
		if char not in checkList and char <= 't':
			checkList[char] = 1
	start = 'a'
	end = 't'
	count = 0
	while start <= end:
		store = []
		current = None
		replace = ''
		minimum = None
		for i in range(n):
			current = start
			if s1[i] == current:
				if s1[i] < s2[i]:
					store.append(i)
					if minimum == None:
						minimum = s2[i]
					elif s2[i] < minimum:
						minimum = s2[i]
				elif s1[i] > s2[i]:
					return -1
		for i in store:
			if minimum <= s2[i]:
				s1[i] = minimum
			else:
				return -1
		if len(store) > 0:
			count += 1
		start = chr(ord(start) + 1)
	return count

def solution():
	n = int(input())
	s1 = input()
	s2 = input()
	print(stringTrans(n, s1, s2))
t = int(input())
for i in range(0, t):
	solution()


t = int(input())
for i in range(t):
	t = int(input())
	a = input()
	b = input()
	re = True
	ans = 0
	d = {}
	for j in range(97, 97 + 20):
		d[chr(j)] = set()
	for i in range(t):
		if b[i] < a[i]:
			re = False
			break
		if b[i] == a[i]:
			continue
		else:
			d[a[i]].add(b[i])
	if re:
		while True:
			bq = True
			for j in d:
				if len(d[j]) != 0:
					r = list(d[j])
					r.sort()
					for k in range(1, len(r)):
						d[r[0]].add(r[k])
					d[j] = set()
					ans += 1
					bq = False
					break
			if bq:
				break
		print(ans)
	else:
		print(-1)


import os
import sys
debug = True
if debug and os.path.exists('input.in'):
	input = open('input.in', 'r').readline
else:
	debug = False
	input = sys.stdin.readline

def inp():
	return int(input())

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

def insr():
	s = input()
	return s[:len(s) - 1]

def invr():
	return map(int, input().split())
test_count = int(input())
for t in range(test_count):
	if debug:
		print('Test Case #', t + 1)
	n = inp()
	a = list(insr())
	b = list(insr())
	move = 0
	possible = True
	for i in range(0, n):
		if b[i] < a[i]:
			possible = False
			break
	if not possible:
		print(-1)
	else:
		for i in range(0, 20):
			ch = chr(ord('a') + i)
			isAny = False
			minimum = 'z'
			for j in range(0, n):
				if a[j] == ch and b[j] > a[j]:
					minimum = min(minimum, b[j])
					isAny = True
			if isAny:
				for j in range(0, n):
					if a[j] == ch and b[j] > a[j]:
						a[j] = minimum
				move += 1
		print(move)


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from itertools import *
import bisect
from heapq import *
from math import *
from copy import *
from collections import deque
from collections import Counter as counter
from itertools import combinations as comb
from itertools import permutations as permutate
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
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')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
mod = 1000000007

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def zerolist(n):
	return [0] * n

def nextline():
	out('\n')

def testcase(t):
	for p in range(t):
		solve()

def printlist(a):
	for p in range(0, len(a)):
		out(str(a[p]) + ' ')

def lcm(a, b):
	return a * b // gcd(a, b)

def power(a, b):
	ans = 1
	while b > 0:
		if b % 2 == 1:
			ans *= a
		a *= a
		b //= 2
	return ans

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True

def solve():
	n = int(inp())
	a = list(inp())
	b = list(inp())
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			return
	cnt = [{} for i in range(20)]
	for i in range(n):
		if a[i] == b[i]:
			continue
		if a[i] in cnt[ord(b[i]) - 97]:
			cnt[ord(b[i]) - 97][a[i]] += 1
		else:
			cnt[ord(b[i]) - 97][a[i]] = 1
	ans = 0
	cnvrted = {}
	for i in range(97 + 19, 96, -1):
		cnvrted[chr(i)] = chr(i)
	for i in range(1, 20):
		if len(cnt[i]) == 0:
			continue
		else:
			new = {}
			for j in cnt[i]:
				if cnvrted[j] not in new:
					new[cnvrted[j]] = 1
			ans += len(new)
			min = chr(97 + i)
			for j in cnt[i]:
				new = []
				for jj in cnvrted:
					if cnvrted[jj] == cnvrted[j]:
						new.append(jj)
				new.append(j)
				for jj in new:
					cnvrted[jj] = min
	print(ans)
testcase(int(inp()))


def solve(n, a, b):
	visited = [0] * 20
	graph = {}
	bad = False

	def dfs(u):
		visited[u] = 1
		for to in graph[u]:
			if not visited[to]:
				dfs(to)
	unique_letters = set()
	for i in range(n):
		if a[i] > b[i]:
			bad = True
			break
		if a[i] != b[i]:
			int_a = ord(a[i]) - ord('a')
			int_b = ord(b[i]) - ord('a')
			if int_a not in unique_letters:
				unique_letters.add(int_a)
			if int_b not in unique_letters:
				unique_letters.add(int_b)
			if graph.get(int_a, -1) == -1:
				graph[int_a] = []
			if graph.get(int_b, -1) == -1:
				graph[int_b] = []
			graph[int_a].append(int_b)
			graph[int_b].append(int_a)
	if not bad:
		answ = len(unique_letters)
		for i in unique_letters:
			if not visited[i]:
				dfs(i)
				answ -= 1
		print(answ)
	else:
		print(-1)
t = int(input())
for i in range(t):
	n = int(input())
	a = input()
	b = input()
	solve(n, a, b)


for _ in range(int(input())):
	(n, a, b) = (int(input()), input(), input())
	d = {}
	for i in 'abcdefghijklmnopqrst':
		d[i] = []
	err = False
	for i in range(n):
		if a[i] > b[i]:
			err = True
			break
		if a[i] < b[i]:
			d[a[i]].append((b[i], i))
	if err:
		print(-1)
		continue
	ans = 0
	for i in 'abcdefghijklmnopqrst':
		if len(d[i]) == 0:
			continue
		new = min(d[i])[0]
		ans += 1
		for j in d[i]:
			if j[0] != new:
				d[new].append(j)
		d[i] = []
	print(ans)


a = int(input())
for i in range(a):
	r = int(input())
	s1 = input()
	s2 = input()
	flag = 0
	for i in range(len(s1)):
		if s1[i] > s2[i]:
			print(-1)
			flag = 1
			break
	if flag == 1:
		continue
	from collections import *
	al = defaultdict(int)
	ban = defaultdict(list)
	for i in range(len(s1)):
		if s1[i] not in ban[s2[i]] and s1[i] != s2[i]:
			ban[s2[i]].append(s1[i])
		al[s2[i]] = 1
	char = []
	for i in range(20):
		char.append(chr(i + 97))
	total = 0
	for x in range(20):
		i = chr(x + 97)
		if al[i] == 0:
			continue
		m = ban[i]
		for j in range(len(m)):
			m[j] = char[ord(m[j]) - 97]
		total += len(list(set(m)))
		if i in m:
			total -= 1
		for x in range(len(m)):
			r = char[ord(m[x]) - 97]
			char[ord(m[x]) - 97] = i
			for u in range(20):
				if char[u] == r:
					char[u] = i
	print(total)


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')

class union_find:

	def __init__(self, n):
		self.n = n
		self.rank = [0] * n
		self.parent = [int(j) for j in range(n)]

	def union(self, i, j):
		i = self.find(i)
		j = self.find(j)
		if self.rank[i] == self.rank[j]:
			self.parent[i] = j
			self.rank[j] += 1
		elif self.rank[i] > self.rank[j]:
			self.parent[j] = i
		else:
			self.parent[i] = j

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

def main():
	for t in range(int(input())):
		n = int(input())
		a = input()
		b = input()
		x = union_find(20)
		ans = 0
		for i in range(n):
			if a[i] > b[i]:
				print(-1)
				break
			elif b[i] > a[i]:
				s = ord(a[i]) - 97
				t = ord(b[i]) - 97
				if x.find(s) != x.find(t):
					x.union(s, t)
					ans += 1
		else:
			print(ans)
main()


import sys
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))

def find(x):
	while x != p[x]:
		x = p[x]
	return x

def union(a, b):
	x = find(a)
	y = find(b)
	if x != y:
		p[y] = p[x] = min(x, y)
		r[min(x, y)] += r[max(x, y)]
(t,) = I()
for _ in range(t):
	(n,) = I()
	a = input().strip()
	b = input().strip()
	p = [i for i in range(20)]
	r = [1] * 20
	pos = 1
	for i in range(n):
		if a[i] < b[i]:
			union(ord(a[i]) - 97, ord(b[i]) - 97)
		elif a[i] != b[i]:
			pos = 0
			break
	if pos:
		an = 0
		for i in range(20):
			if p[i] == i:
				an += r[i] - 1
		print(an)
	else:
		print(-1)


t = int(input())
for test in range(t):
	str_length = int(input())
	A = input()
	B = input()
	flag = False
	for i in range(str_length):
		if A[i] > B[i]:
			print(-1)
			flag = True
			break
	if flag:
		continue
	front = [set() for _ in range(20)]
	for i in range(str_length):
		if A[i] != B[i]:
			front[ord(A[i]) - 96].add(ord(B[i]) - 96)
	moves = 0
	for i in range(20):
		if not front[i]:
			continue
		else:
			flag = False
			for j in range(i + 1, 20):
				if front[j] and front[i].intersection(front[j]) or j in front[i]:
					moves += 1
					front[j] = front[j].union(front[i])
					if j in front[j]:
						front[j].remove(j)
					flag = True
					break
			if not flag:
				moves += len(front[i])
	print(moves)


case = int(input())
for _ in range(case):
	alp = [[] for _ in range(20)]
	n = int(input())
	A = input()
	B = input()
	ans = True
	for i in range(n):
		if ord(A[i]) > ord(B[i]):
			ans = False
			break
		if ord(A[i]) < ord(B[i]):
			p = ord(B[i]) - 97
			if not p in alp[ord(A[i]) - 97]:
				alp[ord(A[i]) - 97].append(p)
	if ans == False:
		print(-1)
		continue
	ans = 0
	for i in range(20):
		lst = alp[i]
		if len(lst) == 0:
			continue
		ans += 1
		idousaki = min(lst)
		for j in lst:
			if idousaki != j:
				alp[idousaki].append(j)
		alp[idousaki] = list(set(alp[idousaki]))
	print(ans)


import os
import sys
from io import BytesIO, IOBase
import threading
from bisect import bisect_right
from math import gcd, log
from collections import Counter

def main():
	n = int(input())
	a = [ord(c) - 97 for c in input()]
	b = [ord(c) - 97 for c in input()]
	ans = 0
	bt = True
	for ch in range(20):
		t = [0] * 20
		for i in range(n):
			if a[i] == ch:
				t[b[i]] = 1
		for i in range(ch):
			if t[i] == 1:
				bt = False
		for i in range(ch + 1, 20):
			if t[i] == 1:
				for j in range(n):
					if a[j] == ch and b[j] > ch:
						a[j] = i
				ans += 1
				break
	if bt:
		print(ans)
	else:
		print(-1)
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')
for _ in range(int(input())):
	main()


import sys
input = sys.stdin.readline
import heapq
import copy
import math
import decimal

def inp():
	return int(input())

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

def insr():
	s = input()
	return list(s[:len(s) - 1])

def insr2():
	s = input()
	return s[:len(s) - 1]

def invr():
	return map(int, input().split())

def pr_list(a):
	print(*a, sep=' ')

def main():
	tests = inp()
	mod = 1000000007
	limit = 10 ** 18
	ans = 0
	stack = []
	hashm = {}
	arr = []
	heapq.heapify(arr)
	for test in range(tests):
		n = inp()
		a = insr()
		b = insr()
		grid = [[0 for i in range(26)] for j in range(26)]
		flag = 0
		for i in range(n):
			if a[i] != b[i]:
				if ord(a[i]) > ord(b[i]):
					flag = 1
					break
				grid[ord(a[i]) - ord('a')][ord(b[i]) - ord('a')] = 1
		if flag == 1:
			print(-1)
		else:
			ans = 0

			def find_comman(a1, b1, itr):
				for i in range(itr, 26):
					if b1[i] == 1:
						return 1
				else:
					return 0

			def merge(a1, b1, itr):
				for i in range(itr, 26):
					b1[i] = max(b1[i], a1[i])
				return b1
			for i in range(26):
				flag = 0
				for j in range(i + 1, 26):
					if grid[i][j] == 1:
						ans = ans + 1
						grid[j] = merge(grid[i], grid[j], j + 1)
						flag = 1
						break
			print(ans)
main()


def dfs(u):
	V[u] = 0
	return sum((dfs(v) for v in g[u] if V[v])) + 1
I = input
for _ in [0] * int(I()):
	I()
	V = [1] * 117
	g = [[] for _ in V]
	f = 0
	for (x, y) in zip(map(ord, I()), map(ord, I())):
		f |= x > y
		g[x] += (y,)
		g[y] += (x,)
	print((sum((dfs(i) - 1 for i in range(117) if V[i])), -1)[f])


t = int(input())

class Graph:

	def __init__(self, V):
		self.V = V
		self.adj = [[] for i in range(V)]

	def DFSUtil(self, temp, v, visited):
		visited[v] = True
		temp.append(v)
		for i in self.adj[v]:
			if visited[i] == False:
				temp = self.DFSUtil(temp, i, visited)
		return temp

	def addEdge(self, v, w):
		self.adj[v].append(w)
		self.adj[w].append(v)

	def connectedComponents(self):
		visited = []
		cc = []
		for i in range(self.V):
			visited.append(False)
		for v in range(self.V):
			if visited[v] == False:
				temp = []
				cc.append(self.DFSUtil(temp, v, visited))
		return cc
for _ in range(t):
	n = input()
	a = input()
	b = input()
	edges = set()
	nodes = set()
	flag = 0
	for i in range(len(a)):
		if a[i] == b[i]:
			continue
		if a[i] > b[i]:
			print(-1)
			flag = 1
			break
		edges.add((a[i], b[i]))
		nodes.add(a[i])
		nodes.add(b[i])
	if flag == 0:
		g = Graph(21)
		for edge in list(edges):
			g.addEdge(ord(edge[0]) - ord('a'), ord(edge[1]) - ord('a'))
		total = 0
		for component in g.connectedComponents():
			total += len(component) - 1
		print(total)


import sys
import heapq
from collections import deque
from collections import defaultdict
I = lambda : list(map(int, input().split(' ')))

def check(a, b, char, visited):
	s = set()
	for i in range(len(a)):
		if b[i] == char and visited[i] == 0:
			s.add(a[i])
	for i in range(len(a)):
		if visited[i] == 0 and a[i] in s:
			a[i] = char
	for i in range(len(a)):
		if b[i] == char:
			visited[i] = 1
	return len(s)
for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	visited = [0] * n
	flag = 1
	for i in range(n):
		if b[i] < a[i]:
			flag = 0
			break
		if a[i] == b[i]:
			visited[i] = 1
	if flag == 0:
		print(-1)
		continue
	ans = 0
	for char in 'abcdefghijklmnopqrst':
		ans += check(a, b, char, visited)
	print(ans)


from string import ascii_lowercase as alph
from sys import stdin
input = lambda : stdin.readline().rstrip()
for _ in range(int(input())):
	n = int(input())
	s = input()
	t = input()
	no = 0
	g = {i: set() for i in alph}
	for i in range(n):
		if s[i] > t[i]:
			no = 1
			break
		if s[i] < t[i]:
			g[s[i]].add(t[i])
	if no:
		print(-1)
		continue
	ans = 0
	while 1:
		for i in alph:
			if g[i]:
				if len(g[i]) == 1:
					ans += 1
					g[i] = 0
				else:
					f = min(g[i])
					g[i].remove(f)
					g[f] |= g.pop(i)
					g[i] = 0
					ans += 1
					break
		else:
			break
	print(ans)


from sys import stdin
input = stdin.readline
for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = input()
	s = set()
	ans = 0
	flag = 0
	for ch in range(20):
		for i in range(n):
			if b[i] == chr(ch + 97):
				if a[i] > b[i]:
					print(-1)
					flag = 1
					break
				elif a[i] < b[i]:
					s.add(a[i])
		for i in range(n):
			if a[i] in s:
				a[i] = chr(ch + 97)
		ans += len(s)
		s = set()
		if flag:
			break
	if not flag:
		print(ans)


import math
from sys import stdin, stdout
from collections import defaultdict
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	d = [[0] * 26 for i in range(26)]
	f = 0
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			print(-1)
			f = 1
			break
		elif ord(a[i]) < ord(b[i]):
			d[ord(a[i]) - 97][ord(b[i]) - 97] += 1
	if f == 1:
		continue
	c = 0
	for i in range(26):
		for j in range(26):
			if d[i][j] != 0:
				d[i][j] = 0
				for k in range(26):
					d[j][k] += d[i][k]
				c += 1
				break
	print(c)


import sys
input = sys.stdin.readline
for _ in range(int(input())):
	(n, a, b, ans) = (int(input()), [char for char in input().strip()], [char for char in input().strip()], 0)
	for i in range(n):
		if a[i] > b[i]:
			ans = -1
	if ans != -1:
		for char in 'abcdefghijklmnopqrst':
			s = set()
			for i in range(n):
				if char == b[i] and a[i] < b[i]:
					s.add(a[i])
			for i in range(n):
				if a[i] in s:
					a[i] = char
			ans += len(s)
	print(ans)


for nt in range(int(input())):
	n = int(input())
	s = list(input())
	t = input()
	new = []
	alpha = []
	for i in range(97, 117):
		alpha.append(chr(i))
	flag = 0
	for i in range(n):
		if t[i] < s[i]:
			flag = 1
			break
	if flag:
		print(-1)
		continue
	ans = 0
	for i in range(97, 117):
		x = 'z'
		flag = 0
		for j in range(n):
			if s[j] == t[j]:
				continue
			if s[j] == chr(i):
				x = min(x, t[j])
				flag = 1
		if not flag:
			continue
		ans += 1
		for j in range(n):
			if s[j] == t[j]:
				continue
			if s[j] == chr(i):
				s[j] = x
	print(ans)


from collections import Counter
t = int(input())
for _ in range(t):
	n = int(input())
	s = list(input())
	t = list(input())
	flag = True
	for i in range(n):
		if ord(t[i]) < ord(s[i]):
			flag = False
			break
	if not flag:
		print(-1)
		continue
	steps = 0
	arr = [chr(i) for i in range(ord('a'), ord('a') + 21)]
	for char in arr:
		mn = float('inf')
		for i in range(n):
			if s[i] == char and t[i] != char:
				mn = min(ord(t[i]), mn)
		if mn != float('inf'):
			steps += 1
			for i in range(n):
				if s[i] == char and t[i] != char:
					s[i] = chr(mn)
	print(steps)


def x():
	n = int(input())
	ans = 0
	A = list(input())
	B = list(input())
	G = []
	ver = set()
	for i in range(n):
		a = ord(A[i]) - ord('a')
		b = ord(B[i]) - ord('a')
		ver.add(a)
		ver.add(b)
		if a <= b:
			G.append([a, b])
		else:
			print(-1)
			return 0
	G.sort()
	res = []
	tree_id = [i for i in range(20)]
	for i in range(n):
		a = G[i][0]
		b = G[i][1]
		if tree_id[a] != tree_id[b]:
			res.append((a, b))
			old_id = tree_id[b]
			new_id = tree_id[a]
			for j in range(20):
				if tree_id[j] == old_id:
					tree_id[j] = new_id
	print(len(res))
for q in range(int(input())):
	x()


import collections

def solve(s1, s2):
	for (ch1, ch2) in zip(s1, s2):
		if ch1 > ch2:
			return -1
	cnt = {}
	for (ch1, ch2) in zip(s1, s2):
		if ch1 != ch2:
			cnt.setdefault(ch1, set())
			cnt[ch1].add(ord(ch2) - ord(ch1))
	ans = 0
	ch = 'a'
	while ch < 't':
		if ch in cnt and cnt[ch]:
			distances = sorted(cnt[ch])
			ans += 1
			if distances:
				dist = distances[0]
				ch2 = chr(ord(ch) + distances[0])
				for d2 in distances:
					if d2 - dist > 0:
						cnt.setdefault(ch2, set())
						cnt[ch2].add(d2 - dist)
		ch = chr(ord(ch) + 1)
	return ans
for _ in range(int(input())):
	n = int(input())
	s1 = input()
	s2 = input()
	print(solve(s1, s2))


from sys import stdin
from collections import deque
mod = 10 ** 9 + 7
import sys
import random
from queue import PriorityQueue
from collections import Counter as cc
from bisect import bisect_right
from bisect import bisect_left
from collections import defaultdict
from math import sqrt, factorial, gcd, log2, inf, ceil
import heapq
input = lambda : sys.stdin.readline().rstrip()
from sys import stdin, stdout
from heapq import heapify, heappush, heappop
from itertools import permutations
from math import factorial as f

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
import sys

def find_parent(b):
	while par[b] != b:
		b = par[b]
	return b
t = int(input())
for _ in range(t):
	n = int(input())
	s1 = input()
	s2 = input()
	if s1 == s2:
		print(0)
		continue
	flag = 0
	for i in range(n):
		if s1[i] > s2[i]:
			flag = 1
			break
	if flag:
		print(-1)
		continue
	par = [i for i in range(30)]
	rank = [1] * 30
	for i in range(n):
		(a, b) = (ord(s1[i]) - 97, ord(s2[i]) - 97)
		(z1, z2) = (find_parent(a), find_parent(b))
		if z1 != z2:
			if rank[z1] > rank[z2]:
				(z1, z2) = (z2, z1)
			par[z1] = z2
			rank[z2] += rank[z1]
	seti = set()
	for i in s1:
		z = find_parent(ord(i) - 97)
		seti.add(z)
	ans = 0
	for i in seti:
		ans += rank[i] - 1
	print(ans)


from collections import defaultdict
t = int(input())
for tc in range(t):
	n = int(input())
	a = str(input())
	arr = list(a)
	b = str(input())
	charray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't']
	flag = 0
	for i in range(n):
		if a[i] > b[i]:
			print('-1')
			flag = 1
			break
	if flag == 0:
		ans = 0
		for i in charray:
			f = defaultdict(int)
			for j in range(n):
				if i == b[j] and i != a[j]:
					f[arr[j]] += 1
			ans += len(f)
			for j in range(n):
				if f[arr[j]] > 0:
					arr[j] = i
		print(ans)


def func(a, b):
	res = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst'
	count = 0
	low = ''
	for i in range(20):
		low = 'z'
		for j in range(len(a)):
			if b[j] < a[j]:
				return -1
			if a[j] == res[i] and a[j] != b[j]:
				low = min(low, b[j])
		if low != 'z':
			n = []
			flag = False
			for j in range(len(a)):
				if a[j] == res[i] and a[j] != b[j]:
					flag = True
					n.append(low)
				else:
					n.append(a[j])
			a = ''.join(n)
			if flag == True:
				count += 1
	return count
t = int(input())
for i in range(t):
	n = int(input())
	s = input()
	b = input()
	res = func(s, b)
	print(res)


def solve(n, s1, s2):
	m = 20
	s1 = [ord(c) - ord('a') for c in s1]
	s2 = [ord(c) - ord('a') for c in s2]
	A = [[0] * m for _ in range(m)]
	for i in range(n):
		if s1[i] > s2[i]:
			return -1
		A[s1[i]][s2[i]] = 1
	for i in range(m):
		for j in range(i + 1, m):
			for k in range(j + 1, m):
				if A[i][j] & A[i][k]:
					A[i][k] = 0
					A[j][k] = 1
	B = [[0] * m for _ in range(m)]
	for k in range(1, m):
		for i in range(k)[::-1]:
			for j in range(i, k):
				B[i][k] = A[i][k] | B[i][j] & B[j][k]
	for i in range(m):
		for j in range(i + 1, m):
			for k in range(j + 1, m):
				if B[i][j] & B[j][k]:
					A[i][k] = 0
	count = 0
	for i in range(m):
		for j in range(i + 1, m):
			if A[i][j]:
				count += 1
	return count

def main(istr, ostr):
	t = int(istr.readline())
	for _ in range(t):
		n = int(istr.readline())
		s1 = istr.readline().strip()
		s2 = istr.readline().strip()
		result = solve(n, s1, s2)
		print(result, file=ostr)
import sys
main(sys.stdin, sys.stdout)


from functools import lru_cache
from sys import stdin, stdout
import sys
from math import *

def dfs(s, p):
	ans = 1
	v[s] = 1
	for i in g[s]:
		if i != p and v[i] == 0:
			ans += dfs(i, s)
	return ans
for __ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	g = [[] for i in range(26)]
	temp = 0
	for i in range(n):
		if a[i] > b[i]:
			temp = 1
			break
	if temp:
		print(-1)
		continue
	for i in range(n):
		if a[i] != b[i]:
			g[ord(a[i]) - 97].append(ord(b[i]) - 97)
			g[ord(b[i]) - 97].append(ord(a[i]) - 97)
	v = [0] * 26
	ans = 0
	for i in range(26):
		ans += dfs(i, -1) - 1
	print(ans)


def toid(c):
	return ord(c) - ord('a')

def solve(n, A, B):
	ret = 0
	matrix = [[0] * 20 for _ in range(20)]
	for i in range(n):
		if ord(A[i]) > ord(B[i]):
			return -1
		matrix[toid(A[i])][toid(B[i])] += 1
	for i in range(20):
		for j in range(i + 1, 20):
			if matrix[i][j] > 0:
				ret += 1
				for k in range(j, 20):
					temp = matrix[i][k]
					matrix[i][k] = 0
					matrix[j][k] += temp
	return ret
t = int(input())
for _ in range(t):
	n = int(input())
	A = input()
	B = input()
	print(solve(n, A, B))


def ok(a, b, n):
	for i in range(n):
		if a[i] > b[i]:
			return False
	return True
MAX = 100001
parent = [0] * MAX
Rank = [0] * MAX

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

def merge(r1, r2):
	if r1 != r2:
		if Rank[r1] > Rank[r2]:
			parent[r2] = r1
			Rank[r1] += Rank[r2]
		else:
			parent[r1] = r2
			Rank[r2] += Rank[r1]

def minimumOperations(s1, s2):
	for i in range(1, 26 + 1):
		parent[i] = i
		Rank[i] = 1
	ans = []
	for i in range(len(s1)):
		if s1[i] != s2[i]:
			if find(ord(s1[i]) - 96) != find(ord(s2[i]) - 96):
				x = find(ord(s1[i]) - 96)
				y = find(ord(s2[i]) - 96)
				merge(x, y)
				ans.append([s1[i], s2[i]])
	print(len(ans))
for _ in range(int(input())):
	n = int(input())
	s = [i for i in input()]
	t = [i for i in input()]
	if ok(s, t, n):
		minimumOperations(''.join(s), ''.join(t))
	else:
		print(-1)


def ans(a, b, n):
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			return -1
	d = {'a': [], 'b': [], 'c': [], 'd': [], 'e': [], 'f': [], 'g': [], 'h': [], 'i': [], 'j': [], 'k': [], 'l': [], 'm': [], 'n': [], 'o': [], 'p': [], 'q': [], 'r': [], 's': [], 't': []}
	for i in range(n):
		d[b[i]].append(i)
	count = 0
	val = []
	for i in d:
		temp = 0
		if d[i] != []:
			for j in d[i]:
				if a[j] not in val and a[j] != b[j]:
					val.append(a[j])
					a = a.replace(a[j], b[j])
					temp += 1
		count += temp
	return count
m = int(input())
for i in range(m):
	n = int(input())
	a = input()
	b = input()
	print(ans(a, b, n))


import sys
inpy = [x for x in sys.stdin.read().split()]
t = int(inpy[0])
index = 1
for _ in range(t):
	n = int(inpy[index])
	(a, b) = (inpy[index + 1], inpy[index + 2])
	index += 3
	memo = set()
	flag = True
	for (i, j) in zip(a, b):
		if i > j:
			flag = False
			break
		elif j > i:
			memo.add((ord(i) - ord('a'), ord(j) - ord('a')))
	if not flag:
		print(-1)
	else:
		l = list(memo)
		l.sort()
		memo = set()
		match = [-1] * 26

		def get(i):
			if match[i] == -1 or match[i] == i:
				return i
			return get(match[i])
		res = 0
		for (i, j) in l:
			if match[i] == -1:
				match[i] = i
			(i, j) = (get(i), get(j))
			if i != j:
				res += 1
				match[min(i, j)] = max(i, j)
		print(res)


import sys
input = sys.stdin.readline
from collections import *
for _ in range(int(input())):
	n = int(input())
	A = input()[:-1]
	B = input()[:-1]
	flag = False
	for i in range(n):
		if A[i] > B[i]:
			flag = True
	if flag:
		print(-1)
		continue
	d = defaultdict(list)
	for i in range(n):
		s = ord(A[i]) - ord('a')
		t = ord(B[i]) - ord('a')
		if s < t:
			d[s].append(t)
	ans = 0
	for i in range(26):
		if len(d[i]) == 0:
			continue
		ans += 1
		m = min(d[i])
		for v in d[i]:
			if m < v:
				d[m].append(v)
	print(ans)


t = int(input())
for _ in range(t):
	n = int(input())
	a = list(input())
	b = list(input())
	count = [[0 for i in range(20)] for i in range(20)]
	flag = 1
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			flag = 0
			print(-1)
			break
	if flag == 0:
		continue
	ans = 0
	count = [[0 for i in range(20)] for i in range(20)]
	for i in range(n):
		count[ord(b[i]) - 97][ord(a[i]) - 97] += 1
	for i in range(1, 20):
		counter = set()
		for j in range(i):
			if count[i][j] > 0:
				counter.add(j)
				ans += 1
		for j in range(20):
			jem = 0
			for k in range(i):
				if k in counter:
					jem += count[j][k]
					count[j][k] = 0
			count[j][i] += jem
	print(ans)


a = input()
for x in range(int(a)):
	d = input()
	b = input()
	c = input()
	tag = 0
	string = 'abcdefghijklmnopqrstuwxyz'
	dict = {}
	dict1 = {}
	dict2 = {}
	for i in string:
		dict[i] = []
		dict1[i] = []
	for i in range(len(c)):
		if c[i] < b[i]:
			tag += 1
		if c[i] != b[i]:
			dict[b[i]].append(i)
			dict1[b[i]].append(c[i])
	ans = 0
	if tag > 0:
		print(-1)
	else:
		for i in string:
			if len(dict1[i]) != 0:
				dict1[i].sort()
				for j in dict[i]:
					if c[j] != dict1[i][0]:
						dict[dict1[i][0]].append(j)
						dict1[dict1[i][0]].append(c[j])
				ans += 1
		print(ans)


def process(check, mn):
	for ele in check:
		a[ele] = mn
for t in range(int(input())):
	n = int(input())
	a = [str(k) for k in input()]
	b = [str(k) for k in input()]
	flag = 0
	count = 0
	alp = 'abcdefghijklmnopqrst'
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			flag = 1
			break
	if flag == 1:
		print(-1)
		continue
	for ele in alp:
		check = []
		mn = 't'
		for i in range(n):
			if a[i] != b[i] and a[i] == ele:
				check.append(i)
				mn = min(mn, b[i])
		if check != []:
			count += 1
			process(check, mn)
	print(count)


def dfs(u):
	for i in g[u]:
		if not visited[i]:
			visited[i] = True
			dfs(i)
for _ in range(int(input())):
	n = int(input())
	bad = False
	(a, b) = [input() for i in range(2)]
	g = [[] for i in range(20)]
	for i in range(n):
		if a[i] != b[i]:
			if a[i] > b[i]:
				bad = True
				break
			g[ord(a[i]) - ord('a')].append(ord(b[i]) - ord('a'))
			g[ord(b[i]) - ord('a')].append(ord(a[i]) - ord('a'))
	if bad:
		print(-1)
		continue
	visited = [False] * 20
	ans = 20
	for i in range(20):
		if not visited[i]:
			visited[i] = True
			dfs(i)
			ans -= 1
	print(ans)


cases = []
for i in range(int(input())):
	input()
	cases.append([list(input()), list(input())])

def solve(case):
	a = case[0]
	b = case[1]
	ab = [list(pair) for pair in zip(a, b) if pair[0] != pair[1]]
	ab.sort()
	for pair in ab:
		if pair[0] > pair[1]:
			print('-1')
			return
	moves = 0
	while len(ab) > 0:
		moves += 1
		lowest_b = ab[0][1]
		s = 0
		for i in ab:
			if i[0] != ab[0][0]:
				break
			lowest_b = min(lowest_b, i[1])
			s += 1
		sli = [[lowest_b, p[1]] for p in ab[:s]]
		ab[:s] = sli
		ab = sorted([pair for pair in ab if pair[0] != pair[1]])
	print(moves)
for case in cases:
	solve(case)


def ans(A, B):
	s = set()
	for (a, b) in zip(A, B):
		if a == b:
			continue
		if a > b:
			return -1
		s.add((ord(a) - 97, ord(b) - 97))
	s = sorted(list(s))
	ret = 0
	while len(s):
		ret += 1
		(a0, b0) = s[0]
		next_s = []
		for (a, b) in s:
			if a0 == a:
				assert b0 <= b
				a = b0
			next_s += [(a, b)]
		s = next_s
		next_s = []
		for (a, b) in s:
			if a == b:
				continue
			next_s += [(a, b)]
		s = sorted(list(set(next_s)))
	return ret
	return s
T = int(input())
for _ in range(T):
	input()
	A = input()
	B = input()
	print(ans(A, B))


def solve(n, a, b):
	for i in range(n):
		if a[i] > b[i]:
			return -1
	ans = 0
	for j in range(20):
		cr = chr(97 + j)
		arr = []
		x = 'z'
		for i in range(n):
			if a[i] == cr and b[i] > cr:
				x = min(b[i], x)
				arr.append(i)
		if len(arr) != 0:
			ans += 1
			for k in arr:
				a[k] = x
	return ans
for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	print(solve(n, a, b))


from collections import defaultdict
import string
T = int(input())
for t in range(T):
	n = int(input())
	source = input()
	target = input()
	exit_flag = False
	for i in range(n):
		if target[i] < source[i]:
			print(-1)
			exit_flag = True
			break
	if exit_flag:
		continue
	d = defaultdict(set)
	for i in range(n):
		if source[i] != target[i]:
			d[source[i]].add(target[i])
	ans = 0
	for i in string.ascii_lowercase:
		if i in d:
			if d[i]:
				smallest_e = min(d[i])
				d[min(d[i])] |= set([j for j in d[i] if j != smallest_e])
				ans += 1
	print(ans)


alpha = 'abcdefghijklmnopqrst'
t = int(input())
for _ in range(t):
	n = int(input())
	a = list(input())
	b = list(input())
	f = 0
	c = 0
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			f = 1
			break
	if f == 0:
		for letter in alpha:
			arr = []
			ch = 'u'
			x = 0
			for i in range(n):
				if a[i] == letter and a[i] < b[i]:
					arr.append(i)
					x = 1
					ch = min(b[i], ch)
			c += x
			for i in arr:
				a[i] = ch
		print(c)


def dfs(u):
	V[u] = 0
	return sum((dfs(v) for v in g[u] if V[v])) + 1
I = input
for _ in [0] * int(I()):
	I()
	s = {*zip(I(), I())}
	V = [1] * 20
	g = [[] for _ in V]
	f = 1
	for (x, y) in s:
		if x > y:
			f = 0
		if x < y:
			x = ord(x) - 97
			y = ord(y) - 97
			g[x] += (y,)
			g[y] += (x,)
	print(sum((dfs(i) - 1 for i in range(20) if V[i])) if f else -1)


t = int(input())
from collections import defaultdict
sr = 'abcdefghijklmnopqrst'
for _ in range(t):
	n = int(input())
	A = input()
	B = input()
	dd = defaultdict(lambda : [])
	bo = False
	for i in range(n):
		ch = A[i]
		x = ord(B[i]) - ord(ch)
		if x < 0:
			print(-1)
			bo = True
			break
		elif x > 0:
			dd[ord(ch) - 96].append(x)
	if bo:
		continue
	m = 0
	for i in range(1, 21):
		li = dd[i]
		if li != []:
			mi = min(li)
			ls = [j - mi for j in li if j - mi != 0]
			dd[i + mi] += ls
			m += 1
	print(m)


from bisect import bisect_left as bl
from bisect import bisect_right as br
from heapq import heappush, heappop, heapify
import math
from collections import *
from functools import reduce, cmp_to_key
import sys
input = sys.stdin.readline
M = mod = 998244353

def factors(n):
	return sorted(set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0))))

def inv_mod(n):
	return pow(n, mod - 2, mod)

def li():
	return [int(i) for i in input().rstrip('\n').split()]

def st():
	return input().rstrip('\n')

def val():
	return int(input().rstrip('\n'))

def li2():
	return [i for i in input().rstrip('\n')]

def li3():
	return [int(i) for i in input().rstrip('\n')]
for _ in range(val()):
	n = val()
	a = st()
	b = st()
	d = defaultdict(dict)
	ans = 0
	for i in range(n):
		if a[i] == b[i]:
			continue
		if a[i] > b[i]:
			ans = -1
			break
		if a[i] not in d:
			d[a[i]] = {}
		if b[i] not in d[a[i]]:
			d[a[i]][b[i]] = 0
		d[a[i]][b[i]] += 1
	if ans == -1:
		print(ans)
		continue
	ans = 0
	chars = 'abcdefghijklmnopqrstuvwxyz'
	visited = {}
	for i in range(26):
		if not len(d[chars[i]]):
			continue
		for j in range(i + 1, 26):
			if chars[j] not in d[chars[i]]:
				continue
			if (i, j) in visited:
				continue
			done = 0
			for k in range(i, j):
				if chars[k] in d[chars[i]]:
					d[chars[k]][chars[j]] = 1
					visited[i, k] = 1
					done = 1
					break
			if not done:
				visited[i, j] = 1
	print(len(visited))


import math
import bisect
import copy
import time
from collections import Counter
for _ in range(int(input())):
	n = int(input())
	x = list(input())
	y = list(input())
	f = n
	c = 0
	kk = 0
	ss = [chr(i) for i in range(97, 97 + 26)]
	p = 0
	for i in range(len(x)):
		if x[i] > y[i]:
			p = 1
			break
	if p:
		print(-1)
		continue
	p = 0
	for i in range(len(ss)):
		h = []
		for j in range(len(x)):
			if x[j] == ss[i] and y[j] != ss[i] and (x[j] != y[j]):
				h.append(y[j])
		if len(h) > 0:
			m = min(h)
			for j in range(len(x)):
				if x[j] == ss[i] and x[j] != m and (x[j] != y[j]):
					p = 1
					x[j] = m
		if p:
			c += 1
		p = 0
	print(c)


from collections import defaultdict
p = 'abcdefghijklmnopqrst'
for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			print(-1)
			break
	else:
		lis = list(zip(b, a))
		lis.sort(key=lambda x: x[0])
		a = []
		b = []
		for i in lis:
			b.append(i[0])
			a.append(i[1])
		d = defaultdict(list)
		for i in range(n):
			if a[i] != b[i]:
				d[a[i]].append(i)
		c = 0
		for i in range(n):
			if a[i] == b[i]:
				continue
			c += 1
			x = a[i]
			for j in d[x]:
				if b[i] != b[j]:
					d[b[i]].append(j)
				a[j] = b[i]
		print(c)


import heapq
import sys
input = sys.stdin.readline
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	flag = 0
	a = list(a)
	b = list(b)
	d = {}
	s = set()
	for i in range(n):
		if a[i] == b[i]:
			s.add(i)
			continue
		if a[i] > b[i]:
			flag = 1
			break
		x = a[i]
		y = b[i]
		if x in d:
			d[x] = min(d[x], y)
		else:
			d[x] = y
	if flag:
		sys.stdout.write(str(-1) + '\n')
		continue
	ans = 0
	for j in range(20):
		if chr(97 + j) not in d:
			continue
		ans += 1
		change = d[chr(97 + j)]
		for i in range(n):
			if i in s:
				continue
			if a[i] == chr(97 + j):
				if change == b[i]:
					s.add(i)
					continue
				else:
					a[i] = change
					if change in d:
						d[change] = min(d[change], b[i])
					else:
						d[change] = b[i]
	sys.stdout.write(str(ans) + '\n')


T = int(input())
alpha = 'abcdefghijklmnopqrst'
for case in range(T):
	i = int(input())
	s1 = input()
	s2 = input()
	maps = {}
	nosol = False
	for (e1, e2) in zip(s1, s2):
		if e2 < e1:
			print('-1')
			nosol = True
			break
		elif e1 < e2:
			try:
				maps[e1].add(e2)
			except:
				maps[e1] = set()
				maps[e1].add(e2)
	if nosol:
		continue
	ret = 0
	for al in alpha:
		if al in maps:
			move = min(maps[al])
			ret += 1
			for al2 in maps[al]:
				if al2 != move:
					try:
						maps[move].add(al2)
					except:
						maps[move] = set()
						maps[move].add(al2)
			del maps[al]
	print(ret)


import sys
from random import *
from bisect import *
from heapq import *
pl = 1
from math import gcd, sqrt
from copy import *
sys.setrecursionlimit(10 ** 5)
if pl:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('outpt.txt', 'w')

def li():
	return [int(xxx) for xxx in input().split()]

def fi():
	return int(input())

def si():
	return list(input().rstrip())

def mi():
	return map(int, input().split())
t = int(input())

def f(i):
	return ord(i) - ord('a')

def dfs(i):
	vis[i] = 1
	ans = 0
	for j in g[i]:
		if vis[j] == 0:
			ans += dfs(j) + 1
	return ans
while t > 0:
	t -= 1
	n = fi()
	a = si()
	b = si()
	g = [set() for i in range(27)]
	flag = 0
	for i in range(n):
		if a[i] > b[i]:
			flag = 1
			break
		if a[i] != b[i]:
			g[f(a[i])].add(f(b[i]))
			g[f(b[i])].add(f(a[i]))
	for i in range(26):
		g[i] = list(g[i])
		g[i].sort()
	vis = [0] * 26
	ans = 0
	for i in range(26):
		if vis[i] == 0:
			ans += dfs(i)
	print(ans if flag == 0 else -1)


from collections import deque
T = int(input())
for test in range(T):
	N = int(input())
	(A, B) = (input(), input())
	nodes = 'abcdefghijklmnopqrst'
	edges = {c1: {c2: False for c2 in nodes} for c1 in nodes}
	valid = True
	for i in range(N):
		if A[i] > B[i]:
			valid = False
		else:
			edges[A[i]][B[i]] = True
			edges[B[i]][A[i]] = True
	if not valid:
		print(-1)
	else:
		ans = 0
		vis = set()
		for root in nodes:
			if root not in vis:
				group = set()
				q = deque([root])
				vis.add(root)
				group.add(root)
				while len(q) > 0:
					curr = q.popleft()
					for adj in nodes:
						if edges[curr][adj] and adj not in vis:
							q.append(adj)
							vis.add(adj)
							group.add(adj)
				ans += len(group) - 1
		print(ans)


from __future__ import division, print_function
import os, sys
from io import BytesIO, IOBase
if sys.version_info[0] < 3:
	from __builtin__ import xrange as range
	from future_builtins import ascii, filter, hex, map, oct, zip
from bisect import bisect_left as lower_bound, bisect_right as upper_bound

def so():
	return int(input())

def st():
	return input()

def mj():
	return map(int, input().strip().split(' '))

def msj():
	return map(str, input().strip().split(' '))

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

def lebe():
	return list(map(int, input()))

def dmain():
	sys.setrecursionlimit(1000000)
	threading.stack_size(1024000)
	thread = threading.Thread(target=main)
	thread.start()

def joro(L):
	return ''.join(map(str, L))

def decimalToBinary(n):
	return bin(n).replace('0b', '')

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def read():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')

def tr(n):
	return n * (n + 1) // 2

def iu():
	m = so()
	s = st()
	P = list(s)
	t = st()
	Q = list(t)
	b = set()
	(y, z) = (0, 0)
	for i in range(20):
		for j in range(m):
			if chr(97 + i) == Q[j]:
				if Q[j] > P[j]:
					b.add(P[j])
				elif P[j] > Q[j]:
					y = 1
					print(-1)
					break
		for ut in range(m):
			if P[ut] in b:
				P[ut] = chr(97 + i)
		r = len(b)
		z = z + r
		b = set()
		if y == 1:
			break
	if y == 0:
		print(z)

def main():
	for i in range(so()):
		iu()
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')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import sys
input = sys.stdin.readline
(inp, ip) = (lambda : int(input()), lambda : [int(w) for w in input().split()])
alp = 'abcdefghijklmnopqrst'
for _ in range(inp()):
	n = inp()
	a = list(input().strip())
	b = list(input().strip())
	flag = 0
	for i in range(n):
		if a[i] > b[i]:
			flag = 1
			break
	if flag:
		print(-1)
		continue
	ans = 0
	for i in alp:
		st = []
		mn = 'z'
		for j in range(n):
			if i == a[j] and a[j] < b[j]:
				st.append(j)
				mn = min(mn, b[j])
		for i in st:
			a[i] = mn
		if st != []:
			ans += 1
	print(ans)


import sys, functools, math, copy

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

def merge(x, y):
	x = find(x)
	y = find(y)
	if x == y:
		return False
	parent[y] = x
	return True
tc = int(sys.stdin.readline())
for _ in range(tc):
	n = int(sys.stdin.readline())
	a = sys.stdin.readline().rstrip()
	b = sys.stdin.readline().rstrip()
	parent = [i for i in range(25)]
	ans = 0
	can = True
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			can = False
			break
		else:
			res = merge(ord(a[i]) - ord('a'), ord(b[i]) - ord('a'))
			if res:
				ans += 1
	if can:
		print(ans)
	else:
		print(-1)


pre = [i for i in range(55)]
cnt = [0] * 55

def Find(x):
	if x == pre[x]:
		return x
	else:
		pre[x] = Find(pre[x])
		return pre[x]

def Join(u, v):
	fu = Find(u)
	fv = Find(v)
	pre[min(fu, fv)] = max(fu, fv)
T = int(input())
for _ in range(T):
	n = int(input())
	a = input()
	b = input()
	f = False
	for i in range(1, 55):
		pre[i] = i
		cnt[i] = 0
	for i in range(n):
		if a[i] == b[i]:
			continue
		if a[i] > b[i]:
			f = True
			break
		Join(int(ord(a[i]) - 96), int(ord(b[i]) - 96))
	if f:
		print('-1')
		continue
	for i in range(1, 21):
		cnt[Find(i)] += 1
	ans = 0
	for i in range(1, 21):
		if cnt[i] >= 2:
			ans += cnt[i] - 1
	print(ans)


from collections import defaultdict
for _ in range(int(input())):
	n = int(input())
	a = list(input().strip())
	b = list(input().strip())
	arr = defaultdict(list)
	f = 0
	for i in range(n):
		if a[i] > b[i]:
			f = 1
			break
		if a[i] != b[i]:
			arr[ord(a[i])].append(b[i])
	print()
	if f:
		print(-1)
		continue
	i = 97
	ans = 0
	while i <= ord('t'):
		arr[i].sort(reverse=True)
		if len(arr[i]) != 0:
			m = arr[i][-1]
			while len(arr[i]) != 0 and arr[i][-1] == m:
				arr[i].pop()
			arr[ord(m)] += arr[i]
			ans += 1
		i += 1
	print(ans)


import sys, math
import io, os
from bisect import bisect_left as bl, bisect_right as br, insort
from heapq import heapify, heappush, heappop
from collections import defaultdict as dd, deque, Counter

def data():
	return sys.stdin.readline().strip()

def mdata():
	return list(map(int, data().split()))

def outl(var):
	sys.stdout.write('\n'.join(map(str, var)) + '\n')

def out(var):
	sys.stdout.write(str(var) + '\n')
from fractions import Fraction
INF = float('inf')
mod = int(1000000000.0) + 7
for t in range(int(data())):
	n = int(data())
	a = list(data())
	b = list(data())
	d = dd(list)
	flag = True
	for i in range(n):
		if a[i] > b[i]:
			flag = False
			break
		elif a[i] < b[i]:
			d[b[i]].append(a[i])
			d[a[i]].append(b[i])
	if flag == False:
		out(-1)
	else:
		l = list(d.keys())
		v = dd(int)
		ans = 0
		for i in l:
			if v[i] == 0:
				s = [i]
				v[i] = 1
				while s:
					a = s.pop()
					for i in d[a]:
						if v[i] == 0:
							ans += 1
							s.append(i)
							v[i] = 1
		out(ans)


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 math import gcd, ceil

def pre(s):
	n = len(s)
	pi = [0] * n
	for i in range(1, n):
		j = pi[i - 1]
		while j and s[i] != s[j]:
			j = pi[j - 1]
		if s[i] == s[j]:
			j += 1
		pi[i] = j
	return pi

def prod(a):
	ans = 1
	for each in a:
		ans = ans * each
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y
for _ in range(int(input()) if True else 1):
	n = int(input())
	s1 = input()
	s2 = input()
	pos = True
	a = []
	di = [[] for _ in range(20)]
	for i in range(n):
		diff = ord(s2[i]) - ord(s1[i])
		if not diff:
			continue
		if diff < 0:
			pos = False
		a += [diff]
		di[ord(s1[i]) - 97] += [diff]
	if not pos:
		print(-1)
		continue
	ans = 0
	for i in range(20):
		di[i] = sorted(di[i])
		if not di[i]:
			continue
		cur = di[i][0]
		ans += 1
		for each in di[i]:
			if each == cur:
				continue
			else:
				di[i + cur] += [each - cur]
	print(ans)


import sys

def inp():
	inp = input().split()
	if len(inp) == 1:
		return int(inp[0])
	else:
		return (int(i) for i in inp)

def inplist():
	inp = input().split()
	for i in range(len(inp)):
		inp[i] = int(inp[i])
	return inp
testcases = inp()
chars = 'abcdefghijklmnopqrst'
for testcase in range(testcases):
	n = inp()
	a = input()
	b = input()
	l = [[] for i in chars]
	fail = False
	for i in range(n):
		inda = chars.index(a[i])
		indb = chars.index(b[i])
		if indb < inda:
			print(-1)
			fail = True
			break
		if indb > inda:
			l[chars.index(a[i])].append(chars.index(b[i]) - chars.index(a[i]))
	if fail:
		continue
	ans = 0
	for i in range(20):
		if l == [[] for i in chars]:
			break
		if l[i] == []:
			continue
		m = min(l[i])
		for j in l[i]:
			if j != m:
				l[i + m].append(j - m)
		ans += 1
	print(ans)


t = int(input())
for j in range(t):
	n = int(input())
	a = input()
	b = input()
	gr = dict(list())
	flag = 0
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			flag = 1
			break
		if gr.get(a[i], 0) == 0:
			gr[a[i]] = []
		if gr.get(b[i], 0) == 0:
			gr[b[i]] = []
		gr[a[i]].append(b[i])
		gr[b[i]].append(a[i])
	if flag == 1:
		print(-1)
	else:
		ans = 0
		visited = [0 for i in range(20)]

		def dfs(ii):
			visited[ii - ord('a')] = 1
			for j in gr.get(chr(ii), []):
				if visited[ord(j) - ord('a')] == 0:
					dfs(ord(j))
		for i in range(ord('a'), ord('t') + 1):
			if visited[i - ord('a')] != 1:
				dfs(i)
				ans += 1
		print(20 - ans)


for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	flag = False
	dic = {}
	N_L = []
	pos = 'abcdefghijklmnopqrst'
	for i in range(n):
		if a[i] > b[i]:
			flag = True
			break
		if a[i] == b[i]:
			continue
		if a[i] not in dic:
			dic[a[i]] = {}
		dic[a[i]][b[i]] = True
		N_L.append((a[i], b[i]))
	if flag:
		print(-1)
	else:
		ans = 0
		l1 = list(dic.keys())
		l1.sort()
		for i in pos:
			if i in dic:
				if len(dic[i]) > 0:
					ans += 1
				mi = 'u'
				for j in dic[i]:
					if mi > j:
						mi = j
				if mi not in dic:
					dic[mi] = {}
				for k in dic[i]:
					if k != mi:
						dic[mi][k] = True
		print(ans)


def _find(st, u):
	ls = []
	while st[u] != u:
		ls.append(u)
		u = st[u]
	for v in ls:
		st[v] = u
	return u

def _union(st, u, v):
	(su, sv) = (_find(st, u), _find(st, v))
	if su != sv:
		st[su] = sv
	return su != sv
T = int(input())
for _ in range(T):
	n = int(input())
	(a, b) = (input(), input())
	st = {chr(u): chr(u) for u in range(ord('a'), ord('t') + 1)}
	(ok, cc) = (1, 0)
	for (ca, cb) in zip(a, b):
		if ca > cb:
			ok = 0
			break
		elif cb > ca:
			cc += _union(st, ca, cb)
	print(cc if ok else -1)


t = int(input())
while t:
	t -= 1
	n = int(input())
	a = input()
	b = input()
	flag = True
	for (i, j) in zip(a, b):
		if j < i:
			flag = False
			break
	if not flag:
		print(-1)
		continue
	arr = [[0 for j in range(26)] for i in range(26)]
	for (i, j) in zip(a, b):
		if ord(j) - ord('a') == ord(i) - ord('a'):
			continue
		arr[ord(i) - ord('a')][ord(j) - ord('a')] += 1
	res = 0
	for i in range(22):
		addin = -1
		for j in range(i + 1, 26):
			if arr[i][j] != 0:
				res += 1
				addin = j
				arr[i][j] = 0
				break
		if addin == -1:
			continue
		for j in range(addin + 1, 26):
			arr[addin][j] += arr[i][j]
	print(res)


ans = []
for stp in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	for i in range(n):
		a[i] = ord(a[i]) - 97
		b[i] = ord(b[i]) - 97
		if a[i] > b[i]:
			ans.append(-1)
			break
	if len(ans) > stp:
		continue
	d = []
	for i in range(20):
		d.append([0] * 20)
	for i in range(n):
		if a[i] == b[i]:
			continue
		d[a[i]][b[i]] += 1
	ansi = 0
	for i in range(20):
		for j in range(20):
			if d[i][j] != 0:
				ind = j
				break
		else:
			continue
		for j in range(ind + 1, 20):
			d[ind][j] += d[i][j]
		ansi += 1
	ans.append(ansi)
print('\n'.join(map(str, ans)))


import os
import heapq
import sys
import math
import operator
from collections import defaultdict, deque
from io import BytesIO, IOBase

def inpt():
	return [int(k) for k in input().split()]

def main():
	for _ in range(int(input())):
		n = int(input())
		ar = list(input())
		br = list(input())
		ans = 0
		bad = False
		for i in range(n):
			if ar[i] > br[i]:
				bad = True
				break
		if bad:
			print(-1)
			continue
		for i in range(20):
			mn = 'z'
			ok = True
			for j in range(n):
				if chr(i + 97) == ar[j] and ar[j] != br[j]:
					ok = False
					mn = min(br[j], mn)
			if not ok:
				ans += 1
				for j in range(n):
					if ar[j] == chr(i + 97) and ar[j] != br[j]:
						ar[j] = mn
		print(ans)
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')
main()


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
for _ in range(int(input())):
	n = int(input())
	s = list(input())
	t = input()
	f = 0
	d = {}
	ls = [[]] * 26
	for i in range(n):
		if ord(s[i]) > ord(t[i]):
			f = 1
			break
	cnt = 0
	if f == 1:
		print(-1)
	else:
		for val in range(97, ord('t') + 1):
			char = chr(val)
			ls = []
			y = 'z'
			for i in range(n):
				if s[i] == char and t[i] > s[i]:
					ls.append(i)
					y = min(t[i], y)
			if ls != []:
				cnt += 1
				for j in ls:
					s[j] = y
		print(cnt)


import sys
from random import *
from bisect import *
from heapq import *
pl = 1
from math import gcd, sqrt
from copy import *
sys.setrecursionlimit(10 ** 5)
if pl:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('outpt.txt', 'w')

def li():
	return [int(xxx) for xxx in input().split()]

def fi():
	return int(input())

def si():
	return list(input().rstrip())

def mi():
	return map(int, input().split())
t = int(input())

def f(i):
	return ord(i) - ord('a')

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

def union(x, y, a):
	(xs, ys) = (find(x, a), find(y, a))
	if xs != ys:
		a[ys] = xs
		return 1
	return 0
while t > 0:
	t -= 1
	n = fi()
	a = si()
	b = si()
	g = [i for i in range(27)]
	flag = ans = 0
	for i in range(n):
		if a[i] > b[i]:
			flag = 1
			break
		if a[i] != b[i]:
			ans += union(f(a[i]), f(b[i]), g)
	print(ans if flag == 0 else -1)


st = 'abcdefghijklmnopqrst'
dic = {}
for i in range(20):
	dic[st[i]] = i
for _ in range(int(input())):
	n = int(input())
	aa = list(input())
	bb = list(input())
	flag = True
	for i in range(n):
		if dic[bb[i]] < dic[aa[i]]:
			flag = False
			break
	ans = 0
	if flag:
		for i in st:
			li = []
			ind = []
			for j in range(n):
				if aa[j] != bb[j] and aa[j] == i:
					ind.append(j)
					li.append(bb[j])
			if li:
				xx = min(li)
				for j in ind:
					aa[j] = xx
				ans += 1
		print(ans)
	else:
		print(-1)


import collections
import copy

def transitions(changes):
	t = collections.defaultdict(set)
	for (i, j) in changes:
		t[i].add(j)
		t[i].add(i)
	while True:
		u = copy.deepcopy(t)
		for i in t:
			for j in t[i]:
				u[i].update(u[j])
		if u == t:
			break
		t = u
	return t

def main():
	t = int(input())
	for _ in range(t):
		n = int(input())
		a = input()
		b = input()
		changes = sorted(set(zip(a, b)))
		if any((i > j for (i, j) in changes)):
			print(-1)
		else:
			trans = collections.defaultdict(set)
			for (i, j) in zip(a, b):
				if i != j:
					trans[i].add(j)
			ans = 0
			while True:
				if len(trans) == 0:
					break
				i = sorted(trans)[0]
				j = sorted(trans[i])[0]
				trans[i].remove(j)
				trans[j].update(trans[i])
				del trans[i]
				if len(trans[j]) == 0:
					del trans[j]
				ans += 1
			print(ans)
main()


import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction
mod = 10 ** 9 + 7
mod1 = 998244353
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')
for ik in range(int(input())):
	n = int(input())
	s1 = input()
	l = input()
	tr2 = defaultdict(set)
	tr1 = defaultdict(set)
	f = 0
	for i in range(n):
		if s1[i] > l[i]:
			print(-1)
			f = 1
			break
		elif s1[i] == l[i]:
			continue
		else:
			tr2[s1[i]].add(l[i])
			tr1[l[i]].add(s1[i])
	if f == 1:
		continue
	ans = 0
	for i in sorted(tr2.keys(), reverse=True):
		ans += len(tr2[i])
		for j in tr2[i]:
			for k in sorted(tr2.keys()):
				if i == k:
					break
				if j in tr2[k]:
					tr2[k].remove(j)
					tr2[k].add(i)
	print(ans)


from collections import defaultdict

def solve():
	n = int(input())
	A = list(map(ord, input()))
	B = list(map(ord, input()))
	extra = defaultdict(list)
	c = [B[i] - A[i] for i in range(n)]
	if min(c) < 0:
		print(-1)
	else:
		for i in range(n):
			if c[i] != 0:
				extra[A[i]].append(c[i])
		ops = 0
		for a in range(ord('a'), ord('t') + 1):
			if a not in extra:
				continue
			diff = extra[a]
			if len(diff) == 1:
				ops += 1
			else:
				min_dif = min(diff)
				ops += 1
				new = [d - min_dif for d in diff if d != min_dif]
				if len(new) > 0:
					extra[a + min_dif].extend(new)
		print(ops)
t = int(input())
for test in range(t):
	solve()


import sys
import heapq, functools, collections
import math, random
from collections import Counter, defaultdict

def solve(arr, brr):
	console('----- solving ------')
	console(arr)
	console(brr)
	abc = dict(((ab, idx) for (idx, ab) in enumerate('abcdefghijklmnopqrst')))
	crr = []
	drr = []
	for (a, b) in zip(arr, brr):
		if a > b:
			return -1
		if a != b:
			crr.append(abc[a])
			drr.append(abc[b])
	console(crr)
	console(drr)
	if len(crr) == 0:
		return 0
	d = defaultdict(set)
	for (a, b) in zip(crr, drr):
		d[a].add(b)
		d[b].add(a)
	console(d)
	visited = [False for _ in range(len(abc))]
	idx = 1
	for k in [x for x in d.keys()]:
		if visited[k]:
			continue
		idx += 1
		visited[k] = idx
		stack = [x for x in d[k]]
		while stack:
			cur = stack.pop()
			visited[cur] = idx
			for nex in d[cur]:
				if visited[nex]:
					continue
				visited[nex] = idx
				stack.append(nex)
		console(d)
	console(visited)
	return sum([a - 1 for a in Counter([x for x in visited if x]).values()])

def console(*args):
	return
for case_num in range(int(input())):
	_ = int(input())
	a = input()
	b = input()
	res = solve(a, b)
	print(res)


t = int(input())
for _ in range(t):
	n = int(input())
	a = input()
	b = input()
	count = [[0 for i in range(20)] for j in range(20)]
	ok = True
	for i in range(n):
		count[ord(a[i]) - ord('a')][ord(b[i]) - ord('a')] += 1
		if ord(a[i]) > ord(b[i]):
			ok = False
	if ok:
		ans = 0
		for i in range(20):
			mini = 20
			for j in range(i + 1, 20):
				if count[i][j] > 0:
					mini = min(mini, j)
			if mini < 20:
				ans += 1
				for j in range(mini + 1, 20):
					if count[i][j] > 0:
						count[mini][j] += 1
		print(ans)
	else:
		print(-1)


import sys
input = sys.stdin.readline
t = int(input())
letters = 'abcdefghijklmnopqrst'
letters_index = {}
for let in letters:
	letters_index[let] = letters.index(let)
for _ in range(t):
	l = int(input())
	a = input().rstrip()
	b = input().rstrip()
	used = {}
	an = ''
	bn = ''
	for j in range(len(a)):
		if (a[j], b[j]) in used:
			pass
		else:
			an += a[j]
			bn += b[j]
			used[a[j], b[j]] = 1
	a = an
	b = bn
	nogo = 0
	for j in range(len(a)):
		x = letters_index[b[j]] - letters_index[a[j]]
		if x < 0:
			nogo = 1
			break
	if nogo == 1:
		print(-1)
	else:
		c = 0
		while a != b:
			tbr = ('z', 999)
			for j in range(len(a)):
				x = letters_index[b[j]] - letters_index[a[j]]
				if x != 0:
					if a[j] < tbr[0]:
						tbr = (a[j], x)
					if x < tbr[1] and a[j] <= tbr[0]:
						tbr = (a[j], x)
			old_l = tbr[0]
			new_l = letters_index[old_l] + tbr[1]
			new_l = letters[new_l]
			av = ''
			bv = ''
			for kk in range(len(a)):
				if a[kk] != b[kk]:
					if a[kk] == old_l:
						av += new_l
					else:
						av += a[kk]
					bv += b[kk]
			a = av
			b = bv
			c += 1
		print(c)


def found(x):
	global uf
	temp = x
	while uf[x] != x:
		x = uf[x]
	ans = x
	while uf[temp] != temp:
		parent = uf[temp]
		uf[temp] = ans
		temp = parent
	return ans
inp = lambda : list(map(lambda x: ord(x) - 97, list(input())))
t = int(input())
for _ in range(t):
	n = int(input())
	a = inp()
	b = inp()
	res = 0
	for i in range(n):
		if a[i] > b[i]:
			res = -1
			break
	if res == -1:
		print(-1)
		continue
	edges = [[] for _ in range(20)]
	for i in range(n):
		if a[i] != b[i] and (not b[i] in edges[a[i]]):
			edges[a[i]].append(b[i])
	uf = [i for i in range(20)]
	for i in range(20):
		if len(edges[i]) == 0:
			continue
		for j in edges[i]:
			temp1 = found(i)
			temp2 = found(j)
			if temp1 != temp2:
				uf[temp1] = temp2
				res += 1
	print(res)


T = int(input())
for _ in range(T):
	N = int(input())
	S = input()
	T = input()
	if any((a > b for (a, b) in zip(S, T))):
		print(-1)
		continue
	s = set()
	for (a, b) in zip(S, T):
		if a == b:
			continue
		s.add(a + b)
	ans = 0
	while s:
		m = min(s)
		ans += 1
		t = set()
		for (a, b) in s:
			if a != m[0]:
				t.add(a + b)
				continue
			if m[1] == b:
				continue
			t.add(m[1] + b)
		s = t
	print(ans)


for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			break
	else:
		s = sorted(list(set(a) | set(b)))
		ans = 0
		for j in s:
			f = False
			x = set()
			for k in range(n):
				if a[k] == j and a[k] != b[k]:
					x.add(b[k])
					f = True
			x = sorted(list(x))
			for k in range(n):
				if a[k] == j and a[k] != b[k]:
					a[k] = x[0]
			if f:
				ans += 1
		print(ans)