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:

  selects some subset of positions $p_1, p_2, \ldots, p_k$ ($k \ge 1; 1 \le p_i \le n; p_i \neq p_j$ if $i \neq j$) of $A$ such that $A_{p_1} = A_{p_2} = \ldots = A_{p_k} = x$ (ie. all letters on this positions are equal to some letter $x$).

  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$).

  sets each letter in positions $p_1, p_2, \ldots, p_k$ to letter $y$. More formally: for each $i$ ($1 \le i \le 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 \le t \le 10$) — the number of test cases. Description of the test cases follows.

The first line of each test case contains one integer $n$ ($1 \le n \le 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:   selects positions $1$ and $2$ and sets $A_1 = A_2 = $ b ($\color{red}{aa}b \rightarrow \color{blue}{bb}b$).  selects positions $2$ and $3$ and sets $A_2 = A_3 = $ c ($b\color{red}{bb} \rightarrow 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:   selects position $1$ and sets $A_1 = $ t ($\color{red}{a}bc \rightarrow \color{blue}{t}bc$).  selects position $2$ and sets $A_2 = $ s ($t\color{red}{b}c \rightarrow t\color{blue}{s}c$).  selects position $3$ and sets $A_3 = $ r ($ts\color{red}{c} \rightarrow ts\color{blue}{r}$).

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Graph algorithms

String algorithms

Sorting

Amortized analysis

Greedy algorithms

Tree algorithms

Spanning trees


Solutions:
from collections import defaultdict

def change(u, j):
	while j in u:
		j = u[j]
	return j
for _ in range(int(input())):
	n = int(input())
	a = input().strip()
	b = input().strip()
	c = defaultdict(dict)
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			break
		if a[i] != b[i]:
			c[b[i]][a[i]] = 1
	else:
		u = defaultdict(str)
		ans = 0
		for i in sorted(c):
			for j in list(c[i]):
				cj = change(u, j)
				c[i][cj] = 1
				if cj != j:
					c[i][j] = 0
			for j in c[i]:
				ans += 1 if c[i][j] else 0
				u[j] = i
		print(ans)


def count(a, b, length, result):
	for i in range(len(a)):
		if a[i] > b[i]:
			return -1
		if a[i] == b[i]:
			a[i] = b[i] = 1000
	if a == b:
		return result
	k = min(b)
	j = b.index(k)
	save = a[j]
	for i in range(len(a)):
		if a[i] == save:
			a[i] = k
	return count(a, b, length, result + 1)
for _ in range(int(input())):
	k = input()
	a = input()
	b = input()
	a = list(map(ord, a))
	b = list(map(ord, b))
	print(count(a, b, k, 0))


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
from collections import defaultdict as dd
from collections import deque
from functools import *
from fractions import Fraction as f
from copy import *
from bisect import *
from heapq import *
from math import *
from itertools import permutations

def eprint(*args):
	print(*args, file=sys.stderr)
zz = 1
if zz:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('all.txt', 'w')

def inc(d, c):
	d[c] = d[c] + 1 if c in d else 1

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

def fli():
	return [float(x) for x in input().split()]

def comp(a, b):
	if a > b:
		return 2
	return 2 if a == b else 0

def gi():
	return [xx for x in input().split()]

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

def pro(a):
	return reduce(lambda a, b: a * b, a)

def swap(a, i, j):
	(a[i], a[j]) = (a[j], a[i])

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

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

def gh():
	sys.stdout.flush()

def graph(n, m):
	for i in range(m):
		(x, y) = mi()
		a[x].append(y)
		a[y].append(x)

def bo(i):
	return ord(i) - ord('a')
t = fi()

def find(a, i):
	if a[i] == i:
		return i
	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:
		return True
	a[ys] = xs
	return False
while t > 0:
	t -= 1
	n = fi()
	s = si()
	p = si()
	l = []
	a = [i for i in range(21)]
	flag = ans = 0
	r = set()
	ss = set()
	for i in range(n):
		if s[i] == p[i]:
			continue
		if s[i] > p[i]:
			ans = -1
			break
		if union(a, bo(s[i]), bo(p[i])):
			continue
		ans += 1
	print(ans)


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

def input():
	return sys.stdin.readline().rstrip()

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 + 1) 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):
		return {r: self.members(r) for r in self.roots()}

def slv():
	n = int(input())

	def f(x):
		return ord(x) - ord('a') + 1
	strA = input()
	strB = input()
	A = [int(ord(c) - ord('a') + 1) for c in strA]
	B = [int(ord(c) - ord('a') + 1) for c in strB]
	if any((A[i] > B[i] for i in range(n))):
		print(-1)
		return
	ans = 0
	dsu = UnionFind(21)
	for (u, v) in zip(A, B):
		if u < v:
			dsu.union(u, v)
	for root in dsu.roots():
		ans += dsu.size(root) - 1
	print(ans)
	return

def main():
	t = int(input())
	for _ in range(t):
		slv()
	return
main()


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)


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
t = int(input())
for ii in range(t):
	n = int(input())
	a = [i for i in input() if i != '\n']
	b = [i for i in input() if i != '\n']
	dicta = dict()
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			break
		if a[i] == b[i]:
			continue
		elif a[i] in dicta:
			dicta[a[i]].add(b[i])
		else:
			dicta[a[i]] = {b[i]}
	else:
		ans = 0
		for i in 'abcdefghijklmnopqrst':
			if i in dicta and dicta[i] != set():
				ans += 1
				pq = min(dicta[i])
				if pq in dicta:
					for j in dicta[i]:
						if j != pq:
							dicta[pq].add(j)
				else:
					dicta[pq] = set()
					for j in dicta[i]:
						if j != pq:
							dicta[pq].add(j)
		print(ans)


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)


import sys
readline = sys.stdin.buffer.readline
ns = lambda : readline().rstrip()
ni = lambda : int(readline().rstrip())
nm = lambda : map(int, readline().split())
nl = lambda : list(map(int, readline().split()))

class UnionFind:

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

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

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return False
		if self.ps[x] > self.ps[y]:
			(x, y) = (y, x)
		self.ps[x] += self.ps[y]
		self.ps[y] = x
		return True

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

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

def solve():
	n = ni()
	uf = UnionFind(150)
	a = list(ns())
	b = list(ns())
	ans = 0
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			return
		if not uf.same(a[i], b[i]):
			ans += 1
			uf.unite(a[i], b[i])
	print(ans)
	return
T = ni()
for _ in range(T):
	solve()


from sys import stdin
input = lambda : stdin.readline().strip()
from collections import deque as d
l = len
for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	cont = True
	c = 0
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			cont = False
			break
	if cont:
		for ch in range(97, 97 + 20):
			x = []
			m = 117
			for i in range(n):
				if a[i] == chr(ch) and a[i] != b[i]:
					x.append(i)
					m = min(m, ord(b[i]))
			if x:
				c += 1
				for i in x:
					a[i] = chr(m)
		print(c)


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)


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)


t = int(input())
for _ in range(t):
	n = int(input())
	s1 = input()
	s2 = input()
	cur = chr(ord('a') - 1)
	flag = 0
	for i in range(n):
		if s1[i] > s2[i]:
			flag = 1
			break
	if flag == 0:
		tot = 0
		temp = list(s1)
		for i in range(20):
			cur = chr(ord(cur) + 1)
			l = []
			mini = 'u'
			for j in range(n):
				if temp[j] == cur and temp[j] != s2[j]:
					l.append(j)
					mini = min(mini, s2[j])
			if len(l) > 0:
				tot += 1
				for val in l:
					temp[val] = mini
		print(tot)
	else:
		print(-1)


import sys
input = sys.stdin.readline
a = ord('a')
for _ in range(int(input())):
	N = int(input())
	A = list(input())[:-1]
	B = list(input())[:-1]
	table = [[0] * 20 for _ in range(21)]
	for i in range(N):
		if A[i] > B[i]:
			break
		table[ord(A[i]) - a][ord(B[i]) - a] += 1
	else:
		res = 0
		for i in range(20):
			x = i + 1
			for j in range(i + 1, 20):
				x = j
				if table[i][j]:
					break
			else:
				continue
			res += 1
			for j in range(i + 1, 20):
				table[x][j] += table[i][j]
				table[i][j] = 0
		print(res)
		continue
	print(-1)


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)


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


I = lambda : list(map(int, input().split()))
import collections as cc
for tc in range(int(input())):
	(n,) = I()
	s = list(input())
	t = list(input())
	tf = 1
	for i in range(n):
		if s[i] > t[i]:
			tf = 0
			break
	if not tf:
		print(-1)
		continue
	else:
		ans = 1
		for i in 'abcdefghijklmnopqrst':
			temp = 'u'
			for j in range(n):
				if s[j] == i and s[j] != t[j]:
					temp = min(temp, t[j])
			if temp == 'u':
				continue
			else:
				ans += 1
				for j in range(n):
					if s[j] == i and s[j] != t[j]:
						s[j] = temp
		print(ans - 1)


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)


import sys
input = sys.stdin.readline
t = int(input())
for _ in range(t):
	n = int(input())
	aa = list(input())[:n]
	bb = list(input())[:n]
	a = []
	b = []
	p = True
	array = [[] for i in range(20)]
	for i in range(n):
		if aa[i] == bb[i]:
			continue
		a.append(ord(aa[i]))
		b.append(ord(bb[i]))
		if a[-1] > b[-1]:
			p = False
			break
		array[a[-1] - 97].append(b[-1] - a[-1])
	if not p:
		print(-1)
		continue
	ans = 0
	for i in range(20):
		if not array[i]:
			continue
		s = min(array[i])
		ans += 1
		for j in set(array[i]):
			if j == s:
				continue
			array[i + s].append(j - s)
	print(ans)


def ss(n, a, b):
	for i in range(n):
		if a[i] > b[i]:
			return -1
	ans = n
	p = {chr(i + ord('a')): chr(i + ord('a')) for i in range(20)}
	count = {chr(i + ord('a')): 1 for i in range(20)}
	rank = {chr(i + ord('a')): 0 for i in range(20)}

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

	def union(x, y):
		px = find(x)
		py = find(y)
		rx = rank[px]
		ry = rank[py]
		if rx < ry:
			count[py] += count[px]
			count[px] = 0
			p[px] = py
		elif rx > ry:
			count[px] += count[py]
			count[py] = 0
			p[py] = px
		else:
			p[py] = px
			rank[x] += 1
			count[py] += count[px]
			count[px] = 0
	for i in range(n):
		if a[i] != b[i]:
			if find(a[i]) != find(b[i]):
				union(a[i], b[i])
	for i in count:
		if p[i] != i:
			count[p[i]] += count[i]
			count[i] = 1
	ans = 0
	for i in count:
		ans += max(count[i] - 1, 0)
	return ans
for _ in range(int(input())):
	n = int(input())
	a = str(input())
	b = str(input())
	print(ss(n, a, b))


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 = input()
t = int(t)

def solve(n, A, B):
	answer = 0
	A = [x for x in A]
	B = [x for x in B]
	for i in range(n):
		if A[i] > B[i]:
			return -1
	for ch in range(20):
		char = chr(ch + 97)
		min_y = chr(97 + 20)
		cpk = 0
		for i in range(n):
			if A[i] == char:
				if B[i] < min_y and B[i] > char:
					min_y = B[i]
					cpk = 1
		if cpk == 1:
			answer += 1
		for i in range(n):
			if A[i] == char:
				A[i] = min_y
	return answer
answers = [0 for _ in range(t)]
for i in range(t):
	n = input()
	n = int(n)
	A = input()
	B = input()
	ans = solve(n, A, B)
	answers[i] = ans
for i in range(t):
	print(answers[i])


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


from collections import defaultdict
con = 10 ** 9 + 7
INF = float('inf')

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

def main():
	T = int(input())
	for _ in range(T):
		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
		jud = 'Yes'
		for i in range(N):
			if A[i] > B[i]:
				jud = 'No'
		if jud == 'No':
			print(-1)
		else:
			ans = 0
			for i in range(20):
				L = [0] * 20
				for j in range(N):
					if B[j] == i:
						L[A[j]] = 1
				L[i] = 0
				ans += sum(L)
				for j in range(N):
					if L[A[j]] == 1:
						A[j] = i
			print(ans)
main()


from collections import defaultdict
for _ in range(int(input())):
	n = int(input())
	A = input()
	B = input()
	ls = defaultdict(list)
	flag = 0
	for i in range(n):
		if A[i] != B[i]:
			ls[B[i]].append(i)
		if A[i] > B[i]:
			flag = 1
	if flag == 1:
		print(-1)
		continue
	else:
		for i in ls:
			ls[i] = sorted(ls[i], key=lambda x: A[x])
		lst = sorted(ls.keys())
		res = 0
		for i in lst:
			for j in ls[i]:
				if A[j] != B[j]:
					res += 1
					A = A.replace(A[j], B[j])
		print(res)


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')
import collections
for j in range(int(input())):
	n = int(input())
	vala = [ord(k) - 97 for k in input()]
	valb = [ord(k) - 97 for k in input()]
	broke = False
	graph = [[] for s in range(20)]
	dict1 = {}
	for s in range(20):
		dict1[s] = set([s])
	for s in range(n):
		if not valb[s] in dict1[vala[s]]:
			graph[vala[s]].append(valb[s])
			dict1[vala[s]].add(valb[s])
		if vala[s] > valb[s]:
			broke = True
			break
	if broke == False:
		dict2 = {}
		visited = set([])
		for s in range(20):
			if len(graph[s]) > 0 and (not s in visited):
				queue = collections.deque([])
				vis = set([])
				for b in range(len(graph[s])):
					if not graph[s][b] in vis:
						if not graph[s][b] in visited:
							queue.append(graph[s][b])
						else:
							for k in dict2.keys():
								if graph[s][b] in k:
									vis = vis.union(k)
									dict2.pop(k)
									break
				while len(queue) > 0:
					v0 = queue.popleft()
					if not v0 in vis:
						vis.add(v0)
						for b in range(len(graph[v0])):
							if not graph[v0][b] in vis:
								if not graph[v0][b] in visited:
									queue.append(graph[v0][b])
								else:
									for k in dict2.keys():
										if graph[v0][b] in k:
											vis = vis.union(k)
											dict2.pop(k)
											break
				if len(vis) > 0:
					vis.add(s)
					visited = visited.union(vis)
					vis = frozenset(vis)
					dict2[vis] = len(vis) - 1
		ans = 0
		for s in dict2.keys():
			ans += dict2[s]
	if broke == False:
		print(ans)
	else:
		print(-1)


import os
import sys
from io import BytesIO, IOBase
import heapq as h
from bisect import bisect_left
from types import GeneratorType
BUFSIZE = 8192

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

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.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 = self.os.read(self._fd, max(self.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:
			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')
import time
start_time = time.time()
import collections as col
import math, string
from functools import reduce

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())
MOD = 10 ** 9 + 7

def solve():
	N = getInt()
	A = getStr()
	B = getStr()
	graph = col.defaultdict(set)
	nodes = set()
	for i in range(N):
		if A[i] > B[i]:
			return -1
		if A[i] < B[i]:
			graph[A[i]].add(B[i])
			graph[B[i]].add(A[i])
			nodes.add(A[i])
			nodes.add(B[i])

	def bfs(node):
		flag = False
		visited.add(node)
		nodes.remove(node)
		queue = col.deque([node])
		while queue:
			s = queue.popleft()
			for neighbour in graph[s]:
				if neighbour not in visited:
					visited.add(neighbour)
					queue.append(neighbour)
					nodes.remove(neighbour)
	ans = 0
	while nodes:
		node = next(iter(nodes))
		visited = set()
		bfs(node)
		ans += len(visited) - 1
	return ans
for _ in range(getInt()):
	print(solve())


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)


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 sys
from collections import *
import bisect
import heapq
import string

def ri():
	return int(input())

def rl():
	return list(map(int, input().split()))
t = ri()
alphabet = dict()
for i in range(len(string.ascii_lowercase)):
	letter = string.ascii_lowercase[i]
	alphabet[letter] = i
for _ in range(t):
	n = ri()
	A = input()
	B = input()
	a = []
	b = []
	for letter in A:
		a.append(alphabet[letter])
	for letter in B:
		b.append(alphabet[letter])
	d = defaultdict(list)
	test = 1
	for i in range(n):
		if b[i] < a[i]:
			test = -1
			break
		elif b[i] > a[i]:
			heapq.heappush(d[a[i]], b[i])
	if test == -1:
		print(-1)
	else:
		i = 0
		ans = 0
		while i < 20:
			if d[i]:
				z = heapq.heappop(d[i])
				ans += 1
				for k in d[i]:
					if k != z:
						heapq.heappush(d[z], k)
			i += 1
		print(ans)


import sys, os, io

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().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')
import math, datetime, functools, itertools, operator, bisect, fractions, statistics
from collections import deque, defaultdict, OrderedDict, Counter
from fractions import Fraction
from decimal import Decimal
from sys import stdout
from heapq import heappush, heappop, heapify, _heapify_max, _heappop_max, nsmallest, nlargest
INF = 999999999999999999999999
alphabets = 'abcdefghijklmnopqrstuvwxyz'

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

class SegTree:

	def __init__(self, n):
		self.N = 1 << n.bit_length()
		self.tree = [0] * (self.N << 1)

	def update(self, i, j, v):
		i += self.N
		j += self.N
		while i <= j:
			if i % 2 == 1:
				self.tree[i] += v
			if j % 2 == 0:
				self.tree[j] += v
			(i, j) = (i + 1 >> 1, j - 1 >> 1)

	def query(self, i):
		v = 0
		i += self.N
		while i > 0:
			v += self.tree[i]
			i >>= 1
		return v

def SieveOfEratosthenes(limit):
	isPrime = [True] * (limit + 1)
	isPrime[0] = isPrime[1] = False
	primes = []
	for i in range(2, limit + 1):
		if not isPrime[i]:
			continue
		primes += [i]
		for j in range(i * i, limit + 1, i):
			isPrime[j] = False
	return primes

def main():
	mod = 1000000007
	starttime = datetime.datetime.now()
	if os.path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	tc = 1
	tc = ri()
	for _ in range(tc):
		n = ri()
		a = list(rs())
		b = list(rs())
		flag = 1
		for i in range(n):
			if a[i] > b[i]:
				wi(-1)
				flag = 0
				break
		if flag:
			ans = 0
			for letter in alphabets[:20]:
				mn = 'z'
				pos = []
				flag = 0
				for i in range(n):
					if a[i] == letter and b[i] > a[i]:
						flag = 1
						mn = min(mn, b[i])
						pos.append(i)
				for i in pos:
					a[i] = mn
				if flag:
					ans += 1
			wi(ans)
	endtime = datetime.datetime.now()
	time = (endtime - starttime).total_seconds() * 1000
	if os.path.exists('input.txt'):
		print('Time:', time, 'ms')

class FastReader(io.IOBase):
	newlines = 0

	def __init__(self, fd, chunk_size=1024 * 8):
		self._fd = fd
		self._chunk_size = chunk_size
		self.buffer = io.BytesIO()

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size))
			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, size=-1):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size if size == -1 else size))
			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()

class FastWriter(io.IOBase):

	def __init__(self, fd):
		self._fd = fd
		self.buffer = io.BytesIO()
		self.write = self.buffer.write

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

class FastStdin(io.IOBase):

	def __init__(self, fd=0):
		self.buffer = FastReader(fd)
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class FastStdout(io.IOBase):

	def __init__(self, fd=1):
		self.buffer = FastWriter(fd)
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.flush = self.buffer.flush
sys.stdin = FastStdin()
sys.stdout = FastStdout()
main()


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


def main():
	for i in range(int(input())):
		n = int(input())
		str1 = input()
		str2 = input()
		ch = list(map(lambda i, j: ord(j) - ord(i), str1, str2))
		idx = [[] for _ in range(20)]
		for (i, j) in enumerate(str1):
			idx[ord(j) - 97].append(i)
		if min(ch) < 0:
			print('-1')
		else:
			counter = 0
			for i in range(20):
				k = 20
				for j in idx[i]:
					if ch[j] > 0:
						k = min(k, ch[j])
				if k != 20:
					for j in idx[i]:
						ch[j] -= k
						idx[i + k].append(j)
					counter += 1
			print(counter)
main()


import time, math as mt, bisect, sys
from sys import stdin, stdout
from collections import deque
from fractions import Fraction
from collections import Counter
from collections import OrderedDict
pi = 3.141592653589793

def II():
	return int(stdin.readline())

def IO():
	return stdin.readline()

def IP():
	return map(int, stdin.readline().split())

def L():
	return list(map(int, stdin.readline().split()))

def P(x):
	return stdout.write(str(x) + '\n')

def PI(x, y):
	return stdout.write(str(x) + ' ' + str(y) + '\n')

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

def gcd(a, b):
	if a == 0:
		return b
	elif b == 0:
		return a
	if a > b:
		return gcd(a % b, b)
	else:
		return gcd(a, b % a)

def readTree():
	v = int(input())
	adj = [set() for i in range(v + 1)]
	for i in range(v - 1):
		(u1, u2) = In()
		adj[u1].add(u2)
		adj[u2].add(u1)
	return (adj, v)

def bfs(adj, v):
	visited = [False] * (v + 1)
	q = deque()
	while q:
		pass

def sieve():
	li = [True] * 1000001
	(li[0], li[1]) = (False, False)
	for i in range(2, len(li), 1):
		if li[i] == True:
			for j in range(i * i, len(li), i):
				li[j] = False
	prime = []
	for i in range(1000001):
		if li[i] == True:
			prime.append(i)
	return prime

def setBit(n):
	count = 0
	while n != 0:
		n = n & n - 1
		count += 1
	return count
mx = 10 ** 7
spf = [mx] * (mx + 1)

def SPF():
	spf[1] = 1
	for i in range(2, mx + 1):
		if spf[i] == mx:
			spf[i] = i
			for j in range(i * i, mx + 1, i):
				if i < spf[j]:
					spf[j] = i
	return
mod = 10 ** 9 + 7

def solve(i):
	n = II()
	a = input()
	b = input()
	if a == b:
		P(0)
		return
	else:
		for i in range(n):
			if ord(a[i]) > ord(b[i]):
				P(-1)
				return
		move = 0
		d = {}
		for i in range(n):
			d[a[i]] = d.get(a[i], 0) + 1
		d2 = {}
		for i in range(n):
			d2[a[i], b[i]] = d2.get((a[i], b[i]), 0) + 1
		used = {}
		for i in range(20):
			curr = chr(97 + i)
			if d.get(curr, -1) != -1:
				for j in range(20):
					char = chr(97 + j)
					if d2.get((curr, char), -1) != -1 and curr != char:
						if used.get(curr, -1) != -1:
							d2[used[curr], char] = d2.get((curr, char), 0) + 1
							del d2[curr, char]
						else:
							move += 1
							used[curr] = char
							d[char] = d.get(char, 0) + 1
							del d2[curr, char]
		P(move)
		return
t = II()
for i in range(t):
	solve(i)


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

def dfs(u, mark, g):
	mark[u] = True
	for i in g[u]:
		if mark[i] == False:
			dfs(i, mark, g)

def stringt(a, b, mark, g):
	cnt = 0
	for i in range(0, len(a)):
		if a[i] > b[i]:
			return -1
		g[ord(a[i]) - 97].append(ord(b[i]) - 97)
		g[ord(b[i]) - 97].append(ord(a[i]) - 97)
	ans = 20
	for i in range(20):
		if mark[i] == False:
			dfs(i, mark, g)
			ans -= 1
	return ans

def main():
	for i in range(int(input())):
		n = input().strip()
		a = input().strip()
		b = input().strip()
		mark = [False] * 20
		g = defaultdict(list)
		print(stringt(a, b, mark, g))
threading.stack_size(10 ** 8)
t = threading.Thread(target=main)
t.start()
t.join()


import sys
input = lambda : sys.stdin.readline().rstrip()
T = int(input())
for _ in range(T):
	N = int(input())
	A = [ord(a) - 97 for a in input()]
	B = [ord(a) - 97 for a in input()]
	X = [[0] * 20 for _ in range(20)]
	for (a, b) in zip(A, B):
		X[a][b] = 1
		if a > b:
			print(-1)
			break
	else:
		ans = 0
		for i in range(20):
			for j in range(i + 1, 20):
				if X[i][j]:
					ans += 1
					for jj in range(j + 1, 20):
						if X[i][jj]:
							X[j][jj] = 1
					break
		print(ans)


import sys
input = sys.stdin.readline
t = int(input())
for tests in range(t):
	n = int(input())
	A = input().strip()
	B = input().strip()
	for i in range(n):
		if A[i] > B[i]:
			print(-1)
			break
	else:
		DICT = dict()
		for i in range(n):
			a = A[i]
			b = B[i]
			if a == b:
				continue
			if a in DICT:
				DICT[a].add(b)
			else:
				DICT[a] = {b}
		ANS = 0
		for x in 'abcdefghijklmnopqrst':
			if x in DICT and DICT[x] != set():
				ANS += 1
				MIN = min(DICT[x])
				if MIN in DICT:
					DICT[MIN] = DICT[MIN] | DICT[x] - {MIN}
				else:
					DICT[MIN] = DICT[x] - {MIN}
		print(ANS)


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)


from collections import defaultdict
t = int(input())
for _ in range(t):
	n = int(input())
	s1 = input()
	s2 = input()
	cnt = 0
	d = defaultdict(str)
	possible = True
	s1 = list(s1)
	s2 = list(s2)
	while True:
		f = False
		last_bad = 'z'
		for (c1, c2) in zip(s1, s2):
			if c1 != c2:
				if c1 > c2:
					possible = False
					break
				f = True
				if not d[c1]:
					d[c1] = c2
				else:
					d[c1] = min(d[c1], c2)
				last_bad = min(last_bad, c1)
		if not possible:
			break
		if not f:
			break
		for (i, z) in enumerate(zip(s1, s2)):
			(c1, c2) = z
			if c1 != c2 and c1 == last_bad:
				s1[i] = d[c1]
		cnt += 1
	print(-1 if not possible else cnt)


for _ in range(int(input())):
	n = int(input())
	a = [ord(c) - ord('a') for c in input()]
	b = [ord(c) - ord('a') for c in input()]
	imp = False
	for i in range(n):
		if b[i] < a[i]:
			print(-1)
			imp = True
			break
	if imp:
		continue
	cnt = 0
	for i in range(21):
		s = []
		for j in range(n):
			ac = a[j]
			bc = b[j]
			if ac == i and ac < bc:
				s.append(j)
		if s:
			cnt += 1
			mn = min(map(lambda o: b[o], s))
			for j in s:
				a[j] = mn
	print(cnt)


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)


def find_set(v):
	if v == pa[v]:
		return v
	pa[v] = find_set(pa[v])
	return pa[v]
for _ in range(int(input())):
	n = int(input())
	s1 = input()
	s2 = input()
	flag = True
	for i in range(n):
		if s1[i] > s2[i]:
			flag = False
			print(-1)
			break
	if flag:
		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
				pa[b] = a
		print(ans)


from sys import stdin, stdout

def ufind(ua, i):
	if ua[i] == i:
		return i
	ua[i] = ufind(ua, ua[i])
	return ua[i]

def union(ua, i, j):
	res = 0
	ri = ufind(ua, i)
	rj = ufind(ua, j)
	if ri != rj:
		res = 1
		ua[ri] = rj
	return res

def string_transformation_1(n, A, B):
	ans = 0
	ua = [i for i in range(20)]
	for i in range(n):
		a = ord(A[i]) - ord('a')
		b = ord(B[i]) - ord('a')
		if a > b:
			return -1
		ans += union(ua, a, b)
	return ans
t = int(stdin.readline())
for _ in range(t):
	n = int(stdin.readline())
	A = stdin.readline().strip()
	B = stdin.readline().strip()
	ans = string_transformation_1(n, A, B)
	stdout.write(str(ans) + '\n')


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)


import sys

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().split()))

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

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

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

def solve(n, a, b):
	d = {}
	for i in range(n):
		c = a[i]
		if c not in d:
			d[c] = set()
		d[c].add(i)
	bb = sorted([(b[i], i) for i in range(n)])
	ans = 0
	for idx in range(n):
		(bi, i) = bb[idx]
		for (ai, v) in d.items():
			if i in v:
				break
		if ai == bi:
			continue
		if ai > b[i]:
			return -1
		ii = [vi for vi in v if b[vi] >= bi]
		for iii in ii:
			v.remove(iii)
		if bi not in d:
			d[bi] = set()
		d[bi].update(ii)
		if len(v) == 0:
			del d[ai]
		ans += 1
	return ans

def main():
	for _ in range(ri()):
		n = ri()
		a = rs()
		b = rs()
		wi(solve(n, a, b))
main()


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)


par = [0] * 26
ans = 0

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

def unite(x, y):
	global ans
	x = find(x)
	y = find(y)
	if x != y:
		par[x] = y
		ans += 1
for i in range(int(input())):
	n = int(input())
	ans = 0
	for i in range(26):
		par[i] = i
	s1 = input()
	s2 = input()
	for i in range(n):
		if s1[i] > s2[i]:
			ans = -1
			break
		unite(ord(s1[i]) - ord('a'), ord(s2[i]) - ord('a'))
	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)


import sys
import os, io
input = sys.stdin.readline

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

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

def print_list(l):
	print(' '.join(map(str, l)))
from collections import defaultdict as dc
N = int(input())
for _ in range(N):
	n = int(input())
	a = input().strip()
	b = input().strip()
	flag = True
	dic = dc(set)
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			flag = False
			break
		if a[i] != b[i]:
			dic[b[i]].add(a[i])
			dic[a[i]].add(b[i])
	if flag:
		all_points = set(dic.keys())
		res = len(all_points)
		count = 0
		while all_points:
			count += 1
			now = set()
			now.add(all_points.pop())
			while now and all_points:
				node = now.pop()
				tmp = dic[node] & all_points
				all_points -= tmp
				now |= tmp
		print(res - count)


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)


def tits(a, b, n):
	for i in range(n):
		if a[i] > b[i]:
			return -1
	gh = [[] for i in range(20)]
	for i in range(n):
		gh[ord(a[i]) - ord('a')].append(ord(b[i]) - ord('a'))
		gh[ord(b[i]) - ord('a')].append(ord(a[i]) - ord('a'))
	visit = [False for i in range(20)]

	def dfs(adj, visit, u):
		visit[u] = True
		for i in adj[u]:
			if not visit[i]:
				dfs(adj, visit, i)
	ans = 20
	for i in range(20):
		if not visit[i]:
			dfs(gh, visit, i)
			ans -= 1
	return ans
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	print(tits(a, b, n))


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 dfs(node):
	global cnt
	vis[node] = 1
	cnt += 1
	for i in adj[node]:
		if not vis[i]:
			dfs(i)
for _ in range(int(input())):
	n = int(input())
	a = input().strip()
	b = input().strip()
	adj = [set() for i in range(20)]
	for i in range(n):
		if b[i] < a[i]:
			print(-1)
			break
		else:
			adj[ord(a[i]) - 97].add(ord(b[i]) - 97)
			adj[ord(b[i]) - 97].add(ord(a[i]) - 97)
	else:
		vis = [0] * 20
		cnt = 0
		an = 0
		for i in range(20):
			if not vis[i]:
				dfs(i)
				an += cnt - 1
				cnt = 0
		print(an)


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 = 1
	for (x, y) in {*zip(map(ord, I()), map(ord, I()))}:
		if x > y:
			f = 0
		if x < y:
			g[x] += (y,)
			g[y] += (x,)
	print((-1, sum((dfs(i) - 1 for i in range(117) if V[i])))[f])


import math as mt
import sys, string
input = sys.stdin.readline
L = lambda : list(map(int, input().split()))
Ls = lambda : list(input().split())
M = lambda : map(int, input().split())
I = lambda : int(input())
from collections import defaultdict
from queue import PriorityQueue
MAX = 10 ** 5 + 1
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]])
	return len(ans)
w = 'abcdefghijklmnopqrstuvwxyz'
p = 0
t = I()
for _ in range(t):
	n = I()
	a = input().strip()
	b = input().strip()
	l = []
	m = []
	for i in a:
		l.append(ord(i) - 97)
	for i in b:
		m.append(ord(i) - 97)
	f = 0
	x = set([])
	for i in range(n):
		if m[i] - l[i] < 0:
			print(-1)
			f = 1
			break
	if f != 1:
		print(minimumOperations(a, b))


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 sys
input = sys.stdin.readline

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

def prog():
	for _ in range(int(input())):
		n = int(input())
		a = list(input().strip())
		b = input().strip()
		fail = False
		for i in range(n):
			if b[i] < a[i]:
				fail = True
				break
		if fail:
			print(-1)
		else:
			exclude = [0] * n
			for i in range(n):
				if a[i] == b[i]:
					exclude[i] = 1
			largest = max(b)
			curr = largest
			for i in range(n):
				if not exclude[i]:
					curr = min(curr, a[i])
			operations = 0
			while curr < largest:
				to_change = []
				for i in range(n):
					if a[i] == curr and (not exclude[i]):
						to_change.append(i)
				smallest = largest
				for i in to_change:
					smallest = min(smallest, b[i])
				for i in to_change:
					if b[i] == smallest:
						exclude[i] = 1
					a[i] = smallest
				curr = largest
				for i in range(n):
					if not exclude[i]:
						curr = min(curr, a[i])
				operations += 1
			print(operations)
prog()


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)


from sys import stdin
from collections import defaultdict
for _ in range(int(stdin.readline())):
	n = int(stdin.readline())
	a = stdin.readline().strip()
	b = stdin.readline().strip()
	dct = defaultdict(set)
	fl = 0
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			fl = 1
			print(-1)
			break
		elif ord(a[i]) < ord(b[i]):
			dct[b[i]].add(a[i])
	if not fl:
		x = 98
		ans = 0
		while x != 117:
			if len(dct[chr(x)]):
				ans += len(dct[chr(x)])
				y = x + 1
				while y != 117:
					for z in dct[chr(x)]:
						if z in dct[chr(y)]:
							dct[chr(y)].remove(z)
							dct[chr(y)].add(chr(x))
					y += 1
			x += 1
		print(ans)


for _ in range(int(input())):
	am = int(input())
	a = list(input())
	b = list(input())
	fromTo = []
	for i in range(20):
		fromTo.append([0] * 20)
	for i in range(am):
		a[i] = ord(a[i]) - 97
		b[i] = ord(b[i]) - 97
		if a[i] != b[i]:
			fromTo[a[i]][b[i]] += 1
	fl = False
	for i in range(am):
		if a[i] > b[i]:
			print(-1)
			fl = True
			break
	if fl:
		continue
	count = 0
	for iter in range(20):
		for i in range(20):
			fromTo[i][i] = 0
			c = 0
			f = 999
			for g in range(20):
				if fromTo[i][g] != 0:
					c += 1
					f = min(f, g)
			if c > 0:
				count += 1
				for g in range(20):
					fromTo[f][g] += fromTo[i][g]
					fromTo[i][g] = 0
				fromTo[i][i] = 0
	print(count)


class A:

	@staticmethod
	def input():
		n = int(input())
		a = input()
		b = input()
		assert len(a) == len(b)
		return (n, a, b)

	def __init__(self, n=None, a=None, b=None, debug=False):
		if n is None:
			(n, a, b) = A.input()
		self.n = n
		self.a = a
		self.b = b
		self.ans = 0

	def gen_dicts(self):
		b___as = {}
		a___bs = {}
		b_sorted = set()
		for (a, b) in zip(self.a, self.b):
			if a > b:
				self.ans = -1
				return (None, None, None)
			if a < b:
				if b not in b___as:
					b___as[b] = set()
					b_sorted.add(b)
				if a not in a___bs:
					a___bs[a] = set()
				b___as[b].add(a)
				a___bs[a].add(b)
		b_sorted = sorted(list(b_sorted))
		return (b___as, b_sorted, a___bs)

	def solve(self):
		(b___as, b_sorted, a___bs) = self.gen_dicts()
		if self.ans == -1:
			return self.return_ans()
		for b in b_sorted:
			for a in b___as.pop(b):
				self.ans += 1
				a___bs[a].remove(b)
				for bb in a___bs[a]:
					b___as[bb].remove(a)
					b___as[bb].add(b)
					if b not in a___bs:
						a___bs[b] = set()
					a___bs[b].add(bb)
		self.return_ans()

	def return_ans(self):
		print(self.ans)
		return self.ans
for _ in range(int(input())):
	A().solve()


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__
t = int(input())
for _ in range(t):
	n = int(input())
	A = [ord(x) - 97 for x in input()]
	B = [ord(x) - 97 for x in input()]
	ok = True
	adj = [set() for x in range(19)]
	for ind in range(n):
		(c1, c2) = (A[ind], B[ind])
		if c1 != c2:
			if c1 > c2:
				ok = False
				break
			adj[c1].add(c2)
	if not ok:
		print(-1)
		continue
	moves = 0
	for x in range(19):
		if len(adj[x]):
			moves += 1
			mn = min(adj[x])
			if len(adj[x]) == 1:
				continue
			for item in adj[x]:
				if item != mn:
					adj[mn].add(item)
	print(moves)


from collections import defaultdict, deque

def bfs(node):
	vis[node] = 1
	q = deque([[node, -1]])
	ans = 0
	dict1 = {}
	while q:
		temp = q.popleft()
		cur = temp[0]
		par = temp[1]
		for j in edge[cur]:
			if vis[j] == 0:
				vis[j] = 1
				q.append([j, cur])
			elif j != par and (j, cur) not in dict1:
				ans += 1
				dict1[cur, j] = 1
	return ans
t = int(input())
for _ in range(t):
	n = int(input())
	a = str(input())
	b = str(input())
	edge = defaultdict(list)
	s = 0
	p = 0
	cycle = 0
	matrix = [[0] * 20 for i in range(20)]
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			s += 1
			break
		elif ord(a[i]) < ord(b[i]):
			if matrix[ord(a[i]) - 97][ord(b[i]) - 97] == 0:
				edge[ord(a[i]) - 97].append(ord(b[i]) - 97)
				edge[ord(b[i]) - 97].append(ord(a[i]) - 97)
				matrix[ord(a[i]) - 97][ord(b[i]) - 97] = 1
				matrix[ord(b[i]) - 97][ord(a[i]) - 97] = 1
			else:
				cycle += 1
			p += 1
	if s == 1:
		print(-1)
	else:
		vis = [0] * 20
		for i in range(20):
			if vis[i] == 0:
				cycle += bfs(i)
		print(p - cycle)


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)


test = int(input())
moves = []
for i in range(test):
	size = int(input())
	current = list(input())
	desired = list(input())
	sum = 0
	if current == desired:
		moves.append(sum)
	else:
		unique = current + desired
		unique = list(set(unique))
		unique.sort()
		for p in range(len(unique)):
			dupIndex = []
			convertCur = []
			convertDes = []
			for j in range(size):
				if current[j] == unique[p]:
					dupIndex.append(j)
					convertCur.append(current[j])
					convertDes.append(desired[j])
			if dupIndex == []:
				continue
			convertCur = list(set(convertCur))
			convertDes = list(set(convertDes))
			small = min(convertDes)
			if small in convertDes and small in convertCur and (len(convertDes) > 1):
				convertDes.remove(small)
				small = min(convertDes)
			change = 0
			for j in dupIndex:
				if ord(desired[j]) > ord(current[j]):
					current[j] = small
					change += 1
				elif ord(desired[j]) == ord(current[j]):
					continue
				else:
					sum = -1
					break
			if change > 0 and sum != -1:
				sum += 1
		moves.append(sum)
		del unique
		del current
for i in moves:
	print(i)


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)


import sys
input = lambda : sys.stdin.readline().rstrip()
for _ in range(int(input())):
	n = int(input())
	a = [a for a in input()]
	b = [a for a in input()]
	flagg = True
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			flagg = False
			break
		elif a[i] == b[i]:
			a[i] = 'z'
			b[i] = 'z'
	u = 1
	ans = 0
	if flagg:
		for i in range(20):
			A = min(a)
			B = 'z'
			for i in range(n):
				if a[i] == A and B > b[i]:
					B = b[i]
			if B == 'z':
				print(0)
				break
			ch = False
			for i in range(n):
				if a[i] == A:
					if b[i] == B:
						a[i] = 'z'
						b[i] = 'z'
					else:
						a[i] = B
					ch = True
			if ch:
				ans += 1
				ch = False
			if a == b:
				print(ans)
				break


def run(n, A, B):
	idx = [[] for _ in range(20)]
	for i in range(n):
		idx[A[i]].append(i)
	count = 0
	for i in range(20):
		mini = int(1000000.0)
		for j in idx[i]:
			if A[j] < B[j] < mini:
				mini = B[j]
		inc = False
		for j in idx[i]:
			if A[j] < B[j]:
				inc = True
				A[j] = mini
				idx[mini].append(j)
		count += inc
	if A != B:
		count = -1
	print(count)

def main():
	t = int(input())
	for _ in range(t):
		n = int(input())
		A = list(map(lambda x: ord(x) - 97, input()))
		B = list(map(lambda x: ord(x) - 97, input()))
		run(n, A, B)
main()


from collections import deque
t = int(input())
for i in range(t):
	n = int(input())
	a = input()
	b = input()
	graph = [[] for j in range(25)]
	visited = [True for j in range(25)]
	look = False
	m = 0
	for j in range(n):
		if a[j] > b[j]:
			look = True
		if a[j] != b[j]:
			graph[ord(a[j]) - ord('a')].append(ord(b[j]) - ord('a'))
			graph[ord(b[j]) - ord('a')].append(ord(a[j]) - ord('a'))
			visited[ord(a[j]) - ord('a')] = False
			visited[ord(b[j]) - ord('a')] = False
	if look:
		print(-1)
		continue
	que = deque()
	count = 0
	for j in range(25):
		if not visited[j]:
			count += 1
			que.append(j)
			visited[j] = True
			while que:
				x = que.popleft()
				m += 1
				for k in graph[x]:
					if not visited[k]:
						que.append(k)
						visited[k] = True
	print(m - count)


from collections import defaultdict as dd
t = int(input())
for _ in range(t):
	n = int(input())
	a = input()
	la = list(a)
	b = input()
	flag = 0
	for i in range(n):
		if ord(b[i]) < ord(a[i]):
			flag = 1
			break
	if flag == 1:
		print(-1)
	else:
		move = 0
		f1 = 0
		for i in range(20):
			small = 21 + 97
			pos = dd(int)
			for j in range(n):
				if la[j] == chr(i + 97):
					pos[j] = 1
					if b[j] != chr(i + 97):
						small = min(ord(b[j]), small)
			if small < 21 + 97 and small != i + 97:
				alpha = chr(small)
				flag = 0
				for j in range(n):
					if pos[j] and la[j] != b[j]:
						la[j] = chr(small)
					if la[j] != b[j]:
						flag = 1
				move += 1
				if flag == 0:
					print(move)
					f1 = 1
					break
		if f1 == 0:
			print(0)


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)


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)


from math import inf as inf
from math import *
from collections import *
import sys
import os
input = sys.stdin.readline
t = int(input())
while t:
	t -= 1
	n = int(input())
	a = input().rstrip('\n')
	b = input().rstrip('\n')
	fl = 0
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			fl = 1
			break
	if fl:
		continue
	a = list(a)
	b = list(b)
	c = 0
	r = 0
	while c != 20:
		c += 1
		d = {}
		for i in range(n):
			if b[i] != a[i]:
				try:
					d[b[i]].append(a[i])
				except:
					d[b[i]] = [a[i]]
		try:
			v = min(d.keys())
		except:
			break
		f = min(d[v])
		fl = 0
		for i in range(n):
			if a[i] == f and a[i] != b[i]:
				a[i] = v
				fl = 1
		if fl:
			r += 1
	print(r)


import bisect
import collections
import copy
import functools
import heapq
import itertools
import math
import random
import re
import sys
import time
import string
from typing import List
sys.setrecursionlimit(99999)
for _ in range(int(input())):
	n = int(input())
	s = input()
	t = input()
	f = True
	for i in range(n):
		if s[i] > t[i]:
			f = False
			break
	if not f:
		print(-1)
		continue
	tree = {}

	def find(st):
		tree.setdefault(st, st)
		if tree[st] != st:
			tree[st] = find(tree[st])
		return tree[st]
	d = [[0] * 26 for _ in range(26)]
	for i in range(n):
		if s[i] < t[i]:
			tree[find(s[i])] = find(t[i])
	cnt = [0] * 26
	for (i, c) in enumerate(string.ascii_lowercase):
		cnt[ord(find(c)) - ord('a')] += 1
	ans = 0
	for i in range(26):
		if cnt[i]:
			ans += cnt[i] - 1
	print(ans)


cases = int(input())
alphabet = [chr(i) for i in range(ord('a'), ord('t') + 1)]
for case in range(cases):
	length = int(input())
	a = input()
	b = input()
	a = [a[i] for i in range(length)]
	b = [b[i] for i in range(length)]
	greater = False
	count = 0
	for char in range(length):
		if a[char] > b[char]:
			greater = True
			break
	if greater:
		print(-1)
		continue
	for alphabet_char in alphabet:
		equals = []
		minimum = 20
		for char in range(length):
			if a[char] != b[char] and a[char] == alphabet_char:
				equals.append(char)
				minimum = min(ord(b[char]) - 97, minimum)
		if equals:
			count += 1
			for pos in equals:
				a[pos] = chr(97 + minimum)
	print(count)


from collections import defaultdict
t = int(input())
cnt = 0
while cnt < t:
	cnt += 1
	DICT = [chr(ord('a') + i) for i in range(20)]
	n = int(input())
	flag = True
	a = list(input())
	b = list(input())
	d = defaultdict(list)
	ans = 0
	tmp = [ord(b[i]) - ord(a[i]) for i in range(n)]
	for (i, elem) in enumerate(a):
		if a[i] == b[i]:
			continue
		if a[i] > b[i]:
			flag = False
			break
		d[elem].append(tmp[i])
	if flag == False:
		print(-1)
		continue
	else:
		for letter in DICT:
			if d[letter] == []:
				continue
			else:
				ans += 1
				argmin = min(d[letter])
				d[chr(ord(letter) + argmin)].extend([d[letter][i] - argmin for i in range(len(d[letter])) if d[letter][i] != argmin])
		print(ans)


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, sys, bisect, copy
from collections import defaultdict, Counter, deque
if os.path.exists('in.txt'):
	sys.stdin = open('in.txt', 'r')
if os.path.exists('out.txt'):
	sys.stdout = open('out.txt', 'w')

def input():
	return sys.stdin.readline()

def mapi(arg=0):
	return map(int if arg == 0 else str, input().split())
for _ in range(int(input())):
	n = int(input())
	a = input().strip()
	b = input().strip()
	f = 0
	mp = defaultdict(list)
	res = 0
	par = [i for i in range(27)]

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

	def union(x, y):
		x = find(x)
		y = find(y)
		if x == y:
			return False
		par[x] = y
		return True
	orda = lambda x: ord(x) - ord('a')
	for i in range(n):
		if a[i] > b[i]:
			f = 1
			break
		if union(orda(a[i]), orda(b[i])):
			res += 1
	if f == 1:
		print(-1)
	else:
		print(res)


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
import math
import itertools
import random
from collections import deque

def solve():
	n = int(input())
	match = [[False for i in range(20)] for j in range(20)]
	a = input()
	b = input()
	for i in range(n):
		if a[i] == b[i]:
			continue
		if a[i] > b[i]:
			print(-1)
			return
		match[ord(a[i]) - ord('a')][ord(b[i]) - ord('a')] = True
	ans = 0
	for i in range(20):
		for j in range(i + 1, 20):
			if match[i][j]:
				ans += 1
				for k in range(j + 1, 20):
					if match[i][k]:
						match[j][k] = True
				break
	print(ans)
t = int(input())
while t > 0:
	solve()
	t -= 1


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


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 sys
import math
from collections import defaultdict, Counter
t = int(input())
for i in range(t):
	n = int(input())
	a = input()
	b = input()
	flag = 0
	d = defaultdict(set)
	v = [0] * 20
	for j in range(n):
		if b[j] < a[j]:
			flag = 1
			break
		if b[j] > a[j]:
			d[ord(b[j]) - 97].add(ord(a[j]) - 97)
			v[ord(b[j]) - 97] = 1
	if flag == 1:
		print(-1)
	else:
		v1 = [0] * 20
		ans = 0
		for j in range(1, 20):
			if v[j] == 1:
				for kk in d[j]:
					ans += 1
					for jj in d:
						if jj > j and kk in d[jj]:
							d[jj].discard(kk)
							d[jj].add(j)
		print(ans)


def main():
	t = int(input())
	for _ in range(t):
		n = int(input())
		a = input()
		b = input()
		ans = 1
		for (i, j) in zip(a, b):
			if i <= j:
				continue
			else:
				ans = 0
				break
		if ans == 0:
			print(-1)
			continue
		a_num = [ord(i) - ord('a') for i in a]
		b_num = [ord(i) - ord('a') for i in b]
		(a, b) = (a_num, b_num)
		ans = [[0] * 20 for i in range(20)]
		for (i, j) in zip(a, b):
			ans[i][j] += 1
		moves = 0
		for i in range(20):
			for j in range(20):
				if i == j:
					continue
				if ans[i][j] != 0:
					for x in range(j, 20):
						ans[j][x] += ans[i][x]
						ans[i][x] = 0
					moves += 1
		print(moves)
main()


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)


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)


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)


for _ in range(int(input())):
	n = int(input())
	s1 = input()
	s2 = input()
	s11 = []
	s22 = []
	for i in s1:
		s11.append(i)
	for j in s2:
		s22.append(j)
	v = []
	for i in range(n):
		v.append(i)
	final = []
	tot = 0
	check = True
	for j in range(n):
		if ord(s11[j]) > ord(s22[j]):
			check = False
			break
	if check:
		for i in range(97, 117):
			final.append(chr(i))
		w = []
		for i in range(n):
			w.append(i * i)
		for i in range(len(final)):
			indx = []
			val = []
			for j in range(n):
				if s11[j] == final[i] and s11[j] != s22[j]:
					indx.append(j)
					val.append(s22[j])
			mi = 116
			for oo in val:
				if ord(oo) < mi:
					mi = ord(oo)
			for oo in indx:
				s11[oo] = chr(mi)
			if len(indx) == 0:
				tot = tot
			else:
				tot = tot + 1
		print(tot)
	else:
		print('-1')


def checker(a, b, n):
	for i in range(n):
		if a[i] > b[i]:
			return -1
	lst = [[] for _ in range(20)]
	for i in range(n):
		lst[ord(a[i]) - ord('a')].append(ord(b[i]) - ord('a'))
		lst[ord(b[i]) - ord('a')].append(ord(a[i]) - ord('a'))
	visited = [False for _ in range(20)]

	def dfs(adjacent, visited, u):
		visited[u] = True
		for i in adjacent[u]:
			if not visited[i]:
				dfs(adjacent, visited, i)
	result = 20
	for i in range(20):
		if not visited[i]:
			dfs(lst, visited, i)
			result -= 1
	return result
for _ in range(int(input())):
	m = int(input())
	s = input()
	t = input()
	print(checker(s, t, m))


import sys
input = sys.stdin.readline
t = int(input())
for tt in range(t):
	n = int(input())
	AA = input().strip('\n')
	B = input().strip('\n')
	A = []
	for i in AA:
		A.append(i)
	flag = True
	counter = 0
	for k in range(20):
		letter = chr(97 + k)
		positions = []
		mini = 'z'
		for i in range(n):
			if A[i] == letter:
				if B[i] == A[i]:
					continue
				if B[i] < A[i]:
					flag = False
					break
				positions.append(i)
				mini = min(mini, B[i])
		if flag == False:
			break
		for i in positions:
			A[i] = mini
		if len(positions) != 0:
			counter += 1
	if flag:
		print(counter)
	else:
		print(-1)


import math, sys
from collections import defaultdict, deque
import bisect as bi

def yes():
	print('YES')

def no():
	print('NO')

def I():
	return int(sys.stdin.readline())

def In():
	return map(int, sys.stdin.readline().split())

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

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gt(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return -1

class DSU:

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

	def find_set(self, v):
		if v == self.parent[v]:
			return v
		self.parent[v] = self.find_set(self.parent[v])
		return self.parent[v]

	def union(self, a, b):
		a = self.find_set(a)
		b = self.find_set(b)
		if a != b:
			self.parent[a] = b
			return True
		return False

def main():
	try:
		n = I()
		a = Sn()
		b = Sn()
		dsu = DSU(26)
		flag = 0
		ans = 0
		for x in range(n):
			if a[x] > b[x]:
				flag = 1
				break
			elif a[x] < b[x]:
				if dsu.union(ord(a[x]) - 96, ord(b[x]) - 96):
					ans += 1
		if flag:
			print(-1)
		else:
			print(ans)
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(I()):
	main()


alphabetlist = ['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']
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	a = [a[i] for i in range(n)]
	b = [b[i] for i in range(n)]
	check = True
	for i in range(n):
		check &= b[i] >= a[i]
	if not check:
		print(-1)
	else:
		count = 0
		for i in range(20):
			al = alphabetlist[i]
			check = 'z'
			for j in range(n):
				if a[j] == al and a[j] != b[j]:
					check = min(check, b[j])
			if check != 'z':
				count += 1
				for j in range(n):
					if a[j] == al and a[j] != b[j]:
						a[j] = check
		print(count)


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)


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)


from collections import defaultdict
for _ in range(int(input())):
	N = int(input())
	A = input()
	B = input()
	flag = 0
	for i in range(N):
		if ord(A[i]) > ord(B[i]):
			flag = 1
			break
	if flag:
		print(-1)
		continue
	else:
		A = [i for i in A]
		B = [i for i in B]
		X = 97
		Ans = 0
		for x in range(20):
			pos = []
			current_character = chr(X + x)
			Min = 198
			for i in range(N):
				if A[i] == current_character and A[i] < B[i]:
					Min = min(Min, ord(B[i]) - ord(A[i]))
					pos.append(i)
			if pos:
				for i in pos:
					A[i] = chr(X + x + Min)
				Ans += 1
		print(Ans)


for _ in range(int(input())):
	N = int(input())
	A = input()
	B = input()
	A = [i for i in A]
	B = [i for i in B]
	ans = 0
	poss = True
	for i in range(len(A)):
		if ord(A[i]) > ord(B[i]):
			poss = False
			break
	if poss:
		for i in range(ord('a'), ord('t') + 1):
			mind = 21
			ind = []
			for j in range(len(A)):
				if ord(A[j]) == i and ord(B[j]) != ord(A[j]):
					ind.append(j)
					mind = min(mind, ord(B[j]) - ord(A[j]))
			if len(ind) > 0:
				for k in ind:
					A[k] = chr(i + mind)
				ans += 1
		print(ans)
	else:
		print(-1)


import sys
import string
import math
from collections import defaultdict
from functools import lru_cache
from collections import Counter
from fractions import Fraction

def mi(s):
	return map(int, s.strip().split())

def lmi(s):
	return list(mi(s))

def tmi(s):
	return tuple(mi(s))

def mf(f, s):
	return map(f, s)

def lmf(f, s):
	return list(mf(f, s))

def js(lst):
	return ' '.join((str(d) for d in lst))

def jsns(lst):
	return ''.join((str(d) for d in lst))

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

def linesp():
	return line().split()

def iline():
	return int(line())

def mat(n):
	matr = []
	for _ in range(n):
		matr.append(linesp())
	return matr

def matns(n):
	mat = []
	for _ in range(n):
		mat.append([c for c in line()])
	return mat

def mati(n):
	mat = []
	for _ in range(n):
		mat.append(lmi(line()))
	return mat

def pmat(mat):
	for row in mat:
		print(js(row))

def solve(A, B):
	counts = defaultdict(int)
	for (c1, c2) in zip(A, B):
		if c1 > c2:
			print(-1)
			return
		elif c1 < c2:
			counts[c1, c2] += 1
	items = list(counts.keys())
	cost = 0
	chars = string.ascii_lowercase
	for i in range(20):
		curr = chars[i]
		while True:
			min_b = 'z'
			for (a, b) in items:
				if curr == a and a != b:
					min_b = min(min_b, b)
			if min_b != 'z':
				for i in range(len(items)):
					if items[i][0] == curr and items[i][0] != items[i][1]:
						items[i] = (min_b, items[i][1])
				cost += 1
			else:
				break
	print(cost)

def main():
	t = iline()
	for _ in range(t):
		line()
		solve(line(), line())
main()


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 sys
import math
import heapq
import collections

def inputnum():
	return int(input())

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

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

def inputstring():
	return [x for x in input()]

def inputmatrixchar(rows):
	arr2d = [[j for j in input().strip()] for i in range(rows)]
	return arr2d

def inputmatrixint(rows):
	arr2d = []
	for _ in range(rows):
		arr2d.append([int(i) for i in input().split()])
	return arr2d
t = int(input())
for q in range(t):
	n = inputnum()
	a = inputstring()
	b = inputstring()
	done = False
	for i in range(n):
		if a[i] > b[i]:
			done = True
	if done:
		print(-1)
		continue
	count = 0
	for i in range(ord('a'), ord('t')):
		has = False
		mn = 'z'
		for j in range(n):
			if a[j] == chr(i) and a[j] < b[j]:
				has = True
				mn = min(mn, b[j])
		if has:
			count += 1
			for j in range(n):
				if a[j] == chr(i):
					a[j] = mn
	print(count)


from sys import stdin, stdout
from math import gcd, sqrt, factorial, pi
from collections import deque, defaultdict
input = stdin.readline
R = lambda : map(int, input().split())
I = lambda : int(input())
S = lambda : input().rstrip('\n')
L = lambda : list(R())
P = lambda x: stdout.write(x)
lcm = lambda x, y: x * y // gcd(x, y)
hg = lambda x, y: (y + x - 1) // x * x
pw = lambda x: 1 if x == 1 else 1 + pw(x // 2)
chk = lambda x: chk(x // 2) if not x % 2 else True if x == 1 else False
sm = lambda x: (x ** 2 + x) // 2
N = 10 ** 9 + 7
for _ in range(I()):
	n = I()
	(*a,) = map(lambda x: ord(x) - 97, S())
	(*b,) = map(lambda x: ord(x) - 97, S())
	v = [set() for i in range(26)]
	flg = False
	for i in range(n):
		if a[i] > b[i]:
			flg = True
			break
		elif a[i] != b[i]:
			v[a[i]].add(b[i])
	if flg:
		print(-1)
		continue
	ans = 0
	for i in range(26):
		if v[i]:
			ans += 1
			p = min(v[i])
			v[p].update(v[i])
			v[p].remove(p)
	print(ans)


import os
import sys
from io import BytesIO, IOBase
from collections import deque
from collections import defaultdict

def main():
	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)
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 string
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	a = list(map(str, a))
	b = list(map(str, b))
	flag = True
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			flag = False
			break
	if flag:
		alpha = string.ascii_lowercase
		ans = 0
		m = alpha[0:20]
		for i in alpha[0:20]:
			y = 'z'
			flag = False
			position = []
			for j in range(n):
				if a[j] == i and b[j] > i:
					y = min(y, b[j])
					position.append(j)
			if position:
				ans += 1
				for pos in position:
					a[pos] = y
		print(ans)


import sys
from math import sqrt
from collections import defaultdict
inpt = sys.stdin.readline

def inp():
	return int(inpt())

def inlist():
	return list(map(int, inpt().split()))

def instr():
	s = inpt()
	return list(s[:len(s) - 1])

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

class Graph:

	def __init__(self, n):
		self.n = n
		self.graph = defaultdict(list)
		self.marked = defaultdict(int)

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

	def dfs(self, u):
		self.marked[u] = 1
		for i in self.graph[u]:
			if self.marked[i] == 0:
				self.dfs(i)

def main():
	t = inp()
	for l in range(t):
		n = inp()
		a = instr()
		b = instr()
		g = Graph(20)
		np = False
		for i in range(n):
			x = ord(a[i]) - 96
			y = ord(b[i]) - 96
			if x > y:
				print(-1)
				np = True
				break
			g.addEdge(x, y)
		if np == False:
			ans = 20
			for i in range(1, 21):
				if g.marked[i] == 0:
					g.dfs(i)
					ans -= 1
			print(ans)
main()


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)


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)


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


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)


from collections import defaultdict
import sys
t = int(input())
for _ in range(t):
	n = int(input())
	x = input()
	y = input()
	a = []
	b = []
	for j in x:
		a.append(j)
	for j in y:
		b.append(j)
	flag = 0
	for j in range(n):
		if ord(b[j]) < ord(a[j]):
			print(-1)
			flag = -1
			break
	if flag != -1:
		res = 0
		for i in range(20):
			curr = chr(97 + i)
			d = defaultdict(lambda : 0)
			for j in range(n):
				if b[j] == curr and a[j] != curr:
					d[a[j]] += 1
			res += len(d)
			for j in range(n):
				if d[a[j]] > 0:
					a[j] = curr
		print(res)


import os
from io import BytesIO, IOBase
from collections import Counter
import sys

def main():
	for t in range(int(input())):
		n = int(input())
		a = list(input().rstrip())
		b = list(input().rstrip())
		if a == b:
			print(0)
		else:
			ans = 0
			for i in range(n):
				if a[i] != b[i]:
					if ord(a[i]) > ord(b[i]):
						ans = -1
						break
			if ans != -1:
				for i in range(97, 97 + 20):
					mi = 'z'
					i = chr(i)
					for j in range(n):
						if a[j] != b[j] and i == a[j]:
							mi = min(b[j], mi)
					if mi != 'z':
						for j in range(n):
							if a[j] != b[j] and i == a[j]:
								a[j] = mi
						ans += 1
						if a == b:
							break
			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 sys
LI = lambda : list(map(int, sys.stdin.readline().strip('\n').split()))
MI = lambda : map(int, sys.stdin.readline().strip('\n').split())
SI = lambda : sys.stdin.readline().strip('\n')
II = lambda : int(sys.stdin.readline().strip('\n'))

def dfs(u):
	global g, vis
	(vis[u], cnt) = (True, 0)
	for v in g[u]:
		if not vis[v]:
			cnt += 1
			dfs(v)
	return cnt != 0
for _ in range(II()):
	(n, a, b, flag, alp) = (II(), SI(), SI(), True, set([]))
	g = {i: [] for i in range(26)}
	vis = [False] * 26
	for i in range(n):
		if a[i] > b[i]:
			flag = False
		if a[i] != b[i]:
			alp.add(a[i])
			alp.add(b[i])
			g[ord(a[i]) - ord('a')].append(ord(b[i]) - ord('a'))
			g[ord(b[i]) - ord('a')].append(ord(a[i]) - ord('a'))
	cc = 0
	for u in range(26):
		if not vis[u]:
			cc += dfs(u)
	print(len(alp) - cc if flag else -1)


y = lambda s: ord(s) - 97
z = lambda : list(map(y, input()))
for _ in range(int(input())):
	n = int(input())
	(a, b) = (z(), z())
	(f, c) = (0, 0)
	for i in range(20):
		m = 20
		l = []
		for j in range(n):
			if a[j] == i:
				if b[j] < i:
					f = 1
					break
				elif b[j] > i:
					m = min(m, b[j])
					l.append(j)
		if f:
			break
		if m == 20:
			continue
		else:
			c += 1
			for j in l:
				a[j] = m
	if f:
		print(-1)
	else:
		print(c)


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)


import sys
readline = sys.stdin.readline
T = int(readline())
Ans = [None] * T
geta = 20
for qu in range(T):
	N = int(readline())
	A = list(map(lambda x: ord(x) - 97, readline().strip()))
	B = list(map(lambda x: ord(x) - 97, readline().strip()))
	if any((a > b for (a, b) in zip(A, B))):
		Ans[qu] = -1
		continue
	res = 0
	table = [[0] * geta for _ in range(geta)]
	for (a, b) in zip(A, B):
		if a != b:
			table[a][b] = 1
	for al in range(geta):
		if sum(table[al]):
			res += 1
			bl = table[al].index(1)
			for cl in range(bl + 1, geta):
				table[bl][cl] = table[bl][cl] | table[al][cl]
	Ans[qu] = res
print('\n'.join(map(str, Ans)))


from collections import defaultdict
import sys
input = sys.stdin.readline
T = int(input())
for t in range(T):
	N = int(input())
	A = list(input()[:-1])
	B = list(input()[:-1])
	pos = defaultdict(list)
	for (i, el) in enumerate(A):
		pos[ord(el)].append(i)
	answer = 0
	imp = False
	for letter in range(ord('a'), ord('t') + 1):
		lowest_above = None
		to_up = set()
		for p in pos[letter]:
			if A[p] < B[p]:
				if lowest_above is None or B[p] < lowest_above:
					lowest_above = B[p]
				to_up.add(p)
			elif A[p] > B[p]:
				print(-1)
				imp = True
				break
		if to_up:
			answer += 1
			for p in to_up:
				A[p] = lowest_above
				pos[ord(lowest_above)].append(p)
		if imp:
			break
	if imp:
		continue
	print(answer)


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
from collections import defaultdict
from itertools import permutations
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())):
	n = int(input())
	a = list(input())
	b = list(input())
	ch = 1
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			ch = 0
			break
	if ch == 0:
		print(-1)
	else:
		c = 'abcdefghijklmnopqrst'
		ct = 0
		for i in range(20):
			mn = 123
			for j in range(n):
				if a[j] == c[i] and a[j] != b[j]:
					mn = min(mn, ord(b[j]))
			if mn != 123:
				ct += 1
				for j in range(n):
					if a[j] == c[i] and a[j] != b[j]:
						a[j] = chr(mn)
		print(ct)


import sys
import math
input = sys.stdin.readline
T = int(input())
for t in range(T):
	N = int(input())
	A = input().strip()
	B = input().strip()
	can = True
	adj = [[] for i in range(20)]
	for (a, b) in zip(A, B):
		a = ord(a) - ord('a')
		b = ord(b) - ord('a')
		if a == b:
			continue
		if a > b:
			can = False
			break
		adj[a].append(b)
		adj[b].append(a)
	if not can:
		print(-1)
		continue
	component = [None for i in range(20)]

	def dfs(vertex, c):
		component[vertex] = c
		size = 1
		for node in adj[vertex]:
			if component[node] is None:
				size += dfs(node, c)
		return size
	num_comp = 0
	ans = 0
	for node in range(20):
		if component[node] is None and adj[node]:
			num_comp += 1
			comp_size = dfs(node, num_comp)
			ans += comp_size - 1
	print(ans)


import sys
input = sys.stdin.readline
alpha = 'abcdefghijklmnopqrst'
for f in range(int(input())):
	n = int(input())
	a = input()
	a = a[0:n]
	b = input()
	b = b[0:n]
	difs = [False] * 20
	for i in range(20):
		difs[i] = [False] * 20
	poss = True
	for i in range(n):
		if a[i] != b[i]:
			if b[i] < a[i]:
				poss = False
			else:
				j1 = 0
				while a[i] != alpha[j1]:
					j1 += 1
				j2 = j1 + 1
				while b[i] != alpha[j2]:
					j2 += 1
				difs[j1][j2] = True
	sol = 0
	if poss:
		for j1 in range(19):
			fnd = False
			got = -1
			for j2 in range(j1 + 1, 20):
				if difs[j1][j2]:
					if fnd:
						difs[got][j2] = True
					else:
						fnd = True
						got = j2
						sol += 1
		print(sol)
	else:
		print(-1)


for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	a = list(a)
	b = list(b)
	fg = 0
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			fg = 1
			break
	if fg == 0:
		res = 0
		for i in range(97, 117):
			mn = 't'
			tmp = []
			for j in range(n):
				if a[j] != b[j] and a[j] == chr(i):
					tmp.append(j)
					mn = min(mn, b[j])
			if len(tmp) != 0:
				res += 1
				for k in range(len(tmp)):
					a[tmp[k]] = mn
		print(res)


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)


t = int(input())
for _ in range(t):
	n = int(input())
	a = input()
	b = input()
	aAscii = ord('a')
	color = list(range(20))
	isPossible = True
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			isPossible = False
			break
		elif ord(a[i]) < ord(b[i]):
			aNum = ord(a[i]) - aAscii
			bNum = ord(b[i]) - aAscii
			if color[aNum] != color[bNum]:
				refColor = color[aNum]
				chgColor = color[bNum]
				for j in range(20):
					if color[j] == chgColor:
						color[j] = refColor
	if isPossible:
		isColorPresent = [0] * 20
		for elem in color:
			isColorPresent[elem] = 1
		print(20 - sum(isColorPresent))
	else:
		print(-1)


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)


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)


for _ in range(0, int(input())):
	n = int(input())
	s1 = list(input())
	s2 = list(input())
	h = {}
	flag5 = 0
	for i in range(0, n):
		if ord(s2[i]) - ord(s1[i]) > 0:
			if s1[i] in h:
				h[s1[i]].append(ord(s2[i]) - ord(s1[i]))
			else:
				h.update({s1[i]: [ord(s2[i]) - ord(s1[i])]})
		elif ord(s2[i]) - ord(s1[i]) < 0:
			flag5 = 1
			break
	if flag5 == 1:
		print(-1)
		continue
	h2 = [[] for a in range(0, 100)]
	for key in h.keys():
		h2[ord(key) - ord('a')] = h[key]
	res = 0
	while True:
		if h2 == [[]] * 25 * 4:
			break
		for i in range(25):
			if h2[i] != []:
				h2[i].sort()
				minimum = h2[i][0]
				res += 1
				for j in range(0, len(h2[i])):
					h2[i][j] -= minimum
					if h2[i][j] > 0:
						h2[i + minimum].append(h2[i][j])
						h2[i][j] = 0
			h2[i] = []
	print(res)


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
t = int(input())
for _ in range(t):
	n = int(input())
	a = input()
	b = input()
	ok = True
	se = set()
	for i in range(n):
		if a[i] < b[i]:
			se.add((a[i], b[i]))
		elif a[i] > b[i]:
			ok = False
			break
	if ok == False:
		print(-1)
	else:
		cnt = 0
		while se:
			minaa = 'z'
			for (aa, bb) in se:
				minaa = min(minaa, aa)
			minbb = 'z'
			for (aa, bb) in se:
				if aa == minaa:
					minbb = min(minbb, bb)
			se2 = set()
			cnt += 1
			for (aa, bb) in se:
				if aa == minaa:
					if bb == minbb:
						pass
					else:
						se2.add((minbb, bb))
				else:
					se2.add((aa, bb))
			se = se2
		print(cnt)


for _ in range(int(input())):
	n = int(input())
	s1 = input()
	s2 = input()
	set1 = set()
	list2 = [set() for i in range(20)]
	f = 0
	for i in range(n):
		if s1[i] < s2[i]:
			list2[ord(s1[i]) - 97].add(s2[i])
		elif s1[i] > s2[i]:
			f = 1
			break
	c = 0
	for i in range(20):
		if len(list2[i]) == 0:
			continue
		elif len(list2[i]) == 1:
			c += 1
		elif len(list2[i]) > 1:
			c += 1
			x = min(list2[i])
			list2[i] = list2[i] - {x}
			list2[ord(x) - 97].update(list2[i])
	if f == 0:
		print(c)
	else:
		print(-1)


import sys

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

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

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

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

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

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

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 19
MOD = 10 ** 9 + 7
for _ in range(INT()):
	N = INT()
	S = [ord(c) - 97 for c in input()]
	T = [ord(c) - 97 for c in input()]
	ng = False
	for i in range(N):
		if S[i] > T[i]:
			ng = True
			break
	if ng:
		print(-1)
		continue
	cnt = 0
	for c in range(20):
		mn = INF
		idx = []
		for i in range(N):
			if S[i] != T[i] and S[i] == c:
				idx.append(i)
				mn = min(mn, T[i])
		if mn != INF:
			for j in idx:
				S[j] = mn
			cnt += 1
	print(cnt)


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)


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
mod = int(pow(10, 9) + 7)
mod2 = 998244353

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

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

def L():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

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

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
try:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('../output.txt', 'w')
except:
	pass
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)


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
sys.setrecursionlimit(10 ** 5)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.readline())

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline()[:-1]

def ng():
	for (a, b) in zip(aa, bb):
		if a > b:
			return True
	return False
for _ in range(II()):
	n = II()
	aa = [ord(c) - 97 for c in SI()]
	bb = [ord(c) - 97 for c in SI()]
	if ng():
		print(-1)
		continue
	ans = 0
	for x in range(20):
		mn = 30
		for i in range(n):
			if aa[i] == x and bb[i] != x:
				mn = min(mn, bb[i])
		if mn == 30:
			continue
		ans += 1
		for i in range(n):
			if aa[i] == x and bb[i] != x:
				aa[i] = mn
	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)


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 sys import stdin as cin
import re
lmap = lambda f, v: list(map(f, v))

def count_ops(A, B):
	N = len(A)
	for i in range(N):
		if A[i] > B[i]:
			return -1
	cnt = 0
	for t in sorted(set(B)):
		S = {A[i] for i in range(N) if B[i] == t} - {t}
		cnt += len(S)
		if S:
			A = re.sub('[' + ''.join(S) + ']', t, A)
	return cnt

def main():
	t = int(next(cin).strip())
	for i in range(t):
		next(cin)
		A = next(cin).strip()
		B = next(cin).strip()
		print(count_ops(A, B))
main()


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 *
from sys import *
input = stdin.readline
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	d = defaultdict(list)
	cn = 0
	ch = 1
	for i in range(n):
		if a[i] == b[i]:
			continue
		elif a[i] > b[i]:
			ch = 0
		else:
			d[a[i]].append((i, b[i]))
	if ch == 0:
		stdout.write(str(-1) + '\n')
		continue
	s = 'abcdefghijklmnopqrst'
	for i in s:
		if len(d[i]) == 0:
			continue
		cn += 1
		d[i].sort(key=lambda x: x[1])
		tp = list(d[i])
		k = tp[0][1]
		for (x, y) in tp:
			if y == k:
				continue
			d[k].append((x, y))
	stdout.write(str(cn) + '\n')


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)


from collections import defaultdict

def dfs(graph, v, visit):
	visit[v] = 1
	for i in graph[v]:
		if visit[i] != 1:
			dfs(graph, i, visit)
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	graph = defaultdict(list)
	ans = 20
	for i in range(n):
		if ord(a[i]) < ord(b[i]):
			graph[ord(a[i]) - ord('a')].append(ord(b[i]) - ord('a'))
			graph[ord(b[i]) - ord('a')].append(ord(a[i]) - ord('a'))
		elif ord(a[i]) > ord(b[i]):
			ans = -1
			break
	visit = [0 for i in range(20)]
	if ans != -1:
		for i in range(20):
			if visit[i] == 0:
				ans -= 1
				dfs(graph, i, visit)
	print(ans)


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)


import sys
input = sys.stdin.readline
t = int(input())
for _ in range(t):
	n = int(input())
	a = list(input().rstrip())
	b = list(input().rstrip())
	flag = 0
	for i in range(n):
		if a[i] > b[i]:
			flag = 1
	if flag:
		print(-1)
		continue
	ans = 0
	s = set()
	for ch in range(20):
		for i in range(n):
			if b[i] == chr(ch + 97) and 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()
	print(ans)


t = int(input())
for testcase in range(t):
	n = int(input())
	A = input()
	B = input()
	impy = False
	for i in range(n):
		if ord(A[i]) > ord(B[i]):
			impy = True
			break
	if impy:
		print('-1')
		continue
	dict = {}
	for a in 'abcdefghijklmnopqrst':
		dict[a] = []
	for i in range(n):
		if A[i] != B[i]:
			dict[A[i]].append(B[i])
	for a in 'abcdefghijklmnopqrst':
		dict[a] = sorted(set(dict[a]))
	answer = 0
	finalDict = {}
	for k in 'abcdefghijklmnopqrst':
		for i in range(len(set(dict[k]))):
			if i > 0:
				vv = dict[k][1:]
				dict[dict[k][i - 1]].extend(vv)
				dict[dict[k][i - 1]] = sorted(set(dict[dict[k][i - 1]]))
				break
			v = dict[k][i]
			if k + '#' + v not in finalDict:
				answer = answer + 1
				finalDict[k + '#' + v] = 1
	print(answer)


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)


abc = [chr(i) for i in range(97, 97 + 20)]
t = int(input())
for _ in range(t):
	n = int(input())
	a = list(input())
	b = list(input())
	s = set([])
	flg = 0
	for i in range(n):
		tempa = abc.index(a[i])
		tempb = abc.index(b[i])
		if tempa > tempb:
			flg = 1
			break
		elif tempa < tempb:
			s.add((tempa, tempb))
	if flg:
		print(-1)
	else:
		ans = 0
		for i in range(len(s)):
			if len(s) == 0:
				break
			s = list(s)
			s.sort()
			(x, y) = s.pop(0)
			for i in range(len(s)):
				temp = list(s[i])
				if temp[0] == x:
					temp[0] = y
				s[i] = tuple(temp)
			s = set(s)
			ans += 1
		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)


for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	(f, ans) = (0, 0)
	for i in range(n):
		if a[i] > b[i]:
			f = 1
			break
	if f:
		print(-1)
		continue
	for c in range(97, 117):
		mn = 116
		l = []
		for i in range(n):
			if a[i] == chr(c) and a[i] != b[i]:
				l.append(i)
				mn = min(mn, ord(b[i]))
		if l:
			ans += 1
			for i in l:
				a[i] = chr(mn)
	print(ans)


import sys
import math

def II():
	return int(sys.stdin.readline())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def MI():
	return map(int, sys.stdin.readline().split())

def SI():
	return sys.stdin.readline().strip()
t = II()
for q in range(t):
	n = II()
	a = SI()
	b = SI()
	d = [[] for i in range(20)]
	boo = True
	for i in range(n):
		if a[i] > b[i]:
			boo = False
			break
		d[ord(a[i]) - 97].append(ord(b[i]) - 97)
		d[ord(b[i]) - 97].append(ord(a[i]) - 97)
	if boo == False:
		print(-1)
	else:
		v = [0] * 20

		def dfs(ind):
			v[ind] = 1
			for i in d[ind]:
				if v[i] == 0:
					dfs(i)
		ans = 20
		for i in range(20):
			if v[i] == 0:
				dfs(i)
				ans -= 1
		print(ans)


def solve():
	n = int(input())
	a = input()
	b = input()
	l = [[0 for i in range(20)] for j in range(20)]
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			return
		elif a[i] < b[i]:
			l[ord(b[i]) - 97][ord(a[i]) - 97] += 1
	ans = 0
	for i in range(20):
		j = 0
		while j < 20:
			if l[j][i] != 0:
				x = j
				j += 1
				ans += 1
				while j < 20:
					if l[j][i] != 0:
						l[j][x] += l[j][i]
					j += 1
			j += 1
	c = 0
	for i in range(20):
		if l[i][19] != 0:
			c += 1
	if c <= 1:
		print(ans + c)
	else:
		print(-1)
t = int(input())
while t > 0:
	solve()
	t -= 1


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)


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


from collections import defaultdict
import sys, math
f = None
try:
	f = open('q1.input', 'r')
except IOError:
	f = sys.stdin
if 'xrange' in dir(__builtins__):
	range = xrange

def print_case_iterable(case_num, iterable):
	print('Case #{}: {}'.format(case_num, ' '.join(map(str, iterable))))

def print_case_number(case_num, iterable):
	print('Case #{}: {}'.format(case_num, iterable))

def print_iterable(A):
	print(' '.join(A))

def read_int():
	return int(f.readline().strip())

def read_int_array():
	return [int(x) for x in f.readline().strip().split(' ')]

def rns():
	a = [x for x in f.readline().split(' ')]
	return (int(a[0]), a[1].strip())

def read_string():
	return list(f.readline().strip())

def ri():
	return int(f.readline().strip())

def ria():
	return [int(x) for x in f.readline().strip().split(' ')]

def rns():
	a = [x for x in f.readline().split(' ')]
	return (int(a[0]), a[1].strip())

def rs():
	return list(f.readline().strip())

def bi(x):
	return bin(x)[2:]
from collections import deque
import math
NUMBER = 10 ** 9 + 7

def factorial(n):
	M = NUMBER
	f = 1
	for i in range(1, n + 1):
		f = f * i % M
	return f

def mult(a, b):
	return a * b % NUMBER

def minus(a, b):
	return (a - b) % NUMBER

def plus(a, b):
	return (a + b) % NUMBER

def egcd(a, b):
	if a == 0:
		return (b, 0, 1)
	else:
		(g, y, x) = egcd(b % a, a)
		return (g, x - b // a * y, y)

def modinv(a):
	m = NUMBER
	(g, x, y) = egcd(a, m)
	if g != 1:
		raise Exception('modular inverse does not exist')
	else:
		return x % m

def choose(n, k):
	if n < k:
		assert false
	return mult(factorial(n), modinv(mult(factorial(k), factorial(n - k)))) % NUMBER
from collections import deque, defaultdict
import heapq
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def dfs(g, timeIn, timeOut, depths, parents):
	cnt = 0
	stack = [[1, 0, 0, 0]]
	while stack:
		(v, neig_i, parent, depth) = stack[-1]
		parents[v] = parent
		depths[v] = depth
		if neig_i == 0:
			timeIn[v] = cnt
			cnt += 1
		while neig_i < len(g[v]):
			u = g[v][neig_i]
			if u == parent:
				neig_i += 1
				continue
			stack[-1][1] = neig_i + 1
			stack.append([u, 0, v, depth + 1])
			break
		if neig_i == len(g[v]):
			stack.pop()
			timeOut[v] = cnt
			cnt += 1
cnt = 0

@bootstrap
def dfs(v, adj, timeIn, timeOut, depths, parents, parent=0, depth=0):
	global cnt
	parents[v] = parent
	depths[v] = depth
	timeIn[v] = cnt
	cnt += 1
	for u in adj[v]:
		if u == parent:
			continue
		yield dfs(u, adj, timeIn, timeOut, depths, parents, v, depth + 1)
	timeOut[v] = cnt
	cnt += 1
	yield

def gcd(a, b):
	if a == 0:
		return b
	return gcd(b % a, a)

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

def get_num_2_5(n):
	twos = 0
	fives = 0
	while n > 0 and n % 2 == 0:
		n //= 2
		twos += 1
	while n > 0 and n % 5 == 0:
		n //= 5
		fives += 1
	return (twos, fives)

def shift(a, i, num):
	for _ in range(num):
		(a[i], a[i + 1], a[i + 2]) = (a[i + 2], a[i], a[i + 1])

def equal(x, y):
	return abs(x - y) <= 1e-09

def getAngle(a, b, c):
	ang = math.degrees(math.atan2(c[1] - b[1], c[0] - b[0]) - math.atan2(a[1] - b[1], a[0] - b[0]))
	return ang + 360 if ang < 0 else ang

def getLength(a, b):
	return math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
from heapq import heapify, heappush, heappop

def bfs(adj):
	s = set()
	d = defaultdict(set)
	q = deque([])
	s.add(0)
	d[0].add(0)
	q.append((0, 0))
	while len(q) > 0:
		(v, depth) = q.popleft()
		for u in adj[v]:
			if u not in s:
				s.add(u)
				d[depth + 1].add(u)
				q.append((u, depth + 1))
	return d

@bootstrap
def dfs(u, top, adj, vis):
	vis[u] = 1
	for (v, d) in adj[u]:
		if vis[v] == 2 or d == 0:
			continue
		if vis[v] == 1:
			yield 'No'
		x = (yield dfs(v, top, adj, vis))
		if x == 'No':
			yield 'No'
	vis[u] = 2
	top.append(u)
	yield

def isSubsetSum(arr, n, summ):
	subarr = [[False for i in range(summ + 1)] for i in range(n + 1)]
	for i in range(n + 1):
		subarr[i][0] = True
	for i in range(1, summ + 1):
		subarr[0][i] = False
	for i in range(1, n + 1):
		for j in range(1, summ + 1):
			if j < arr[i - 1]:
				subarr[i][j] = subarr[i - 1][j]
			if j >= arr[i - 1]:
				subarr[i][j] = subarr[i - 1][j] or subarr[i - 1][j - arr[i - 1]]
	return subarr[n][summ]

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

def find_lcm_array(A):
	if len(A) == 1:
		return A[0]
	lcm = find_lcm(A[0], A[1])
	for i in range(2, len(A)):
		lcm = find_lcm(lcm, A[i])
	return lcm
from string import ascii_lowercase as al

def solution(a, b, n):
	a = [ord(x) - ord('a') for x in a]
	b = [ord(x) - ord('a') for x in b]
	for i in range(n):
		if a[i] > b[i]:
			return -1
	s = defaultdict(set)
	for i in range(n):
		if a[i] < b[i]:
			s[a[i]].add(b[i])
	final = 0
	for i in range(20):
		if i not in s:
			continue
		final += 1
		if len(s[i]) == 1:
			continue
		mi = min(s[i])
		s[i].remove(mi)
		s[mi] |= s[i]
	return final
	return final

def main():
	T = 1
	T = ri()
	for i in range(T):
		n = ri()
		a = rs()
		b = rs()
		x = solution(a, b, n)
		if 'xrange' not in dir(__builtins__):
			print(x)
		else:
			(print >> output, 'Case #' + str(i + 1) + ':', str(x))
	if 'xrange' in dir(__builtins__):
		print(output.getvalue())
		output.close()
if 'xrange' in dir(__builtins__):
	import cStringIO
	output = cStringIO.StringIO()
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)


ALP = 'abcdefghijklmnopqrst'
n_tests = int(input())

def dfs(adj, reachable, node):
	reachable[node] = 1
	for i in adj[node]:
		if not reachable[i]:
			reachable = dfs(adj, reachable, i)
	return reachable
for i in range(n_tests):
	string_length = int(input())
	flag_solution = True
	connections = dict()
	sol = 20
	A = input()
	B = input()
	adj = [[] for x in range(20)]
	for j in range(string_length):
		if A[j] > B[j]:
			flag_solution = False
		elif A[j] < B[j]:
			adj[ALP.find(A[j])].append(ALP.find(B[j]))
			adj[ALP.find(B[j])].append(ALP.find(A[j]))
	if flag_solution:
		reachable = [0] * 20
		for j in range(20):
			if not reachable[j]:
				dfs(adj, reachable, j)
				sol -= 1
		print(sol)
	else:
		print(-1)


import sys

def remove(l, r):
	i = 0
	while i < r and l[0][0] is l[0][1]:
		l.pop(0)
		i += 1
	return l

def chk(k):
	(i, j) = (k[0], k[1])
	global bul
	if bul:
		return False
	elif i is j:
		return None
	elif j > i:
		return (i, j)
	else:
		bul = True
		return False

def bal(i):
	return i
t = int(sys.stdin.readline())
while t:
	t -= 1
	bul = False
	n = int(sys.stdin.readline())
	A = sys.stdin.readline().strip()
	B = sys.stdin.readline().strip()
	c = set(map(chk, zip(A, B)))
	if False in c:
		print(-1)
		continue
	if None in c:
		c.remove(None)
	c = list(map(list, c))
	c.sort()
	i = 0
	cnt = 0
	ll = len(c)
	while ll:
		i = 0
		x = c[0][0]
		y = c[0][1]
		while i < len(c) and c[i][0] is x:
			c[i][0] = y
			i += 1
		c = remove(c, ll)
		c.sort()
		cnt += 1
		ll = len(c)
	print(cnt)


t = int(input())
for tt in range(t):
	n = int(input())
	a = list(map(str, input()))
	b = list(map(str, input()))
	c = 0
	d = set([])
	for i in range(0, len(a)):
		if ord(a[i]) > ord(b[i]):
			c = 1
			break
		elif ord(a[i]) == ord(b[i]):
			continue
		else:
			d.add((ord(a[i]), ord(b[i])))
	if c == 1:
		print(-1)
	else:
		k = list(d)
		k = sorted(k)
		i = 0
		while len(k) > 0:
			for j in range(0, len(k)):
				if j == 0:
					(x, y) = k[j]
					k[j] = (y, y)
				else:
					(ap, pp) = k[j]
					if x == ap:
						k[j] = (y, pp)
					else:
						break
			while True:
				if len(k) == 0:
					break
				(l, r) = k[0]
				if l == r:
					k.remove(k[0])
				else:
					break
			k = sorted(k)
			i = i + 1
		print(i)


from sys import stdin
input = stdin.readline

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

def union(i, j):
	if rank[i] > rank[j]:
		(i, j) = (j, i)
	elif rank[i] == rank[j]:
		rank[j] += 1
	p[i] = j
z = []
t = int(input())
for _ in range(t):
	n = int(input())
	(a, b) = (input(), input())
	edge = []
	ans = 0
	A = ord('a')
	for i in range(n):
		if ord(a[i]) < ord(b[i]):
			edge.append((1, ord(a[i]) - A, ord(b[i]) - A))
		elif ord(a[i]) == ord(b[i]):
			pass
		else:
			ans = -1
			break
	if ans == 0:
		p = list(range(20))
		rank = [0] * 20
		for (w, x, y) in edge:
			(x, y) = (find(x), find(y))
			if x != y:
				union(x, y)
				ans += w
	z.append(ans)
print(*z)


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


from sys import stdin

def uf_find(n, p):
	ufl = []
	while p[n] != n:
		ufl.append(n)
		n = p[n]
	for i in ufl:
		p[i] = n
	return n

def uf_union(a, b, p, rank):
	ap = uf_find(a, p)
	bp = uf_find(b, p)
	if ap == bp:
		return True
	else:
		if rank[ap] > rank[bp]:
			p[bp] = ap
		elif rank[ap] < rank[bp]:
			p[ap] = bp
		else:
			p[bp] = ap
			rank[ap] += 1
		return False
alp = 'abcdefghijklmnopqrst'
ad = {}
for i in range(20):
	ad[alp[i]] = i
tt = int(stdin.readline())
for loop in range(tt):
	n = int(stdin.readline())
	A = stdin.readline()
	B = stdin.readline()
	lis = [[False] * 20 for i in range(20)]
	flag = True
	for i in range(n):
		if A[i] > B[i]:
			flag = False
			break
		elif A[i] < B[i]:
			lis[ad[A[i]]][ad[B[i]]] = True
	if flag:
		ans = 0
		p = [i for i in range(20)]
		rank = [0] * 20
		for j in range(20):
			for i in range(j):
				if lis[i][j] and uf_find(i, p) != uf_find(j, p):
					ans += 1
					uf_union(i, j, p, rank)
		print(ans)
	else:
		print(-1)


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


from collections import defaultdict
for _ in range(int(input())):
	n = int(input())
	s = input()
	t = input()
	d = defaultdict(set)
	chk = True
	for i in range(n):
		if s[i] > t[i]:
			chk = False
			break
		if s[i] < t[i]:
			d[s[i]].add(t[i])
	cnt = 0
	if chk:
		for i in map(chr, range(97, 97 + 26)):
			if d[i]:
				cnt += 1
				m = min(d[i])
				d[i].remove(m)
				d[m] = d[m].union(d[i])
		print(cnt)
	else:
		print(-1)


from collections import defaultdict
alphabet = [chr(c) for c in range(ord('a'), ord('t') + 1)]

def solve(a: str, b: str) -> int:
	adj = defaultdict(list)
	for (u, v) in zip(a, b):
		if u > v:
			return -1
		adj[u].append(v)
		adj[v].append(u)
	visited = set()

	def dfs(u: str):
		visited.add(u)
		for v in adj[u]:
			if v not in visited:
				dfs(v)
	res = len(alphabet)
	for letter in alphabet:
		if letter not in visited:
			dfs(letter)
			res -= 1
	return res
for _ in range(int(input())):
	n = int(input())
	print(solve(input(), input()))


for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	moves = 0
	dp = [[0 for i in range(n)] for j in range(20)]
	for i in range(n):
		dp[ord(a[i]) - ord('a')][i] = 1
	flag = 0
	for i in range(20):
		col = []
		targ = []
		for j in range(n):
			if dp[i][j] == 1:
				if ord(b[j]) - ord('a') - i > 0:
					col.append(j)
					targ.append(ord(b[j]) - ord('a'))
				elif ord(b[j]) - ord('a') - i < 0:
					flag = 1
					break
		if flag == 0:
			if col:
				moves += 1
				lol = min(targ)
				for k in col:
					dp[lol][k] = 1
	print(moves if flag == 0 else -1)


for _ in range(int(input())):
	n = int(input())
	s = input()
	t = input()
	d = {chr(ord('a') + i): set() for i in range(26)}
	stop = False
	for i in range(n):
		if s[i] == t[i]:
			continue
		if s[i] > t[i]:
			stop = True
			break
		d[s[i]].add(t[i])
	if stop:
		print(-1)
		continue
	ans = 0
	for i in range(26):
		if len(d[chr(ord('a') + i)]) == 0:
			continue
		x = min(d[chr(ord('a') + i)])
		for c in d[chr(ord('a') + i)]:
			if c != x:
				d[x].add(c)
		ans += 1
	print(ans)


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush, nsmallest
from math import ceil, floor, gcd, fabs, factorial, fmod, sqrt, inf
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
from decimal import Decimal
mod = pow(10, 9) + 7
mod2 = 998244353

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

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

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

def l():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

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

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
for _ in range(int(data())):
	n = int(data())
	s = list(data())
	t = list(data())
	r = True
	answer = 0
	d = dd(list)
	for i in range(n):
		if s[i] > t[i]:
			r = False
			break
		if s[i] == t[i]:
			continue
		d[t[i]].append(i)
	if not r:
		out(-1)
		continue
	for i in range(20):
		c = chr(i + 97)
		temp = set()
		for j in d[c]:
			temp.add(s[j])
		if not d[c]:
			continue
		for j in range(n):
			if s[j] in temp:
				s[j] = c
		answer += len(temp)
	out(answer)


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)


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


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


def rep(s, t, n):
	ans = 0
	for i in range(n):
		if s[i] > t[i]:
			return -1
	for j in range(20):
		arr = []
		x = 'u'
		ch = chr(97 + j)
		for i in range(n):
			if s[i] == ch and t[i] > s[i]:
				x = min(t[i], x)
				arr.append(i)
		if len(arr) != 0:
			ans += 1
			for i in arr:
				s[i] = x
	return ans
for _ in range(int(input())):
	n = int(input())
	s = list(input())
	t = list(input())
	print(rep(s, t, n))


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)


from sys import stdin

def inp():
	return stdin.buffer.readline().rstrip().decode('utf8')

def itg():
	return int(stdin.buffer.readline())

def mpint():
	return map(int, stdin.buffer.readline().split())

def main():
	n = itg()
	a = list(inp())
	b = inp()
	for i in range(n):
		if a[i] > b[i]:
			return -1
	ans = 0
	for c in range(20):
		char = chr(97 + c)
		indices = []
		y = 'y'
		for i in range(n):
			if a[i] == char and a[i] != b[i]:
				y = min(y, b[i])
				indices.append(i)
		if y != 'y':
			ans += 1
			for idx in indices:
				a[idx] = y
	return ans
for case in range(itg()):
	print(main())


for _ in range(int(input())):
	n = int(input())
	A = input()
	B = input()
	a = []
	b = []
	for i in A:
		a.append(i)
	for i in B:
		b.append(i)
	c = []
	cnt = 0
	check = False
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			check = True
			break
	if check:
		print('-1')
	else:
		for i in range(97, 117):
			c.append(chr(i))
		for i in range(len(c)):
			d = []
			e = []
			for j in range(n):
				if a[j] == c[i] and a[j] != b[j]:
					d.append(j)
					e.append(b[j])
			minm = 116
			for j in e:
				if ord(j) < minm:
					minm = ord(j)
			for j in d:
				a[j] = chr(minm)
			if len(d) != 0:
				cnt += 1
		print(cnt)


import sys
import math
from collections import defaultdict
import heapq
t = int(sys.stdin.readline())
for _ in range(t):
	n = int(sys.stdin.readline())
	a = list(sys.stdin.readline()[:-1])
	b = list(sys.stdin.readline()[:-1])
	z = True
	for i in range(n):
		if a[i] > b[i]:
			z = False
			break
	if not z:
		print(-1)
		continue
	dic = defaultdict(set)
	for i in range(n):
		if b[i] != a[i]:
			dic[b[i]].add(a[i])
	ans = 0
	vis = [0 for x in range(20)]
	for i in sorted(dic):
		l = set()
		newvis = [0 for x in range(20)]
		for j in dic[i]:
			toadd = j
			while vis[ord(toadd) - 97] != 0:
				toadd = vis[ord(toadd) - 97]
			l.add(toadd)
			newvis[ord(toadd) - 97] = i
		for j in l:
			vis[ord(j) - 97] = newvis[ord(j) - 97]
		ans += len(l)
	print(ans)


from sys import stdin, stdout

def arrinp():
	return [*map(int, stdin.readline().split(' '))]

def mulinp():
	return map(int, stdin.readline().split(' '))

def intinp():
	return int(stdin.readline())

def inp():
	return stdin.readline()

def solution():
	n = intinp()
	a = list(inp())
	b = inp()
	f = 0
	ls = [[]] * 26
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			f = 1
			break
	cnt = 0
	if f == 1:
		print(-1)
	else:
		for i in range(97, ord('t') + 1):
			char = chr(i)
			ls = []
			y = 'z'
			for i in range(n):
				if a[i] == char and b[i] > a[i]:
					ls.append(i)
					y = min(b[i], y)
			if ls != []:
				cnt += 1
				for j in ls:
					a[j] = y
		print(cnt)
testcases = 1
testcases = intinp()
for _ in range(testcases):
	solution()


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


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)


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


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


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)


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)


def ans(a, b):
	t1 = t2 = ''
	for i in range(n):
		if a[i] > b[i]:
			return -1
		elif a[i] != b[i]:
			t1 += a[i]
			t2 += b[i]
	a = list(t1)
	b = list(t2)
	ans = 0
	x = 'abcdefghijklmnopqrst'
	for i in x:
		y = 'z'
		pos = []
		for j in range(len(a)):
			if a[j] == i and i != b[j]:
				y = min(y, b[j])
				pos.append(j)
		if len(pos) > 0:
			ans += 1
			for j in pos:
				a[j] = y
	return ans
for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	print(ans(a, b))


import bisect
import os
import gc
import sys
from io import BytesIO, IOBase
from collections import Counter
from collections import deque
import heapq
import math
import statistics

def sin():
	return input()

def ain():
	return list(map(int, sin().split()))

def sain():
	return input().split()

def iin():
	return int(sin())
MAX = float('inf')
MIN = float('-inf')
MOD = 1000000007

def sieve(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
	s = set()
	for p in range(2, n + 1):
		if prime[p]:
			s.add(p)
	return s

def readTree(n, m):
	adj = [deque([]) for _ in range(n + 1)]
	for _ in range(m):
		(u, v) = ain()
		adj[u].append(v)
		adj[v].append(u)
	return adj

def main():
	for _ in range(iin()):
		n = iin()
		a = list(sin())
		b = list(sin())
		ans = 0
		flag = 0
		s = 'abcdefghijklmnopqrst'
		for i in range(n):
			if a[i] > b[i]:
				flag = 1
				break
		if flag:
			print(-1)
		else:
			for i in s:
				x = 't'
				d = deque([])
				for j in range(n):
					if a[j] == i and b[j] > i:
						d.append(j)
						x = min(x, b[j])
				if d:
					ans += 1
					for j in d:
						a[j] = x
			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')
if os.getcwd() == 'D:\\code':
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
	input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


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


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)


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')
import sys, threading
sys.setrecursionlimit(400000)
threading.stack_size(10 ** 8)

def dfs(x):
	global v, adj, c
	v[x] = 1
	c += 1
	for i in adj[x]:
		if not v[i]:
			dfs(i)

def main():
	global v, adj, c
	t = int(input())
	from collections import defaultdict
	for i in range(t):
		n = int(input())
		a = input()
		b = input()
		f = 1
		adj = defaultdict(set)
		v = defaultdict(int)
		ans = 0
		for j in range(n):
			if a[j] > b[j]:
				f = 0
				break
			if a[j] != b[j]:
				char = a[j]
				adj[a[j]].add(b[j])
				adj[b[j]].add(a[j])
		for i in range(97, 117):
			if not v[chr(i)]:
				c = 0
				dfs(chr(i))
				ans += c - 1
		if f:
			print(ans)
		else:
			print(-1)
th = threading.Thread(target=main)
th.start()
th.join()


from __future__ import division, print_function
MOD = 998244353
mod = 10 ** 9 + 7

def prepare_factorial():
	fact = [1]
	for i in range(1, 100005):
		fact.append(fact[-1] * i % mod)
	ifact = [0] * 100005
	ifact[100004] = pow(fact[100004], mod - 2, mod)
	for i in range(100004, 0, -1):
		ifact[i - 1] = i * ifact[i] % mod
	return (fact, ifact)
import sys
from bisect import bisect_left, bisect_right, insort
from math import floor, ceil, sqrt, degrees, atan, pi, log, sin, radians
from heapq import heappop, heapify, heappush
from collections import Counter, defaultdict, deque

def modinv(n, p):
	return pow(n, p - 2, p)

def ncr(n, r, fact, ifact):
	t = fact[n] * (ifact[r] * ifact[n - r]) % mod % mod
	return t

def intarray():
	return map(int, sys.stdin.readline().strip().split())

def array():
	return list(map(int, sys.stdin.readline().strip().split()))

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

def GCD(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

def lcm(x, y):
	return x * y // GCD(x, y)

def get_xor(n):
	return [n, 1, n + 1, 0][n % 4]

def fast_expo(a, b):
	res = 1
	while b:
		if b & 1:
			res = res * a
			res %= MOD
			b -= 1
		else:
			a = a * a
			a %= MOD
			b >>= 1
	res %= MOD
	return res

def get_n(P):
	ans = (-1 + sqrt(1 + 8 * P)) // 2
	return ans

def solve():
	n = int(input())
	a = list(input())
	b = input()
	ans = 0
	for i in range(20):
		x = 'z'
		for j in range(n):
			if a[j] == chr(97 + i):
				if a[j] > b[j]:
					flag = 0
					print(-1)
					return
				elif a[j] == b[j]:
					continue
				else:
					x = min(x, b[j])
		if x == 'z':
			continue
		for k in range(n):
			if a[k] == chr(97 + i) and a[k] != b[k]:
				a[k] = x
		ans += 1
	print(ans)
	return

def main():
	T = int(input())
	while T:
		solve()
		T -= 1
py2 = round(0.5)
if py2:
	from future_builtins import ascii, filter, hex, map, oct, zip
	range = xrange
import os, sys
from io import IOBase, BytesIO
BUFSIZE = 8192

class FastIO(BytesIO):
	newlines = 0

	def __init__(self, file):
		self._file = file
		self._fd = file.fileno()
		self.writable = 'x' in file.mode or 'w' in file.mode
		self.write = super(FastIO, self).write if self.writable else None

	def _fill(self):
		s = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
		self.seek((self.tell(), self.seek(0, 2), super(FastIO, self).write(s))[0])
		return s

	def read(self):
		while self._fill():
			pass
		return super(FastIO, self).read()

	def readline(self):
		while self.newlines == 0:
			s = self._fill()
			self.newlines = s.count(b'\n') + (not s)
		self.newlines -= 1
		return super(FastIO, self).readline()

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		if py2:
			self.write = self.buffer.write
			self.read = self.buffer.read
			self.readline = self.buffer.readline
		else:
			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')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

def comb(n, m):
	return factorial(n) / (factorial(m) * factorial(n - m)) if n >= m else 0

def perm(n, m):
	return factorial(n) // factorial(n - m) if n >= m else 0

def mdis(x1, y1, x2, y2):
	return abs(x1 - x2) + abs(y1 - y2)

def toord(c):
	return ord(c) - ord('a')
mod = 998244353
INF = float('inf')
from math import factorial, sqrt, ceil, floor
from collections import Counter, defaultdict, deque
from heapq import heapify, heappop, heappush

def main():
	for _ in range(N()):
		n = N()
		s = [ord(i) - ord('a') for i in input()]
		t = [ord(i) - ord('a') for i in input()]
		rec = [[0] * 20 for _ in range(20)]
		for i in range(n):
			if s[i] == t[i]:
				continue
			rec[s[i]][t[i]] += 1
			if s[i] > t[i]:
				print(-1)
				break
		else:
			res = 0
			for i in range(20):
				for j in range(20):
					if rec[i][j] != 0:
						res += 1
						for k in range(j + 1, 20):
							if rec[i][k]:
								rec[j][k] += rec[i][k]
								rec[i][k] = 0
			print(res)
main()


t = int(input())
for _ in range(t):
	n = int(input())
	list1 = list(input())
	list2 = list(input())
	for i in range(n):
		list1[i] = ord(list1[i]) - 97
		list2[i] = ord(list2[i]) - 97
	map1 = dict()
	for i in range(20):
		temp = []
		for j in range(i):
			temp.append(0)
		map1[i] = temp
	possible = 1
	for i in range(n):
		key = list2[i]
		value = list1[i]
		if key < value:
			possible = 0
		elif key > value:
			map1[key][value] += 1
	if possible == 0:
		print(-1)
		continue
	count = 0
	for val in map1:
		temp = map1[val]
		for i in range(len(temp)):
			if temp[i] > 0:
				count += 1
				for j in range(val + 1, 20):
					map1[j][val] += map1[j][i]
					map1[j][i] = 0
	print(count)


import sys
input = sys.stdin.readline
t = int(input())
for case in range(t):
	n = int(input())
	A_str = input().rstrip()
	B_str = input().rstrip()
	flag = True
	Trans_set = [set() for _ in range(20)]
	for i in range(n):
		if B_str[i] < A_str[i]:
			flag = False
			break
		elif A_str[i] != B_str[i]:
			Trans_set[ord(A_str[i]) - 97].add(B_str[i])
	Ans = -1
	if flag:
		Ans = 0
		for i in range(20):
			if not Trans_set[i]:
				continue
			tmp = Trans_set[i]
			nxt = min(list(tmp))
			tmp.remove(nxt)
			Trans_set[ord(nxt) - 97].update(list(tmp))
			Ans += 1
	print(Ans)


import sys
sys.setrecursionlimit(10000)
t = int(input())
for _ in range(t):
	n = int(input())
	A = input()
	B = input()
	no = False
	mydict = {}
	for i in range(n):
		if ord(A[i]) > ord(B[i]):
			no = True
		elif A[i] != B[i]:
			if A[i] not in mydict:
				mydict[A[i]] = []
			mydict[A[i]].append(B[i])
	if no is True:
		print('-1')
	else:
		ans = 0
		for i in range(97, 117):
			if chr(i) in mydict:
				minimum = min(mydict[chr(i)])
				ans += 1
				for j in mydict[chr(i)]:
					if j != minimum:
						if minimum not in mydict:
							mydict[minimum] = []
						mydict[minimum].append(j)
		print(ans)


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

def input():
	return sys.stdin.readline().rstrip()

def split_input():
	return [int(i) for i in input().split()]
tests = int(input())
for _ in range(tests):
	n = int(input())
	a = list(input())
	b = list(input())
	s = [[0 for i in range(20)] for i in range(20)]
	for i in range(n):
		if b[i] < a[i]:
			print(-1)
			break
		if b[i] == a[i]:
			continue
		s[ord(a[i]) - ord('a')][ord(b[i]) - ord('a')] += 1
	else:
		cnt = 0
		for i in range(20):
			tmp = -1
			for j in range(20):
				if s[i][j] != 0:
					tmp = j
					break
			if tmp != -1:
				cnt += 1
				for j in range(tmp + 1, 20):
					s[tmp][j] += s[i][j]
		print(cnt)


import io
import os
from collections import Counter, defaultdict, deque

def solve(N, A, B):
	A = [ord(x) - ord('a') for x in A]
	B = [ord(x) - ord('a') for x in B]
	counts = Counter()
	for (a, b) in zip(A, B):
		if a > b:
			return -1
		counts[a, b] += 1
	moves = 0
	for x in range(20):
		for y in range(x + 1, 20):
			if counts[x, y]:
				for z in range(y, 20):
					counts[y, z] += counts[x, z]
					counts[x, z] = 0
				moves += 1
				break
	return moves
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
T = int(input())
for t in range(T):
	(N,) = [int(x) for x in input().split()]
	A = input().decode().rstrip()
	B = input().decode().rstrip()
	ans = solve(N, A, B)
	print(ans)


from collections import defaultdict

def f(n, a, b):
	d = defaultdict(set)
	for i in range(n):
		if a[i] > b[i]:
			return -1
		elif a[i] < b[i]:
			d[a[i]].add(b[i])
	count = 0
	for x in 'abcdefghijklmnopqrs':
		if x in d:
			if x in d[x]:
				d[x].remove(x)
			if len(d[x]) != 0:
				y = min(d[x])
				d[y] = d[y].union(d[x])
				if x in d[y]:
					d[y].remove(x)
				count += 1
	return count
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	print(f(n, a, b))


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)


import heapq

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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
t1 = int(input())
for _ in range(t1):
	n = int(input())
	a = input()
	b = input()
	fail = 0
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			print(-1)
			fail = 1
			break
	if fail == 1:
		continue
	uf = UnionFind(20)
	for i in range(n):
		uf.union(ord(a[i]) - 97, ord(b[i]) - 97)
	ans = 20
	ans -= uf.group_count()
	print(ans)


for _ in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	flag = 0
	for i in range(n):
		if a[i] > b[i]:
			flag = 1
			break
	if flag == 1:
		print(-1)
		continue
	ans = 0
	for x in range(20):
		pos = []
		y = 'z'
		for i in range(n):
			if a[i] == chr(x + 97) and b[i] > chr(x + 97):
				pos.append(i)
				y = min(y, b[i])
		if len(pos) > 0:
			ans += 1
			for p in pos:
				a[p] = y
	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)


from sys import stdin, stdout
import collections, heapq, bisect, math
input = stdin.readline

def rint():
	return int(input())

def rstr():
	return input().strip()

def rlstr():
	return list(input().strip().split())

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

def main():
	n = rint()
	(a, b) = (rstr(), rstr())
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			return
	p = [i for i in range(20)]
	res = n

	def find(x):
		if p[x] != x:
			p[x] = find(p[x])
		return p[x]
	for i in range(n):
		u = ord(a[i]) - ord('a')
		v = ord(b[i]) - ord('a')
		pu = find(u)
		pv = find(v)
		if pu == pv:
			res -= 1
		else:
			p[pu] = pv
	print(res)
for _ in range(rint()):
	main()


def gather_group(forwards, backwards, inital_node):
	group = set()
	to_do = [inital_node]
	seen = set([inital_node])
	while to_do:
		node = to_do.pop(0)
		group.add(node)
		if node in forwards:
			for connection in forwards[node]:
				if connection not in seen:
					seen.add(connection)
					to_do.append(connection)
			del forwards[node]
		if node in backwards:
			for connection in backwards[node]:
				if connection not in seen:
					seen.add(connection)
					to_do.append(connection)
			del backwards[node]
	return len(group)

def solve(n, A, B):
	forwards = {}
	backwards = {}
	for i in range(n):
		if A[i] > B[i]:
			return -1
		elif A[i] < B[i]:
			if A[i] not in forwards:
				forwards[A[i]] = set([B[i]])
			else:
				forwards[A[i]].add(B[i])
			if B[i] not in backwards:
				backwards[B[i]] = set([A[i]])
			else:
				backwards[B[i]].add(A[i])
	moves = 0
	fkeys = list(forwards.keys())
	while fkeys:
		node = fkeys.pop(0)
		if node not in forwards and node not in backwards:
			continue
		group_size = gather_group(forwards, backwards, node)
		moves += group_size - 1
	return moves

def main():
	t = int(input())
	for _ in range(t):
		n = int(input())
		A = input()
		B = input()
		print(solve(n, A, B))
main()


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)


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)


import sys

def input():
	return sys.stdin.readline().rstrip()

def input_split():
	return [int(i) for i in input().split()]
testCases = int(input())
answers = []

def cast(char):
	return ord(char) - ord('a')

def replace_el(lis, old_el, new_el):
	return [a if a != old_el else new_el for a in lis]
for _ in range(testCases):
	n = int(input())
	arr = [cast(i) for i in input()]
	barr = [cast(i) for i in input()]
	count = 0
	ans = 0
	for to_fix in range(20):
		mismatched = set()
		indices = []
		for i in range(n):
			x = arr[i]
			y = barr[i]
			if x == y:
				pass
			elif x != y and x == to_fix:
				indices.append(i)
				mismatched.add(y)
		mismatched = list(mismatched)
		if len(mismatched) == 0:
			pass
		else:
			mini = min(mismatched)
			if mini < to_fix:
				ans = -1
				break
			else:
				for ind in indices:
					arr[ind] = mini
				count += 1
				if to_fix == 19:
					count += len(mismatched) - 1
	if ans != -1:
		ans = count
	answers.append(ans)
print(*answers, sep='\n')


from os import path
import sys
from heapq import heappush, heappop
from functools import cmp_to_key as ctk
from collections import deque, defaultdict as dd
from bisect import bisect, bisect_left, bisect_right, insort, insort_left, insort_right
from itertools import permutations
from datetime import datetime
from math import ceil, sqrt, log, gcd

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

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

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

def li():
	return list(mi())
abc = 'abcdefghijklmnopqrstuvwxyz'
mod = 1000000007
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def bo(i):
	return ord(i) - ord('a')
file = 1

def solve():
	for _ in range(ii()):
		par = [i for i in range(20)]

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

		def union_set(a, b):
			a = find_set(a)
			b = find_set(b)
			if a != b:
				if a > b:
					(a, b) = (b, a)
				par[b] = a
				return 1
			return 0
		n = ii()
		a = si()
		b = si()
		ans = 0
		for i in range(n):
			if a[i] > b[i]:
				ans = -1
				break
			if a[i] == b[i]:
				continue
			if union_set(bo(a[i]), bo(b[i])):
				ans += 1
		print(ans)
if file:
	if path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	else:
		input = sys.stdin.readline
solve()


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)


for test in range(int(input())):
	n = int(input())
	a = list(input())
	b = list(input())
	poss = 1
	for i in range(n):
		if ord(a[i]) > ord(b[i]):
			print(-1)
			poss = 0
			break
	if poss == 1:
		moves = 0
		while True:
			minc = 'z'
			minbb = 'z'
			for i in range(n):
				if a[i] != b[i]:
					if a[i] < minc:
						minc = a[i]
						minbb = b[i]
					elif a[i] == minc:
						minbb = min(minbb, b[i])
			if minc == 'z':
				break
			moves += 1
			for i in range(n):
				if a[i] == minc and a[i] != b[i]:
					a[i] = minbb
		print(moves)


import sys
for _ in range(int(input())):
	n = int(input())
	a = input()
	b = input()
	f = True
	for i in range(n):
		if a[i] > b[i]:
			f = False
			break
	if f == False:
		print(-1)
		continue
	temp = [[0] * 20 for i in range(20)]
	for i in range(n):
		temp[ord(a[i]) - ord('a')][ord(b[i]) - ord('a')] += 1
	ans = 0
	for i in range(20):
		for j in range(20):
			if temp[i][j] > 0 and i != j:
				ans += 1
				for k in range(j + 1, 20):
					temp[j][k] += temp[i][k]
					temp[i][k] = 0
				break
	print(ans)


import os, io
from sys import stdout
import collections
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def primes(n):
	sieve = [True] * n
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i]:
			sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
	return [2] + [i for i in range(3, n, 2) if sieve[i]]

def binomial_coefficient(n, k):
	if 0 <= k <= n:
		ntok = 1
		ktok = 1
		for t in range(1, min(k, n - k) + 1):
			ntok *= n
			ktok *= t
			n -= 1
		return ntok // ktok
	else:
		return 0

def powerOfK(k, max):
	if k == 1:
		return [1]
	if k == -1:
		return [-1, 1]
	result = []
	n = 1
	while n <= max:
		result.append(n)
		n *= k
	return result

def divisors(n):
	i = 1
	result = []
	while i * i <= n:
		if n % i == 0:
			if n / i == i:
				result.append(i)
			else:
				result.append(i)
				result.append(n / i)
		i += 1
	return result

def distance(xa, ya, xb, yb):
	return ((ya - yb) ** 2 + (xa - xb) ** 2) ** 0.5

def digitsSum(n):
	if n == 0:
		return 0
	r = 0
	while n > 0:
		r += n % 10
		n //= 10
	return r

def isValid(i, j, n, m):
	return i >= 0 and i < n and (j >= 0) and (j < m)

def print_grid(grid):
	for line in grid:
		print(' '.join(map(str, line)))

def kadane(a, size):
	max_so_far = 0
	max_ending_here = 0
	for i in range(0, size):
		max_ending_here = max_ending_here + a[i]
		if max_so_far < max_ending_here:
			max_so_far = max_ending_here
		if max_ending_here < 0:
			max_ending_here = 0
	return max_so_far

def prefixSum(arr):
	for i in range(1, len(arr)):
		arr[i] = arr[i] + arr[i - 1]
	return arr

def ceil(n, d):
	if n % d == 0:
		return n // d
	else:
		return n // d + 1

def _abs(a, b):
	return int(abs(a - b))

def evenodd(l):
	even = [e for e in l if e & 1 == 0]
	odd = [e for e in l if e & 1]
	return (even, odd)
from collections import defaultdict

def solve(n, a, b):
	g = defaultdict(set)
	for i in range(n):
		if b[i] < a[i]:
			return -1
		if a[i] != b[i]:
			g[a[i]].add(b[i])
	alph = 'abcdefghijklmnopqrst'
	ans = 0
	for char in alph:
		if char in g:
			gchars = g[char]
			minchar = min(gchars)
			for otherchar in gchars:
				if otherchar != minchar:
					g[minchar].add(otherchar)
			ans += 1
	return ans
for _ in range(int(input())):
	n = int(input())
	a = list(input().decode('utf-8').strip())
	b = list(input().decode('utf-8').strip())
	ans = solve(n, a, b)
	print(ans)


import sys
input = sys.stdin.readline

class UnionFind:

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

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

	def merge(self, x, y):
		x = self.root(x)
		y = self.root(y)
		if x == y:
			return
		if self.parent[x] > self.parent[y]:
			(x, y) = (y, x)
		self.parent[x] += self.parent[y]
		self.parent[y] = x
		self.cnt -= 1

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

	def get_size(self, x):
		return -self.parent[self.root(x)]

	def get_cnt(self):
		return self.cnt
t = int(input())
alph = 'abcdefghijklmnopqrstuvwxyz'
to_ind = {char: i for (i, char) in enumerate(alph)}
for _ in range(t):
	n = int(input())
	a = list(input())
	b = list(input())
	flag = False
	for i in range(n):
		if a[i] > b[i]:
			print(-1)
			flag = True
			break
	if flag:
		continue
	uf = UnionFind(26)
	for i in range(n):
		u = to_ind[a[i]]
		v = to_ind[b[i]]
		uf.merge(u, v)
	print(26 - uf.get_cnt())


from sys import stdin
import bisect
t = int(stdin.readline().strip())
for _ in range(t):
	n = int(stdin.readline().strip())
	A = stdin.readline().strip()
	B = stdin.readline().strip()
	A = [ord(c) - ord('a') for c in A]
	B = [ord(c) - ord('a') for c in B]
	S = sorted(list(set(zip(A, B))))
	count = 0
	while len(S) > 0:
		(a, b) = S[0]
		if a > b:
			count = -1
			break
		elif a == b:
			S.remove((a, b))
		else:
			S.remove((a, b))
			count += 1
			while len(S) > 0 and S[0][0] == a:
				(x, y) = S.pop(0)
				bisect.insort(S, (b, y))
	print(count)


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


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


line_init = int(input())

def recur(dic, key):
	if not mark[key]:
		mark[key] = True
		if key in dic.keys() and dic[key]:
			for h in dic[key]:
				recur(dic, h)
	return 0
for i in range(line_init):
	line_1 = int(input())
	line_2 = input()
	line_3 = input()
	world = set(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'])
	dic = {x: set() for x in world}
	count = 0
	for i in range(line_1):
		if line_2[i] > line_3[i]:
			count = -1
			break
		if line_2[i] != line_3[i]:
			dic[line_2[i]].add(line_3[i])
			dic[line_3[i]].add(line_2[i])
	if count != -1:
		alf = list(world)
		alf.sort()
		mark = dict.fromkeys(alf, False)
		count = 20
		for i in range(len(alf)):
			if not mark[alf[i]]:
				count -= 1
				recur(dic, alf[i])
	print(count)


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)


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)