Polycarp came up with a new programming language. There are only two types of statements in it:

"x := s": assign the variable named x the value s (where s is a string). For example, the statement var := hello assigns the variable named var the value hello. Note that s is the value of a string, not the name of a variable. Between the variable name, the := operator and the string contains exactly one space each.

"x = a + b": assign the variable named x the concatenation of values of two variables a and b. For example, if the program consists of three statements a := hello, b := world, c = a + b, then the variable c will contain the string helloworld. It is guaranteed that the program is correct and the variables a and b were previously defined. There is exactly one space between the variable names and the = and + operators.

All variable names and strings only consist of lowercase letters of the English alphabet and do not exceed $5$ characters.

The result of the program is the number of occurrences of string haha in the string that was written to the variable in the last statement.

Polycarp was very tired while inventing that language. He asks you to implement it. Your task is — for given program statements calculate the number of occurrences of string haha in the last assigned variable.


-----Input-----

The first line contains an integer $t$ ($1 \le t \le 10^3$). Then $t$ test cases follow.

The first line of each test case contains a single integer $n$ ($1 \le n \le 50$) — the number of statements in the program. All variable names and strings are guaranteed to consist only of lowercase letters of the English alphabet and do not exceed $5$ characters.

This is followed by $n$ lines describing the statements in the format described above. It is guaranteed that the program is correct.


-----Output-----

For each set of input data, output the number of occurrences of the haha substring in the string that was written to the variable in the last statement.


-----Examples-----

Input
4
6
a := h
b := aha
c = a + b
c = c + c
e = c + c
d = a + c
15
x := haha
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
x = x + x
1
haha := hah
5
haahh := aaaha
ahhhh = haahh + haahh
haahh = haahh + haahh
ahhhh = ahhhh + haahh
ahhaa = haahh + ahhhh
Output
3
32767
0
0


-----Note-----

In the first test case the resulting value of d is hhahahaha.

Source: codeforces | Difficulty: HARD
Tags: Matrices

Data structures

Implementation

String algorithms


Solutions:
t = int(input())
for _ in range(t):
	n = int(input())
	v = {}
	last = ''
	for _ in range(n):
		c = input()
		if ':=' in c:
			(w, s) = c.split(' := ')
			(f, e) = (s[:4], s[-4:])
			q = (s[:4] == 'haha') + (s[1:] == 'haha')
			v[w] = (f, e, q)
			last = w
		else:
			(w, w1, w2) = c.replace('+', '=').split(' = ')
			q = v[w1][2] + v[w2][2] + ((v[w1][1][-3:] + v[w2][0][:1] == 'haha') + (v[w1][1][-2:] + v[w2][0][:2] == 'haha') + (v[w1][1][-1:] + v[w2][0][:3] == 'haha'))
			(f, e) = ((v[w1][0] + v[w2][0])[:4], (v[w1][1] + v[w2][1])[-4:])
			v[w] = (f, e, q)
			last = w
	print(v[last][2])


def first(a):
	s = ''
	for i in range(0, 3):
		if i >= len(a):
			return s
		else:
			s += a[i]
	return s

def last(a):
	s = ''
	n = len(a)
	for i in range(0, 3):
		if n + i - 3 < 0:
			continue
		else:
			s += a[n + i - 3]
	return s

def count(a):
	b = 0
	if len(a) < 4:
		return 0
	for i in range(0, len(a) - 3):
		if a[i] == 'h' and a[i + 1] == 'a' and (a[i + 2] == 'h') and (a[i + 3] == 'a'):
			b += 1
	return b
t = int(input())
for _ in range(0, t):
	d = {}
	ans = 0
	n = int(input())
	for __ in range(0, n):
		s = input().split()
		if s[1] == ':=':
			d[s[0]] = [count(s[2]), first(s[2]), last(s[2])]
		else:
			d[s[0]] = [d[s[2]][0] + d[s[4]][0] + count(d[s[2]][2] + d[s[4]][1]), first(d[s[2]][1] + d[s[4]][1]), last(d[s[2]][2] + d[s[4]][2])]
		ans = d[s[0]][0]
	print(ans)


def f(a):
	b = 0
	for i in range(len(a) - 3):
		if a[i] + a[i + 1] + a[i + 2] + a[i + 3] == 'haha':
			b += 1
	return b
for z in range(int(input())):
	b = []
	b1 = 0
	c = 0
	for y in range(int(input())):
		a = input().split()
		if len(a) == 3:
			for i in range(b1):
				if b[i][0] == a[0]:
					b[i] = [a[0], f(a[2]), a[2][:3], a[2][-3:]]
					c = b[i][1]
					break
			else:
				b.append([a[0], f(a[2]), a[2][:3], a[2][-3:]])
				c = b[b1][1]
				b1 += 1
		else:
			d = []
			e = []
			for i in range(b1):
				if b[i][0] == a[2]:
					d = b[i]
				if b[i][0] == a[4]:
					e = b[i]
			for i in range(b1):
				if b[i][0] == a[0]:
					b[i] = [a[0], d[1] + e[1] + f(d[3] + e[2]), str(d[2] + e[3])[:3], str(d[2] + e[3])[-3:]]
					c = b[i][1]
					break
			else:
				b.append([a[0], d[1] + e[1] + f(d[3] + e[2]), str(d[2] + e[3])[:3], str(d[2] + e[3])[-3:]])
				c = b[b1][1]
				b1 += 1
	print(c)


class Element:

	def __init__(self, s=''):
		if len(s) >= 6:
			self.pref = s[:3]
			self.suf = s[-3:]
		else:
			self.pref = s[:3]
			self.suf = s[3:]
		self.ans = calc(s)
		self.orig = ''
		self.len = len(s)

def calc(s: str):
	ans = 0
	for (num, i) in enumerate(s):
		ans += s[num:num + 4] == 'haha'
	return ans
t = int(input())
for _ in range(t):
	n = int(input())
	a = [input() for i in range(n)]
	d = dict()
	for i in a:
		if ':=' in i:
			(a1, shit, a2) = i.split()
			new = Element(a2)
			new.orig = a2
			d[a1] = Element(a2)
		else:
			(a1, shit, b1, plus, b2) = i.split()
			new = Element()
			new.ans = d[b1].ans + d[b2].ans
			s = d[b1].pref + d[b1].suf + d[b2].pref + d[b2].suf
			if len(s) >= 6:
				new.pref = s[:3]
				new.suf = s[-3:]
			else:
				new.pref = s[:3]
				new.suf = s[3:]
			new.ans += calc((d[b1].pref + d[b1].suf)[-3:] + (d[b2].pref + d[b2].suf)[:3])
			d[a1] = new
	print(d[a[-1].split()[0]].ans)


import sys
input = sys.stdin.readline
a = [(0, 0), (2, 0), (0, 0), (2, 1)]
h = [(1, 0), (1, 0), (3, 0), (1, 0)]
z = [(0, 0), (0, 0), (0, 0), (0, 0)]

def solve():
	n = int(input())
	vars = dict()
	last = None
	for i in range(n):
		tmp = input().split()
		if tmp[1] == ':=':
			v1 = None
			if tmp[2][0] == 'a':
				v1 = a
			elif tmp[2][0] == 'h':
				v1 = h
			else:
				v1 = z
			for j in tmp[2][1:]:
				if j == 'a':
					v2 = a
				elif j == 'h':
					v2 = h
				else:
					v2 = z
				v = [(v2[v1[i][0]][0], v2[v1[i][0]][1] + v1[i][1]) for i in range(4)]
				v1 = v
			vars[tmp[0]] = v1
			last = v1
		else:
			v1 = vars[tmp[2]]
			v2 = vars[tmp[4]]
			last = [(v2[v1[i][0]][0], v2[v1[i][0]][1] + v1[i][1]) for i in range(4)]
			vars[tmp[0]] = last
	print(last[0][1])
for i in range(int(input())):
	solve()


import sys
input = sys.stdin.readline

def count2(S):
	ANS = 0
	for i in range(len(S)):
		if S[i:i + 4] == 'haha':
			ANS += 1
	return ANS
t = int(input())
for tests in range(t):
	n = int(input())
	A = []
	D = dict()
	for i in range(n):
		x = input().split()
		if x[1] == ':=':
			if x[0] in D:
				A[D[x[0]]] = (x[2], count2(x[2]))
			else:
				A.append((x[2], count2(x[2])))
				D[x[0]] = len(A) - 1
		else:
			(x1, xcount) = A[D[x[2]]]
			(y1, ycount) = A[D[x[4]]]
			if type(x1) == tuple or type(y1) == tuple:
				if type(x1) == tuple and type(y1) == tuple:
					(xfirst, xlast) = x1
					(yfirst, ylast) = y1
					c = xcount + ycount + count2(xlast + yfirst)
					if x[0] in D:
						A[D[x[0]]] = ((xfirst, ylast), c)
					else:
						A.append(((xfirst, ylast), c))
						D[x[0]] = len(A) - 1
				elif type(x1) == tuple:
					(xfirst, xlast) = x1
					c = xcount + count2(xlast + y1)
					ylast = (xlast + y1)[-3:]
					if x[0] in D:
						A[D[x[0]]] = ((xfirst, ylast), c)
					else:
						A.append(((xfirst, ylast), c))
						D[x[0]] = len(A) - 1
				else:
					(yfirst, ylast) = y1
					c = ycount + count2(x1 + yfirst)
					xfirst = (x1 + yfirst)[:3]
					if x[0] in D:
						A[D[x[0]]] = ((xfirst, ylast), c)
					else:
						A.append(((xfirst, ylast), c))
						D[x[0]] = len(A) - 1
			else:
				xx = x1 + y1
				c = count2(xx)
				if len(xx) >= 6:
					xfirst = xx[:3]
					xlast = xx[-3:]
					if x[0] in D:
						A[D[x[0]]] = ((xfirst, xlast), c)
					else:
						A.append(((xfirst, xlast), c))
						D[x[0]] = len(A) - 1
				elif x[0] in D:
					A[D[x[0]]] = (xx, c)
				else:
					A.append((xx, c))
					D[x[0]] = len(A) - 1
	print(A[D[x[0]]][1])


from sys import stdin, stdout
readline = stdin.readline

def find(s):
	cnt = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			cnt += 1
	return cnt

def main():
	t = int(readline().strip())
	for _ in range(t):
		n = int(readline().strip())
		d = dict()
		for i in range(n):
			s = readline().strip()
			last = ''
			if ':=' in s:
				(s1, s2) = s.split(' := ')
				if len(s2) >= 4:
					d[s1] = [s2[:3], s2[-3:], find(s2)]
				else:
					d[s1] = [s2, s2, 0]
				last = d[s1]
			else:
				(s1, s2) = s.split(' = ')
				(s3, s4) = s2.split(' + ')
				temp = d[s3][1] + d[s4][0]
				temp1 = d[s3][0]
				if len(temp1) < 3:
					temp1 += d[s4][0]
				temp1 = temp1[:3]
				temp2 = d[s4][1]
				if len(temp2) < 3:
					temp2 = d[s3][1] + temp2
				temp2 = temp2[-3:]
				d[s1] = [temp1, temp2, find(temp) + d[s3][2] + d[s4][2]]
				last = d[s1]
		print(last[2])
main()


import sys, os.path
import copy
from collections import defaultdict as dd
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 cnt(s):
	match = 'haha'
	ans = 0
	for i in range(len(s)):
		if s[i] == match[0]:
			flag = True
			if i + 3 >= len(s):
				continue
			for j in range(i + 1, min(i + 4, len(s))):
				if s[j] != match[j - i]:
					flag = False
			if flag:
				ans += 1
	return ans
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
for _ in range(int(input())):
	n = int(input())
	d = dd(list)
	final = ''
	for i in range(n):
		s = input()
		flag = True
		for i in range(len(s)):
			if s[i] == '+':
				flag = False
				break
		if flag:
			(final, s) = map(str, s.split(' := '))
			ct = cnt(s)
			d[final] = [ct, s[:3], s[-3:]]
		else:
			(final, inp) = map(str, s.split(' = '))
			(f, s) = map(str, inp.split(' + '))
			ss = d[f][2] + d[s][1]
			ct = cnt(ss)
			ct0 = d[f][0] + d[s][0]
			first = d[f][1]
			second = d[s][2]
			if len(d[f][1]) < 3:
				first = ss[:3]
			if len(d[s][2]) < 3:
				second = ss[-3:]
			d[final] = [ct + ct0, first, second]
	print(d[final][0])


def count(s):
	ans = 0
	for i in range(len(s)):
		if s[i:i + 4] == 'haha':
			ans += 1
	return ans

def modify(s):
	if len(s) >= 3:
		return s[:3] + '|' + s[-3:]
	else:
		return s

def solve(statements):
	vars = {}
	vars_count = {}
	cur_var = ''
	for statement in statements:
		items = statement.split(' ')
		cur_var = items[0]
		if len(items) == 3:
			vars_count[cur_var] = count(items[2])
			vars[cur_var] = modify(items[2])
		elif len(items) == 5:
			vars[cur_var] = vars[items[2]] + vars[items[4]]
			vars_count[cur_var] = vars_count[items[2]] + vars_count[items[4]] + count(vars[cur_var])
			vars[cur_var] = modify(vars[cur_var])
	return vars_count[cur_var]
t = int(input())
for i in range(t):
	n = int(input())
	statements = [input().strip() for _ in range(n)]
	print(solve(statements))


import sys, io, os
Z = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
O = []
for _ in range(int(Z())):
	n = int(Z())
	d = {}
	for i in range(n):
		s = Z().split()
		if len(s) == 3:
			(c, t) = (s[0], s[2])
			if len(t) <= 3:
				d[c] = (t, 0, t)
			else:
				w = any((t[j:j + 4] == b'haha' for j in range(len(t) - 3)))
				d[c] = (t[:3], w, t[-3:])
		else:
			(c, a, b) = (s[0], s[2], s[4])
			(e, f, g) = d[a]
			(m, n, o) = d[b]
			t = g + m
			w = sum((t[j:j + 4] == b'haha' for j in range(len(t) - 3)))
			if len(e) < 3:
				e = t[:3]
			if len(o) < 3:
				o = t[-3:]
			d[c] = (e, f + w + n, o)
	O.append(str(int(d[c][1])))
print('\n'.join(O))


import sys
readline = sys.stdin.readline

def count(s):
	cnt = 0
	start = -1
	for start in iter(lambda : s.find('haha', start + 1), -1):
		cnt += 1
	return cnt

def solve():
	n = int(readline().strip())
	t = dict()
	ans = 0
	for _ in range(n):
		s = readline().strip()
		if ':=' in s:
			(x, s) = s.split(' := ')
			ans = count(s)
			t[x] = [ans, s[:3], s[-3:]]
		else:
			(x, y) = s.split(' = ')
			(a, b) = y.split(' + ')
			ans = t[a][0] + t[b][0] + count(t[a][-1] + t[b][1])
			(aa, bb) = (t[a][1], t[b][-1])
			if len(t[a][1]) != 3:
				aa = (t[a][1] + t[b][1])[:3]
			if len(t[b][1]) != 3:
				bb = (t[a][-1] + t[b][1])[-3:]
			t[x] = [ans, aa, bb]
	print(ans)
n = int(readline().strip())
for _ in range(n):
	solve()


import sys, os.path
import copy
from collections import defaultdict as dd

def cnt(s):
	count = 0
	pos = 0
	while pos > -1:
		pos = s.find('haha', pos)
		if pos > -1:
			count += 1
			pos += 1
	return count
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
for _ in range(int(input())):
	n = int(input())
	d = dd(list)
	final = ''
	for i in range(n):
		s = input()
		flag = True
		for i in range(len(s)):
			if s[i] == '+':
				flag = False
				break
		if flag:
			(final, s) = map(str, s.split(' := '))
			ct = cnt(s)
			d[final] = [ct, s[:3], s[-3:]]
		else:
			(final, inp) = map(str, s.split(' = '))
			(f, s) = map(str, inp.split(' + '))
			ss = d[f][2] + d[s][1]
			ct = cnt(ss)
			ct0 = d[f][0] + d[s][0]
			first = d[f][1]
			second = d[s][2]
			if len(d[f][1]) < 3:
				first = ss[:3]
			if len(d[s][2]) < 3:
				second = ss[-3:]
			d[final] = [ct + ct0, first, second]
	print(d[final][0])


from collections import defaultdict

def assignment(arr):
	s = arr[1]
	count = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			count += 1
	pref = ''
	suff = ''
	for i in range(0, min(len(s), 3)):
		pref += s[i]
	for j in range(max(len(s) - 3, 0), len(s)):
		suff += s[j]
	d[arr[0]] = [count, pref, suff]

def concat(arr):
	var = arr[0]
	one = arr[2]
	two = arr[4]
	count = d[one][0] + d[two][0]
	for i in range(min(3, len(d[one][1]))):
		try:
			if d[one][2][i:] + d[two][1][:4 - len(d[one][2][i:])] == 'haha':
				count += 1
		except:
			pass
	pref = d[one][1]
	suff = d[two][2]
	ind = 0
	while len(pref) != 3 and ind < len(d[two][1]):
		pref += d[two][1][ind]
		ind += 1
	ind = len(d[one][2]) - 1
	while len(suff) != 3 and ind >= 0:
		suff = d[one][2][ind] + suff
		ind -= 1
	d[var] = [count, pref, suff]
t = int(input())
for _ in range(t):
	n = int(input())
	d = defaultdict(list)
	for i in range(n):
		s = input()
		if s.split()[1] == ':=':
			assignment(s.split(' := '))
		else:
			concat(s.split())
		if i == n - 1:
			print(d[s.split()[0]][0])


import os
import sys
from io import BytesIO, IOBase

def solve(x):
	(n, su) = (len(x), 0)
	for i in range(n - 3):
		su += x[i:i + 4] == 'haha'
	return su

def main():
	for _ in range(int(input())):
		n = int(input())
		b = {}
		for i in range(n):
			x = input().split()
			if ':=' == x[1]:
				b[x[0]] = (x[2][:3], x[2][max(0, len(x[2]) - 3):], solve(x[2]))
			else:
				(xx, yy) = (b[x[2]], b[x[4]])
				z = xx[0] + yy[1]
				b[x[0]] = (z[:3], z[max(0, len(z) - 3):], xx[2] + yy[2] + solve(xx[1] + yy[0]))
		print(b[x[0]][2])
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


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

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
t = int(input())

def add(s):
	for i in range(len(s)):
		if s[i] == ':':
			if len(s[i + 3:]) > 3:
				if s[i + 3:][:4] == 'haha' or s[i + 3:][1:] == 'haha':
					dict[s[:i - 1]] = [s[i + 3:][:3], s[i + 3:][-3:], 1]
				else:
					dict[s[:i - 1]] = [s[i + 3:][:3], s[i + 3:][-3:], 0]
			else:
				dict[s[:i - 1]] = [s[i + 3:], s[i + 3:], 0]
			return dict[s[:i - 1]][2]

def update(s):
	i = 0
	j = 0
	for k in range(len(s)):
		if s[k] == '=':
			i = k
		elif s[k] == '+':
			j = k
	c = s[:i - 1]
	a = s[i + 2:j - 1]
	b = s[j + 2:]
	if c not in dict:
		dict[c] = [0, 0, 0]
	count = dict[a][2] + dict[b][2]
	word = dict[a][1] + dict[b][0]
	if len(word) > 3:
		for i in range(len(word)):
			for j in range(i + 3, len(word)):
				if word[i:j + 1] == 'haha':
					count += 1
	dict[c][2] = count
	if len(dict[a][0]) > 2:
		dict[c][0] = dict[a][0]
	elif len(dict[a][1] + dict[b][0]) > 3:
		dict[c][0] = (dict[a][1] + dict[b][0])[:3]
	else:
		dict[c][0] = dict[a][1] + dict[b][0]
	if len(dict[b][1]) > 2:
		dict[c][1] = dict[b][1]
	elif len(dict[a][1] + dict[b][0]) > 3:
		dict[c][0] = (dict[a][1] + dict[b][0])[-3:]
	else:
		dict[c][0] = dict[a][1] + dict[b][0]
	return dict[c][2]
while t:
	t -= 1
	n = int(input())
	dict = {}
	for i in range(n):
		s = input()
		if ':' in s:
			ans = add(s)
		else:
			ans = update(s)
	print(ans)


t = int(input())
curvars = {}

def concat(a, b):
	(pa, sa, na) = a
	(pb, sb, nb) = b
	x = 0
	for i in range(0, 10):
		if (sa + pb)[i:i + 4] == 'haha':
			x += 1
	return ((pa + pb)[:3], (sa + sb)[-3:], na + nb + x)
for _ in range(t):
	n = int(input())
	for _ in range(n):
		s = input()
		if ':=' in s:
			(name, _, val) = s.split()
			curvars[name] = (val[:3], val[-3:], val.count('haha'))
		else:
			(name, _, a, _, b) = s.split()
			curvars[name] = concat(curvars[a], curvars[b])
	print(curvars[name][2])


import collections
import functools
import math
import random
import sys
import bisect
import io, os
input = sys.stdin.readline

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

def funnysub():

	def countrep(s):
		c = 0
		for i in range(len(s) - 3):
			if s[i] == s[i + 2] == 'h' and s[i + 1] == s[i + 3] == 'a':
				c += 1
		return c
	for _ in range(int(input())):
		d = dict()
		count = dict()
		for _ in range(int(input())):
			(a, t, *b) = input().split()
			if t == ':=':
				d[a] = [b[0][:3], b[0][-3:]]
				count[a] = countrep(b[0])
			else:
				(fir, sec) = (b[0], b[2])
				count[a] = count[fir] + count[sec]
				count[a] += countrep(d[fir][1] + d[sec][0])
				d[a] = [d[fir][0] + d[sec][0][:3 - len(d[fir][0])], d[fir][1][len(d[fir][1]) - len(d[sec][1]) + 3:] + d[sec][1]]
		print(count[a])
funnysub()


import re
i = input
t = int(i())
while t:
	t -= 1
	p = {}
	n = int(i())
	while n:
		n -= 1
		s = i()
		a = s.split()[::2]
		if ':' in s:
			(k, v) = a
			p[k] = (v[:3], v[-3:], v.count('haha'))
		else:
			(k, x, y) = a
			(a, b, c) = p[x]
			(d, e, f) = p[y]
			p[k] = ((a + d)[:3], (b + e)[-3:], c + f + len(re.findall('(?=haha)', b + d)))
	print(p[k][2])


for t in range(int(input())):
	store = {}
	var = ''
	for i in range(int(input())):
		a = input().split()
		var = a[0]
		if a[1] == ':=':
			c = a[2].count('haha')
			store[var] = [c, a[2][:3], a[2][-3:]]
		else:
			c = store[a[2]][0] + store[a[4]][0]
			x = store[a[2]][2] + store[a[4]][1]
			for j in range(len(x)):
				if x[j:j + 4] == 'haha':
					c += 1
			s1 = (store[a[2]][1] + store[a[4]][1])[:3]
			s2 = (store[a[2]][2] + store[a[4]][2])[-3:]
			store[var] = [c, s1, s2]
	print(store[var][0])


import sys
pl = 1
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())

def ff():
	sys.stdout.flush()
t = fi()
u = 'haha'
while t > 0:
	t -= 1
	n = fi()
	d = {}
	for i in range(n):
		s = input().rstrip().split(' ')
		if s[1] == ':=':
			v = s[0]
			p = s[2][:4]
			q = s[2][len(s) - 3:]
			c = 0
			for j in range(len(s[2]) - 3):
				if s[2][j:j + 4] == u:
					c += 1
			d[s[0]] = [p, q, c, len(s[2])]
		else:
			v = s[0]
			p = s[2]
			q = s[4]
			r = d[p][0]
			g = d[q][1]
			if d[p][3] < 4:
				f = d[p][0] + d[q][1]
				r = f[:4]
			if d[q][3] < 4:
				f = d[p][1] + d[q][0]
				g = f[:4]
			c = -d[p][1].count(u) - d[q][0].count(u)
			w = d[p][1] + d[q][0]
			for j in range(len(w)):
				if w[j:j + 4] == u:
					c += 1
			c += d[p][2] + d[q][2]
			d[v] = [r, g, c, max(6, d[p][3] + d[q][3])]
	print(d[v][2])


import os
import sys
from io import BytesIO, IOBase

def solve(s):
	n = len(s)
	cnt = 0
	for i in range(n - 3):
		if s[i] == 'h' and s[i + 1] == 'a' and (s[i + 2] == 'h') and (s[i + 3] == 'a'):
			cnt += 1
	return cnt

class string:
	count = 0
	pre = str()
	post = str()

def main():
	for _ in range(int(input())):
		n = int(input())
		d = {}
		last = str()
		for _ in range(n):
			l = input().split()
			last = l[0]
			if len(l) == 3:
				z = string()
				z.count = solve(l[2])
				z.pre = l[2][:3]
				z.post = l[2][-3:]
				d[l[0]] = z
			else:
				(x, y) = (d[l[2]], d[l[4]])
				z = string()
				z.count = x.count + y.count + solve(x.post + y.pre)
				z.pre = (x.pre + y.pre)[:3]
				z.post = (x.post + y.post)[-3:]
				d[l[0]] = z
		print(d[last].count)
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 im():
	return map(int, input().split())

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

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

def ins():
	return input()[:-1]
import re
for _ in range(ii()):
	n = ii()
	dic = {}
	for _ in range(n):
		st = ins()
		lis = list(st.split(' '))
		if lis[1] == ':=':
			cnt = len(re.findall('(?=haha)', lis[2]))
			dic[lis[0]] = [lis[2][:3], lis[2][-3:], cnt]
		else:
			sf = dic[lis[2]][1]
			sl = dic[lis[4]][0]
			cnt = len(re.findall('(?=haha)', sf + sl))
			cnt += dic[lis[2]][2] + dic[lis[4]][2]
			dic[lis[0]] = [(dic[lis[2]][0] + dic[lis[4]][1])[:3], (dic[lis[2]][0] + dic[lis[4]][1])[-3:], cnt]
		last = lis[0]
	print(dic[last][2])


def fun(s):
	c = 0
	n = len(s)
	for i in range(n):
		if i + 3 < n and s[i] == 'h' and (s[i + 1] == 'a') and (s[i + 2] == 'h') and (s[i + 3] == 'a'):
			c += 1
	return c
from collections import defaultdict
for _ in range(int(input())):
	n = int(input())
	d1 = defaultdict(str)
	d2 = defaultdict(int)
	last = 0
	for i in range(n):
		p = input().split()
		if len(p) == 3:
			if len(p[2]) < 8:
				d1[p[0]] = p[2]
			else:
				d1[p[0]] = p[2][:4] + p[2][-4] + p[2][-3] + p[2][-2] + p[2][-1]
			d2[p[0]] = fun(p[2])
			last = d2[p[0]]
		else:
			k = 0
			if len(d1[p[2]]) >= 2 and len(d1[p[4]]) >= 2:
				if d1[p[2]][-2] + d1[p[2]][-1] + d1[p[4]][0] + d1[p[4]][1] == 'haha':
					k += 1
			if len(d1[p[2]]) >= 1 and len(d1[p[4]]) >= 3:
				if d1[p[2]][-1] + d1[p[4]][0] + d1[p[4]][1] + d1[p[4]][2] == 'haha':
					k += 1
			if len(d1[p[2]]) >= 3 and len(d1[p[4]]) >= 1:
				if d1[p[2]][-3] + d1[p[2]][-2] + d1[p[2]][-1] + d1[p[4]][0] == 'haha':
					k += 1
			hehe = d1[p[2]] + d1[p[4]]
			if len(hehe) < 8:
				d1[p[0]] = hehe
			else:
				d1[p[0]] = hehe[:4] + hehe[-4] + hehe[-3] + hehe[-2] + hehe[-1]
			d2[p[0]] = d2[p[2]] + d2[p[4]] + k
			last = d2[p[0]]
	print(last)


def solve(N, equ):
	tot = 0
	count_haha = {}
	for eq in equ:
		if ':' in eq:
			(new_var, new_val) = eq.split(' := ')
			haha_count = 0
			if 'haha' in new_val:
				haha_count = 1
			(end, start) = get_start_end(new_val)
			count_haha[new_var] = (start, end, haha_count, new_val)
			last_var = new_var
		else:
			(chg_var, assig) = eq.split(' = ')
			(left_var, right_var) = assig.split(' + ')
			new_count = count_haha[left_var][2] + count_haha[right_var][2]
			leftend = count_haha[left_var][1]
			rightstart = count_haha[right_var][0]
			if leftend == 'hah' and rightstart == 'aha':
				new_count += 2
			if leftend == 'hah' and rightstart == 'a':
				new_count += 1
			elif leftend == 'ha' and rightstart == 'ha':
				new_count += 1
			elif leftend == 'h' and rightstart == 'aha':
				new_count += 1
			new_str = count_haha[left_var][3] + count_haha[right_var][3]
			if len(new_str) <= 8:
				(start, end) = get_start_end(new_str)
			else:
				(start, end) = (count_haha[left_var][0], count_haha[right_var][1])
				new_str = 'a' * 10
			count_haha[chg_var] = (start, end, new_count, new_str)
			last_var = chg_var
	return count_haha[last_var][2]

def get_start_end(new_val):
	if len(new_val) >= 3 and 'aha' == new_val[:3]:
		start = 'aha'
	elif len(new_val) >= 2 and 'ha' == new_val[:2]:
		start = 'ha'
	elif len(new_val) >= 1 and 'a' == new_val[0]:
		start = 'a'
	else:
		start = ''
	if len(new_val) >= 3 and 'hah' == new_val[-3:]:
		end = 'hah'
	elif len(new_val) >= 2 and 'ha' == new_val[-2:]:
		end = 'ha'
	elif len(new_val) >= 1 and 'h' == new_val[-1]:
		end = 'h'
	else:
		end = ''
	return (end, start)
import io
import os
import math
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
T = int(input().decode().strip())
for t in range(T):
	N = int(input().decode().strip())
	equ = []
	for i in range(N):
		equ.append(input().decode().strip())
	res = solve(N, equ)
	print(res)


def solve():
	t = int(input())
	values = dict()
	name = ''
	for _ in range(t):
		cur_string = input()
		if ':=' in cur_string:
			(name, value) = cur_string.split(' := ')
			end = value[-3:]
			begin = value[:3]
			haha_counter = int('haha' in value)
			values[name] = dict(end=end, begin=begin, haha=haha_counter)
		else:
			(name, second_part) = cur_string.split(' = ')
			(first, second) = second_part.split(' + ')
			common_part = values[first]['end'] + values[second]['begin']
			haha_dop = 0
			for item in range(len(common_part) - 3):
				haha_dop += int(common_part[item:item + 4] == 'haha')
			if values[first]['begin'].__len__() < 3:
				values[first]['begin'] += values[second]['begin']
			if values[second]['end'].__len__() < 3:
				values[second]['end'] += values[first]['end']
			values[first]['begin'] = values[first]['begin'][:3]
			values[second]['end'] = values[second]['end'][-3:]
			values[name] = dict(end=values[second]['end'], begin=values[first]['begin'], haha=values[first]['haha'] + values[second]['haha'] + haha_dop)
	print(values[name]['haha'])
for _ in range(int(input())):
	solve()


def cnt(a):
	n = len(a)
	ret = 0
	for i in range(0, n - 3):
		if str(a[i:i + 4]) == 'haha':
			ret += 1
	return ret

def extEND(a):
	mn = min(3, len(a))
	n = len(a)
	return str(a[n - mn:n])

def extBEG(a):
	mn = min(3, len(a))
	return str(a[0:mn])
t = int(input())
while t > 0:
	t -= 1
	c = int(input())
	mp = {}
	last = ''
	for i in range(1, c + 1):
		p = input().split(' ')
		if p[1] == ':=':
			mp[p[0]] = (cnt(p[2]), extBEG(p[2]), extEND(p[2]))
		else:
			mp[p[0]] = (mp[p[2]][0] + mp[p[4]][0] + cnt(mp[p[2]][2] + mp[p[4]][1]), extBEG(mp[p[2]][1] + mp[p[4]][1]), extEND(mp[p[2]][2] + mp[p[4]][2]))
	last = p[0]
	print(mp[last][0])


class S:

	def __init__(self, n, f, l):
		self.n = n
		self.f = f
		self.l = l

	def __add__(self, other):
		return S(self.n + other.n + int('haha' in self.l + other.f) + int(self.l + other.f == 'hahaha'), (self.f + other.f)[:3], (self.l + other.l)[-3:])
for _ in range(int(input())):
	d = {}
	for _ in range(int(input())):
		l = input().split()
		if ':=' in l:
			d[l[0]] = S(int('haha' in l[2]), l[2][:3], l[2][-3:])
		else:
			d[l[0]] = d[l[2]] + d[l[4]]
	print(d[l[0]].n)


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

def find(x):
	cnt = 0
	for i in range(len(x) - 3):
		if x[i] == 'h' and x[i + 1] == 'a' and (x[i + 2] == 'h') and (x[i + 3] == 'a'):
			cnt += 1
	return cnt

def merge(x, y):
	c = find(x[1] + y[0])
	return ((x[0] + y[0])[:3], (x[1] + y[1])[-3:], x[2] + y[2] + c)

def f(q):
	dct = defaultdict(str)
	mp = {}
	for l in q:
		if l[1] == ':=':
			v = l[2]
			mp[l[0]] = (v[:3], v[-3:], v.count('haha'))
		else:
			mp[l[0]] = merge(mp[l[2]], mp[l[4]])
	return mp[q[-1][0]][2]
for _ in range(int(input())):
	q = []
	for i in range(int(input())):
		lst = list(map(str, input().strip().split()))
		q.append(lst)
	print(f(q))


def haha(s):
	cnt = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			cnt += 1
	return cnt

def solve():
	vars = dict()
	for _ in range(int(input())):
		s = input().split()
		if s[1] == ':=':
			vars[s[0]] = (haha(s[2]), s[2][:3], s[2][-3:])
		else:
			vars[s[0]] = (vars[s[2]][0] + vars[s[4]][0] + haha(vars[s[2]][2] + vars[s[4]][1]), (vars[s[2]][1] + vars[s[4]][1])[:3], (vars[s[2]][2] + vars[s[4]][2])[-3:])
	print(vars[s[0]][0])
for _ in range(int(input())):
	solve()


T = int(input())
t = 1
while t <= T:
	n = int(input())
	dic = {}
	hahanum = {}
	for i in range(n):
		s = input()
		s = s.split(' ')
		newv = s[0]
		if len(s) == 3:
			dic[newv] = [s[2], s[2]]
			if 'haha' in s[2]:
				hahanum[newv] = 1
			else:
				hahanum[newv] = 0
		elif len(s) == 5:
			fronts = dic[s[2]]
			rears = dic[s[4]]
			if len(fronts[0]) >= 5 and len(rears[1]) >= 5:
				newfront = fronts[0]
				newrear = rears[1]
			elif len(fronts[0]) < 5 and len(rears[1]) < 5:
				news = fronts[0] + rears[1]
				newfront = news[:5]
				newrear = news[-5:]
			elif len(fronts[0]) == 5 and len(rears[1]) < 5:
				newfront = fronts[0]
				newrear = fronts[1][-(5 - len(rears[1])):] + rears[1]
			elif len(fronts[0]) < 5 and len(rears[1]) == 5:
				newrear = rears[1]
				newfront = fronts[0] + rears[0][:5 - len(fronts[0])]
			base = 0
			for i in [1, 2, 3]:
				if fronts[1][-i:] + rears[0][:4 - i] == 'haha':
					base += 1
			base += hahanum[s[2]]
			base += hahanum[s[4]]
			dic[newv] = [newfront, newrear]
			hahanum[newv] = base
	print(hahanum[newv])
	t += 1


import sys
from collections import deque

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

def rl_types(types):
	str_list = [x for x in sys.stdin.readline().strip().split(' ')]
	return [types[i](str_list[i]) for i in range(len(str_list))]

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

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

def solve(array):
	return array

class Haha:

	def __init__(self, s):
		self._str = s
		self._len = len(s)
		self._nocc = 0
		if len(s) >= 4:
			for i in range(len(s) - 3):
				self._nocc += 1 if s[i:i + 4] == 'haha' else 0
			self._front = s[:4]
			self._back = s[len(s) - 4:]

	def join(self, other):
		(l1, l2) = (self._len, other._len)
		if l1 < 4 and l2 < 4:
			return Haha(self._str + other._str)
		elif l1 >= 4 and l2 >= 4:
			newH = Haha('')
			newH._front = self._front
			newH._back = other._back
			newH._nocc = self._nocc + other._nocc
			newH._len = self._len + other._len
			(s1, s2) = (self._back, other._front)
			if s1[-3:] + s2[0] == 'haha':
				newH._nocc += 1
			if s1[-2:] + s2[:2] == 'haha':
				newH._nocc += 1
			if s1[-1] + s2[:3] == 'haha':
				newH._nocc += 1
		elif l1 >= 4:
			newH = Haha('')
			newH._front = self._front
			(s1, s2) = (self._back, other._str)
			t = s1 + s2
			newH._back = t[-4:]
			newH._nocc = self._nocc + other._nocc
			newH._len = self._len + other._len
			if len(s2) > 2 and s1[-1] + s2 == 'haha':
				newH._nocc += 1
			if len(s2) > 1 and s1[-2:] + s2[:2] == 'haha':
				newH._nocc += 1
			if s1[-3:] + s2[0] == 'haha':
				newH._nocc += 1
		else:
			newH = Haha('')
			(s1, s2) = (self._str, other._front)
			t = s1 + s2
			newH._front = t[:4]
			newH._back = other._back
			newH._nocc = self._nocc + other._nocc
			newH._len = self._len + other._len
			if len(s1) > 2 and s1 + s2[0] == 'haha':
				newH._nocc += 1
			if len(s1) > 1 and s1[-2:] + s2[:2] == 'haha':
				newH._nocc += 1
			if s1[-1] + s2[:3] == 'haha':
				newH._nocc += 1
		return newH

	def __repr__(self):
		if self._len < 4:
			return f'[{self._str},{self._nocc}]'
		else:
			return f'[{self._front}...{self._back},{self._nocc}]'
NT = int(rl())
for ti in range(NT):
	nlines = int(rl())
	varlist = {}
	last_var = None
	for _ in range(nlines):
		parts = rl().split(' ')
		var = parts[0]
		val1 = parts[2]
		if parts[1][0] == ':':
			varlist[var] = Haha(val1)
		else:
			val2 = parts[4]
			varlist[var] = varlist[val1].join(varlist[val2])
		last_var = var
	nocc = 0
	tocheck = varlist[last_var]
	nocc = tocheck._nocc
	pr(nocc)


t = int(input())

def add(a, b):
	ans1 = a[0] + b[0]
	p = a[1][1]
	q = b[1][0]
	t = p + q
	total = 0
	for i in range(len(t)):
		if t[i:i + 4] == 'haha':
			ans1 += 1
	ans2 = ((a[1][0] + b[1][0])[:3], (a[1][1] + b[1][1])[-3:])
	return (ans1, ans2)
for _ in range(t):
	n = int(input())
	d = dict()
	ans = 0
	for i in range(n):
		line = input()
		if ':=' in line:
			s = line.split(' := ')
			a = int('haha' in s[1])
			d[s[0]] = (a, (s[1][:3], s[1][-3:]))
			ans = d[s[0]][0]
		else:
			(x, p0, y, p1, z) = line.split()
			d[x] = add(d[y], d[z])
			ans = d[x][0]
	print(ans)


t = int(input())
for testcase in range(t):
	n = int(input())
	num_haha = {}
	variable = {}
	last_var = ''
	for i in range(n):
		command = input()
		parsed = command.split()
		var = parsed[0]
		last_var = var
		op = parsed[1]
		if op == ':=':
			val = parsed[2]
			variable[var] = val
			x = 0
			for j in range(max(len(val) - 3, 0)):
				if val[j:j + 4] == 'haha':
					x = x + 1
			num_haha[var] = x
		else:
			a = parsed[2]
			b = parsed[4]
			A = variable[a]
			B = variable[b]
			variable[var] = A + B
			if len(variable[var]) > 8:
				variable[var] = variable[var][:4] + variable[var][-4:]
			num_haha[var] = num_haha[a] + num_haha[b]
			j = 4
			for j in range(max(1, 4 - len(B)), min(3, len(A)) + 1):
				if A[-j:] + B[:4 - j] == 'haha':
					num_haha[var] += 1
	print(num_haha[last_var])


i = input
t = int(i())
while t:
	t -= 1
	p = {}
	n = int(i())
	while n:
		n -= 1
		s = i()
		a = s.split()[::2]
		if ':' in s:
			(k, v) = a
			p[k] = (v[:3], v[-3:], v.count('haha'))
		else:
			(k, x, y) = a
			(a, b, c) = p[x]
			(d, e, f) = p[y]
			g = b + d
			p[k] = ((a + d)[:3], (b + e)[-3:], c + f + sum((g[i:i + 4] == 'ha' * 2 for i in range(len(g)))))
	print(p[k][2])


class word:

	def __init__(self, len=None, cnt=None, s=None):
		self.len = len
		self.cnt = cnt
		self.s = s

def count(s: str):
	cnt = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			cnt += 1
	return cnt

def merge(a: word, b: word):
	c = word()
	c.len = a.len + b.len
	c.s = a.s + b.s
	c.cnt = a.cnt + b.cnt + count(a.s[-3:] + b.s[:3])
	if len(c.s) >= 7:
		c.s = c.s[:3] + '@' + c.s[-3:]
	return c
for _ in range(int(input())):
	n = int(input())
	vrs = {}
	ans = 0
	for i in range(n):
		tmp = input().split()
		if len(tmp) == 3:
			w = word(len(tmp[2]), count(tmp[2]), tmp[2])
			vrs[tmp[0]] = w
		else:
			vrs[tmp[0]] = merge(vrs[tmp[2]], vrs[tmp[4]])
		ans = vrs[tmp[0]].cnt
	print(ans)


from sys import stdin, stdout, setrecursionlimit
input = stdin.readline
inf = float('inf')
from functools import cmp_to_key
from collections import defaultdict as dd
from collections import Counter, deque
from heapq import *
import math
from math import floor, ceil, sqrt

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

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

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

def getls():
	return list(map(str, input().strip().split()))

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

def geta():
	return int(input())

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

def solve():
	for _ in range(geta()):
		n = geta()
		count = dd(int)
		value = dd(int)
		for steps in range(n):
			s = gets()
			if ':' in s:
				now = list(s.split(' '))
				char = now[0]
				val = now[-1]
				temp = 0
				for i in range(len(val)):
					if val[i:i + 4] == 'haha':
						temp += 1
				count[char] = temp
				value[char] = val
				if steps == n - 1:
					print(temp)
			else:
				now = list(s.split(' '))
				char = now[0]
				a = now[-3]
				b = now[-1]
				count[char] = count[a] + count[b]
				a = value[a]
				b = value[b]
				if a[-1:] + b[:3] == 'haha':
					count[char] += 1
				if a[-2:] + b[:2] == 'haha':
					count[char] += 1
				if a[-3:] + b[:1] == 'haha':
					count[char] += 1
				c = a + b
				if len(c) > 10:
					c = c[:4] + c[-4:]
				value[char] = c
				if steps == n - 1:
					print(count[char])
solve()


from collections import namedtuple
Haha = namedtuple('Haha', ['haha', 'prefix', 'suffix'])

def build(s):
	return Haha(sum((s[i:i + 4] == 'haha' for i in range(len(s) - 3))), s[:3], s[-3:])

def merge(a: Haha, b: Haha):
	return Haha(a.haha + b.haha + sum((a.suffix[-i:] + b.prefix[:4 - i] == 'haha' for i in range(1, 4))), (a.prefix + b.prefix)[:3], (a.suffix + b.suffix)[-3:])
t = int(input())
for _ in range(t):
	n = int(input())
	mem = {}
	for _ in range(n):
		tokens = input().split()
		if len(tokens) == 3:
			mem[tokens[0]] = build(tokens[2])
		else:
			mem[tokens[0]] = merge(mem[tokens[2]], mem[tokens[4]])
	print(mem[tokens[0]].haha)


t = int(input())
for _ in range(t):
	n = int(input())
	haha = {}
	st = {}
	end = {}
	for rr in range(n):
		s = input()
		z = 1
		for i in s:
			if i == '+':
				z = 2
				break
		if z == 1:
			s = s.split()
			cnt = 0
			for i in range(len(s[2]) - 3):
				tmp = ''
				tmp += s[2][i]
				tmp += s[2][i + 1]
				tmp += s[2][i + 2]
				tmp += s[2][i + 3]
				if tmp == 'haha':
					cnt += 1
			haha[s[0]] = cnt
			st[s[0]] = s[2][0:3]
			end[s[0]] = s[2][-3:-1] + s[2][-1]
			if rr == n - 1:
				print(cnt)
		else:
			s = s.split()
			c = s[0]
			a = s[2]
			b = s[4]
			cnt = haha[a] + haha[b]
			for i in range(1, 4):
				tmp = end[a][-i:-1] + end[a][-1] + st[b][0:4 - i]
				if tmp == 'haha':
					cnt += 1
			haha[s[0]] = cnt
			if len(st[a]) >= 3:
				st[c] = st[a][0:3]
			else:
				st[c] = st[a] + st[b][0:3 - len(st[a])]
			if len(end[b]) >= 3:
				end[c] = end[b][-3:-1] + end[b][-1]
			else:
				end[c] = end[a][-(4 - len(end[b])):-1] + end[a][-1] + end[b]
			if rr == n - 1:
				print(cnt)


from bisect import bisect_left as bl
from bisect import bisect_right as br
from heapq import heappush, heappop
import math
from collections import *
from functools import reduce, cmp_to_key, lru_cache
from itertools import accumulate, permutations
import sys
input = sys.stdin.readline
M = mod = 10 ** 9 + 7

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').split()]

def li3():
	return [int(i) for i in input().rstrip('\n')]
for _ in range(val()):
	n = val()
	d = defaultdict(list)
	last = ''
	for i in range(n):
		s = li2()
		if '+' not in s:
			mystring = s[2]
			last = s[0]
			d[last] = [mystring[:4], mystring.count('haha'), mystring[-4:]]
		else:
			first = s[0]
			second = s[2]
			third = s[4]
			curr = [0, 0, 0]
			currstring = d[second][0] + d[third][2]
			curr[0] = currstring[:4]
			curr[-1] = currstring[-4:]
			curr[1] = d[second][1] + d[third][1]
			if d[second][2][-1:] == 'h' and d[third][0][:3] == 'aha':
				curr[1] += 1
			if d[second][2][-2:] == 'ha' and d[third][0][:2] == 'ha':
				curr[1] += 1
			if d[second][2][-3:] == 'hah' and d[third][0][:1] == 'a':
				curr[1] += 1
			d[first] = curr[:]
			last = s[0]
	print(d[last][1])


def count(s):
	val = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			val += 1
	return val
t = int(input())
for i in range(t):
	n = int(input())
	dic = {}
	ans = {}
	for j in range(n):
		cmd = input()
		if ':=' in cmd:
			(var, inp) = cmd.split(' := ')
			var = var.strip()
			inp = inp.strip()
			dic[var] = inp
			ans[var] = 0
		else:
			(var, inp) = cmd.split(' = ')
			var = var.strip()
			(var1, var2) = inp.split(' + ')
			var1 = var1.strip()
			var2 = var2.strip()
			fs = dic[var1] + dic[var2]
			if len(fs) > 6:
				ans[var] = ans.get(var1, 0) + ans.get(var2, 0) + count(fs)
				fs = fs[0:3] + '-' + fs[-3:]
			dic[var] = fs
		if j == n - 1:
			if '-' in dic[var]:
				print(ans.get(var, 0))
			else:
				print(count(dic[var]))


import sys
input = sys.stdin.readline
for _ in range(int(input())):
	n = int(input())
	dic = {}
	for _ in range(n):
		s = input().split()
		if s[1] == ':=':
			cnt = 0
			for i in range(len(s[2]) - 3):
				if s[2][i:i + 4] == 'haha':
					cnt += 1
			dic[s[0]] = (cnt, s[2])
		else:
			(x, y) = (s[2], s[4])
			cnt = dic[x][0] + dic[y][0]
			z = dic[x][1] + dic[y][1]
			for i in range(max(0, len(dic[x][1]) - 3), min(len(z) - 3, len(dic[x][1]))):
				if z[i:i + 4] == 'haha':
					cnt += 1
			if len(z) >= 6:
				z = z[:3] + z[-3:]
			dic[s[0]] = (cnt, z)
	print(dic[s[0]][0])


import sys, io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
O = []
for _ in range(int(input())):
	n = int(input())
	d = {}
	for i in range(n):
		s = input().split()
		if len(s) == 3:
			(c, t) = (s[0], s[2])
			if len(t) <= 3:
				d[c] = (t, 0, t)
			else:
				w = 0
				for j in range(len(t) - 3):
					if t[j:j + 4] == b'haha':
						w = 1
				d[c] = (t[:3], w, t[-3:])
		else:
			(c, a, b) = (s[0], s[2], s[4])
			(pa, va, sa) = d[a]
			(pb, vb, sb) = d[b]
			t = sa + pb
			w = 0
			for j in range(len(t) - 3):
				if t[j:j + 4] == b'haha':
					w += 1
			if len(pa) < 3:
				pa = t[:3]
			if len(sb) < 3:
				sb = t[-3:]
			d[c] = (pa, va + w + vb, sb)
	O.append(str(d[c][1]))
print('\n'.join(O))


import re
t = int(input())
for test in range(t):
	n = int(input())
	variable = {}
	for statement in range(n):
		cmd = input().replace(' ', '')
		if ':=' in cmd:
			name = cmd.split(':=')[0]
			value = cmd.split(':=')[1]
			count = len(re.findall('(?=(haha))', value))
			variable[name] = (value, count)
		else:
			name = cmd.split('=')[0]
			R = cmd.split('=')[1]
			data1 = variable[R.split('+')[0]]
			data2 = variable[R.split('+')[1]]
			obj = data1[0] + data2[0]
			if len(obj) > 6:
				obj = obj[:3] + obj[-3:]
			variable[name] = (obj, data1[1] + data2[1] + len(re.findall('(?=(haha))', data1[0][-3:] + data2[0][:3])))
	print(variable[name][1])


class Word:

	def __init__(self, s):
		self.len = len(s)
		self.cnt = 0
		for j in range(self.len - 3):
			if s[j:j + 4] == 'haha':
				self.cnt += 1
		if self.len > 3:
			self.pref = s[:3]
			self.suff = s[len(s) - 3:]
		else:
			self.pref = s
			self.suff = s

def add(self, other):
	a = Word('')
	a.len = self.len + other.len
	a.cnt = self.cnt + other.cnt
	s = self.suff + other.pref
	for j in range(len(s) - 3):
		if s[j:j + 4] == 'haha':
			a.cnt += 1
	a.pref = self.pref + other.pref
	a.pref = a.pref[:min(3, len(a.pref))]
	a.suff = self.suff + other.suff
	a.suff = a.suff[max(len(a.suff) - 3, 0):]
	return a
t = int(input())
for _ in range(t):
	n = int(input())
	ans = 0
	d = dict()
	for i in range(n):
		g = input()
		func = g.split()
		if len(func) == 3:
			d[func[0]] = Word(func[2])
			ans = d[func[0]].cnt
		else:
			d[func[0]] = add(d[func[2]], d[func[4]])
			ans = d[func[0]].cnt
	print(ans)


import math
import re
import sys
from itertools import permutations
from collections import Counter
import itertools
MOD = 1000000007

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

def ninp():
	return int(input())

def haha(s):
	cnt = 0
	fir = -1
	for fir in iter(lambda : s.find('haha', fir + 1), -1):
		cnt += 1
	return cnt
for _ in range(ninp()):
	n = ninp()
	ans = dict()
	res = 0
	for _ in range(n):
		s = input().strip()
		if ':=' in s:
			(x, s) = s.split(' := ')
			res = haha(s)
			ans[x] = [res, s[:3], s[-3:]]
		else:
			(x, y) = s.split(' = ')
			(a, b) = y.split(' + ')
			res = ans[a][0] + ans[b][0] + haha(ans[a][-1] + ans[b][1])
			(aa, bb) = (ans[a][1], ans[b][-1])
			if len(ans[a][1]) != 3:
				aa = (ans[a][1] + ans[b][1])[:3]
			if len(ans[b][1]) != 3:
				bb = (ans[a][-1] + ans[b][1])[-3:]
			ans[x] = [res, aa, bb]
	print(res)


def count(s):
	cnt = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			cnt += 1
	return cnt

def merge(s1, s2):
	(prefix1, suffix1) = (s1[:3], s1[-3:])
	(prefix2, suffix2) = (s2[:3], s2[-3:])
	return (prefix1 + prefix2)[:3] + (suffix1 + suffix2)[-3:]
t = int(input())
for i in range(t):
	d = {}
	n = int(input())
	for j in range(n):
		line = input()
		tokens = line.split(' ')
		if tokens[1] == ':=':
			(k, _, v) = tokens
			d[k] = (v, v.count('haha'))
		elif tokens[1] == '=':
			(k, _, k1, _, k2) = tokens
			(s1, s2) = (d[k1][0], d[k2][0])
			d[k] = (merge(s1, s2), d[k1][1] + d[k2][1] + count(s1[-3:] + s2[:3]))
		else:
			print(tokens)
			raise NotImplementedError
	print(d[k][1])


from collections import OrderedDict

def find(s: str) -> int:
	cnt = 0
	for i in range(len(s)):
		if i + 3 >= len(s):
			break
		elif s[i:i + 4] == 'haha':
			cnt += 1
	return cnt

def find_duplicate(a: str, b: str) -> int:
	cnt = 0
	if a[-1] + b[:3] == 'haha':
		cnt += 1
	if a[-2:] + b[:2] == 'haha':
		cnt += 1
	if a[-3:] + b[:1] == 'haha':
		cnt += 1
	return cnt

def solve():
	n = int(input())
	dict = OrderedDict()
	for _ in range(n):
		s = input()
		s = s.split(' ')
		if s[1][0] == ':':
			dict[s[0]] = [s[2][:4], s[2][max(len(s[2]) - 4, 0):], find(s[2])]
		else:
			a = dict[s[2]][0]
			b = dict[s[2]][1]
			c = dict[s[4]][0]
			d = dict[s[4]][1]
			if len(a) < 4 or len(d) < 4:
				here = b + c
				dict[s[0]] = [here[:4], here[max(len(here) - 4, 0):], find_duplicate(b, c) + dict[s[2]][2] + dict[s[4]][2]]
			else:
				dict[s[0]] = [a, d, find_duplicate(b, c) + dict[s[2]][2] + dict[s[4]][2]]
		item = dict[s[0]][-1]
	print(item)
t = int(input())
for _ in range(t):
	solve()


res = {}
cur_str = {}

def FindOccurrence(value):
	l = len(value)
	if l < 4:
		return 0
	freq = 0
	for i in range(l - 3):
		if value[i:i + 4] == 'haha':
			freq += 1
	return freq

def Truncate(value):
	l = len(value)
	if l <= 10:
		return value
	else:
		return value[0:3] + '****' + value[-3:l]

def Init(var, value):
	res[var] = FindOccurrence(value)
	cur_str[var] = Truncate(value)

def Update(var1, var2, var3):
	res[var1] = res[var2] + res[var3]
	tot_str = ''
	if len(cur_str[var2]) < 4:
		tot_str += cur_str[var2]
	else:
		tot_str += cur_str[var2][-3:len(cur_str[var2])]
	if len(cur_str[var3]) < 4:
		tot_str += cur_str[var3]
	else:
		tot_str += cur_str[var3][0:3]
	res[var1] += FindOccurrence(tot_str)
	cur_str[var1] = Truncate(cur_str[var2] + cur_str[var3])

def Solve():
	res.clear()
	cur_str.clear()
	n = int(input())
	cur_res = 0
	for _ in range(n):
		eq = input().split()
		if len(eq) == 3:
			Init(eq[0], eq[2])
		else:
			Update(eq[0], eq[2], eq[4])
		cur_res = res[eq[0]]
	print(cur_res)
t = int(input())
for _ in range(t):
	Solve()


t = int(input())

class var:

	def __init__(self):
		self.len = 0
		self.count = 0
		self.pref = ''
		self.suff = ''

def count_haha(string: str):
	lent = len(string)
	if lent < 4:
		return 0
	total = 0
	for (i, char) in enumerate(string):
		if char == 'h':
			if i + 1 < lent and string[i + 1] == 'a':
				if i + 2 < lent and string[i + 2] == 'h':
					if i + 3 < lent and string[i + 3] == 'a':
						total += 1
	return total
index = 0
while index < t:
	n = int(input())
	varbs = dict()
	last_var = 0
	for stmt in range(n):
		string = input()
		string = string.split()
		var_name = string[0]
		inst = var()
		if string[1] == ':=':
			val = str(string[2])
			inst.pref = val[0:3]
			inst.suff = val[-3:]
			inst.len = len(val)
			inst.count = count_haha(val)
		else:
			l1 = varbs.get(string[2], None)
			l2 = varbs.get(string[4], None)
			if l1.len < 3:
				inst.pref = (l1.pref + l2.pref)[0:3]
			else:
				inst.pref = l1.pref
			if l2.len < 3:
				inst.suff = (l1.suff + l2.suff)[-3:]
			else:
				inst.suff = l2.suff
			inst.len = l1.len + l2.len
			inst.count = l1.count + l2.count + count_haha(l1.suff + l2.pref)
		varbs[var_name] = inst
		if stmt == n - 1:
			last_var = var_name
	print(varbs[last_var].count)
	index += 1


def count_hahas(s):
	count = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			count += 1
	return count
t = int(input())
for _ in range(t):
	vars = dict()
	for _ in range(int(input())):
		line = input()
		if ':' in line:
			line = line.split()
			(v, s) = (line[0], line[2])
			vars[v] = [count_hahas(s), s[0:min(len(s), 3)], s[max(len(s) - 3, 0):]]
		else:
			line = line.split()
			(v, a, b) = (line[0], vars[line[2]], vars[line[4]])
			count = a[0] + b[0]
			con = a[2] + b[1]
			count += count_hahas(con)
			start = a[1] + b[1]
			end = a[2] + b[2]
			vars[v] = [count, start[0:min(len(start), 3)], end[max(len(end) - 3, 0):]]
	print(vars[v][0])


from collections import defaultdict, deque, Counter
from sys import stdin, stdout
from heapq import heappush, heappop
import math
import io
import os
import math
import bisect

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

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

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

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

def 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
	return prime

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

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

def mapin():
	return map(str, input().split())

def a1(n):
	s = str(n)
	ans = 0
	ll = len(s)
	for i in range(len(s)):
		ans += int(s[0:ll])
		ll -= 1
	return ans
t = int(input())
yn = ['NO', 'YES']
d = {}
for _ in range(t):
	n = int(input())
	a = ''
	for j in range(n):
		a = input()
		if ':' in a:
			dd = [0, 0, 0]
			a = a.split(' := ')
			dd[0] = a[1][0:3]
			dd[-1] = a[1][-3:]
			for i in range(0, len(a[1]) - 3):
				if a[1][i] == 'h' and a[1][i + 1] == 'a' and (a[1][i + 2] == 'h') and (a[1][i + 3] == 'a'):
					dd[1] += 1
			d[a[0]] = dd
		else:
			a = a.split(' = ')
			b = a[1].split(' + ')
			ccc = d[b[0]]
			ddd = d[b[1]]
			eee = [0, 0, 0]
			eee[1] = ccc[1] + ddd[1]
			ss = ccc[-1] + ddd[0]
			for i in range(0, len(ss) - 3):
				if ss[i] == 'h' and ss[i + 1] == 'a' and (ss[i + 2] == 'h') and (ss[i + 3] == 'a'):
					eee[1] += 1
			eee[0] = ccc[0]
			if len(eee[0]) < 3:
				eee[0] += ddd[0]
			eee[0] = eee[0][0:3]
			eee[-1] = ddd[-1]
			if len(ddd[-1]) < 3:
				eee[-1] = ccc[-1] + ddd[-1]
			eee[-1] = eee[-1][-3:]
			d[a[0]] = eee
	print(d[a[0]][1])


from sys import stdin, stdout, setrecursionlimit as srl
from threading import stack_size
from collections import deque, defaultdict as dd
from math import gcd, ceil
input = stdin.readline
flush = stdout.flush

def ub(arr, lo, hi, val):
	glo = lo
	ghi = hi
	while lo < hi:
		mid = (lo + hi) // 2
		if arr[mid] > val:
			hi = mid - 1
		elif arr[mid] <= val:
			lo = mid + 1
	if lo == ghi and arr[ghi] <= val:
		lo = ghi + 1
	return lo

def lb(arr, lo, hi, val):
	glo = lo
	ghi = hi
	while lo < hi:
		mid = (lo + hi) // 2
		if arr[mid] < val:
			lo = mid + 1
		elif arr[mid] > val:
			hi = mid - 1
		else:
			hi = mid
	while arr[lo] < val:
		lo += 1
	return lo

def f(a):
	if len(a) < 4:
		return 0
	ans = 0
	for i in range(len(a)):
		if a[i:i + 4] == 'haha':
			ans += 1
	return ans
tc = 1
tc = int(input())
for _ in range(tc):
	n = int(input())
	ans = 0
	d = {}
	for i in range(n):
		x = input()[:-1]
		try:
			(a, b) = x.split(' := ')
			d[a] = (b[:min(len(b), 3)], b[len(b) - min(3, len(b)):], f(b))
			ans = d[a][2]
		except:
			(c, s) = x.split(' = ')
			(a, b) = s.split(' + ')
			d[c] = (d[a][0] + d[b][0][:max(0, 3 - len(d[a][0]))], d[a][1][max(0, len(d[a][1]) - (3 - len(d[b][1]))):] + d[b][1], d[a][2] + d[b][2] + f(d[a][1] + d[b][0]))
			ans = d[c][2]
	print(ans)


def count(s):
	return len([pos for pos in range(len(s)) if pos + 3 < len(s) and s[pos:pos + 4] == 'haha'])

def plus(a, b):
	return (a[0] + b[0] + count(a[2] + b[1]), (a[1] + b[1])[:3], (a[2] + b[2])[-3:])
TC = int(input())
for _ in range(TC):
	n = int(input())
	map_var = dict()
	for _ in range(n):
		s = input().split()
		z = s[0]
		a = s[2]
		if s[1] == ':=':
			map_var[z] = (count(a), a[:3], a[-3:])
		else:
			b = s[4]
			map_var[z] = plus(map_var[a], map_var[b])
	print(map_var[s[0]][0])


import copy
t = int(input())

def count(s, pat):
	count = 0
	pos = 0
	while pos > -1:
		pos = s.find(pat, pos)
		if pos > -1:
			count += 1
			pos += 1
	return count

class StringData:

	def __init__(self):
		self.len = 0
		self.first_three_char = ''
		self.last_three_char = ''
		self.haha_count = 0

	def set(self, s):
		self.haha_count = count(s, 'haha')
		self.len = len(s)
		self.first_three_char = s[:3]
		self.last_three_char = s[-3:]

	def append(self, sd):
		middle_part = self.last_three_char + sd.first_three_char
		self.haha_count += count(middle_part, 'haha')
		if self.len < 3:
			self.first_three_char += sd.first_three_char
			self.first_three_char = self.first_three_char[:3]
		if len(sd.last_three_char) < 3:
			self.last_three_char += sd.last_three_char
			self.last_three_char = self.last_three_char[-3:]
		else:
			self.last_three_char = sd.last_three_char
		self.haha_count += sd.haha_count
		self.len += sd.len
for idx in range(t):
	n = int(input())
	string_datas = {}
	last_haha_count = 0
	lines = []
	for i in range(n):
		l = input()
		lines.append(l)
		if l.count(':'):
			(var, _, value) = l.split()
			string_datas[var] = StringData()
			string_datas[var].set(value)
			last_haha_count = string_datas[var].haha_count
		else:
			(var, _, var1, _, var2) = l.split()
			var1_copy = copy.deepcopy(string_datas[var1])
			var1_copy.append(string_datas[var2])
			string_datas[var] = var1_copy
			last_haha_count = string_datas[var].haha_count
	print(last_haha_count)


def count(s):
	return sum((1 for i in range(len(s) - 3) if s[i:i + 4] == 'haha'))

def compress(s):
	cnt = count(s)
	a = s[:3]
	b = s[-3:]
	return (cnt, a, b)

def combine(x, y):
	(cnt0, a0, b0) = x
	(cnt1, a1, b1) = y
	cnt = cnt0 + cnt1
	a = (a0 + a1)[:3]
	b = (b0 + b1)[-3:]
	cnt += count(b0 + a1)
	return (cnt, a, b)

def solve():
	n = int(input())
	mp = {}
	for _ in range(n):
		u = input().replace(':=', ' ').replace('=', ' ').replace('+', ' ').split()
		if len(u) == 2:
			mp[u[0]] = compress(u[1])
		else:
			mp[u[0]] = combine(mp[u[1]], mp[u[2]])
	return mp[u[0]][0]
for _ in range(int(input())):
	print(solve())


import sys
input = lambda : sys.stdin.readline().rstrip()

def gg(s):
	ans = 0
	for i in range(len(s)):
		if s[i] == 'h' and i + 3 < len(s):
			if s[i + 1] == 'a' and s[i + 2] == 'h' and (s[i + 3] == 'a'):
				ans += 1
	return ans

def get(s):
	if len(s) < 4:
		return [s]
	return [s[:3], s[-3:], gg(s)]

def merge(x, y):
	if len(x) == 1 and len(y) == 1:
		return get(x[0] + y[0])
	if len(x) == 1 and len(y) == 3:
		ss = x[0] + y[0]
		s = ss[:3]
		return [s, y[1], y[2] + gg(ss)]
	if len(x) == 3 and len(y) == 1:
		ss = x[1] + y[0]
		s = ss[-3:]
		return [x[0], s, x[2] + gg(ss)]
	return [x[0], y[1], x[2] + y[2] + gg(x[1] + y[0])]
for _ in range(int(input())):
	n = int(input())
	d = dict()
	last = ''
	for ii in range(n):
		a = input().split()
		if a[1] == ':=':
			d[a[0]] = get(a[2])
			last = a[0]
		else:
			d[a[0]] = merge(d[a[2]], d[a[4]])
			last = a[0]
	if len(d[last]) == 1:
		print(0)
	else:
		print(d[last][2])


import re

def merge(x, y):
	c = len(re.findall('(?=haha)', x[1] + y[0]))
	return ((x[0] + y[0])[:3], (x[1] + y[1])[-3:], x[2] + y[2] + c)
i = input
for _ in [1] * int(i()):
	mp = {}
	for _ in [1] * int(i()):
		s = i()
		if ':=' in s:
			(k, _, v) = s.split()
			mp[k] = (v[:3], v[-3:], v.count('haha'))
		else:
			(k, _, x, _, y) = s.split()
			mp[k] = merge(mp[x], mp[y])
	print(mp[k][2])


import sys
IS_INTERACTIVE = False
input = input
if not IS_INTERACTIVE:
	(*data,) = sys.stdin.read().split('\n')[::-1]

	def input():
		return data.pop()

def fprint(*args, **kwargs):
	print(*args, **kwargs, flush=True)

def eprint(*args, **kwargs):
	print(*args, **kwargs, file=sys.stderr)
HAHA = 'haha'
for _ in range(int(input())):
	n = int(input())
	ctx = {}
	counts = {}
	cnt = 0
	for _ in range(n):
		s = input().split()
		if ':=' in s:
			ctx[s[0]] = s[-1]
			cnt = counts[s[0]] = int(HAHA in s[-1])
		else:
			key = s[0]
			left = ctx[s[-3]]
			right = ctx[s[-1]]
			cnt = counts[s[-1]] + counts[s[-3]]
			for i in range(1, len(HAHA)):
				if left.endswith(HAHA[0:i]) and right.startswith(HAHA[i:]):
					cnt += 1
			res = ctx[s[-3]] + ctx[s[-1]]
			if len(res) > 6:
				res = res[:3] + res[-3:]
			ctx[key] = res
			counts[key] = cnt
	print(cnt)


t = int(input())
while t > 0:
	n = int(input())
	mp = {}
	mp1 = {}
	mp2 = {}
	prev = None
	cnt = 0
	for i in range(n):
		s = input().split(' ')
		if ':=' in s:
			if 'haha' in s[2]:
				mp[s[0]] = 1
			else:
				mp[s[0]] = 0
			if len(s[2]) >= 3:
				mp1[s[0]] = s[2][-3:]
				mp2[s[0]] = s[2][0:3]
			else:
				mp1[s[0]] = s[2]
				mp2[s[0]] = s[2]
		if '+' in s:
			mp[s[0]] = mp[s[2]] + mp[s[4]]
			x = max(-3, -len(mp1[s[2]]))
			y = min(3, len(mp2[s[4]]))
			ss = mp1[s[2]][x:] + mp2[s[4]][0:y]
			if 'haha' in ss:
				cc = 0
				for l in range(0, len(ss) - 3):
					if ss[l] == 'h' and ss[l + 1] == 'a' and (ss[l + 2] == 'h') and (ss[l + 3] == 'a'):
						cc += 1
				mp[s[0]] += cc
			if len(mp1[s[4]]) == 3:
				mp1[s[0]] = mp1[s[4]]
			elif len(mp1[s[4]]) == 2:
				mp1[s[0]] = mp1[s[2]][-1:] + mp1[s[4]]
			elif len(mp1[s[4]]) == 1:
				if len(mp1[s[2]]) >= 2:
					mp1[s[0]] = mp1[s[2]][-2:] + mp1[s[4]]
				else:
					mp1[s[0]] = mp1[s[2]] + mp1[s[4]]
			if len(mp2[s[2]]) == 3:
				mp2[s[0]] = mp2[s[2]]
			elif len(mp2[s[2]]) == 2:
				mp2[s[0]] = mp2[s[2]] + mp2[s[4]][0:1]
			elif len(mp2[s[2]]) == 1:
				if len(mp2[s[4]]) >= 2:
					mp2[s[0]] = mp2[s[2]] + mp2[s[4]][0:2]
				else:
					mp2[s[0]] = mp2[s[2]] + mp2[s[4]]
		prev = s[0]
	print(mp[s[0]])
	t -= 1


import sys
from sys import stdin

def cnthaha(s):
	ret = 0
	for i in range(len(s)):
		if s[i:i + 4] == 'haha':
			ret += 1
	return ret
tt = int(stdin.readline())
for loop in range(tt):
	n = int(stdin.readline())
	ndic = {}
	fi = {}
	la = {}
	for i in range(n):
		q = stdin.readline()[:-1]
		if ':' in q:
			(v, op, st) = q.split()
			ndic[v] = cnthaha(st)
			fi[v] = st[:3]
			la[v] = st[-1 * min(3, len(st)):]
		else:
			(v, op, l, plus, r) = q.split()
			newcnt = ndic[l] + ndic[r] + cnthaha(la[l] + fi[r])
			newfi = (fi[l] + fi[r])[:3]
			tmp = la[l] + la[r]
			newla = tmp[-1 * min(3, len(tmp)):]
			ndic[v] = newcnt
			fi[v] = newfi
			la[v] = newla
		if i == n - 1:
			print(ndic[v])


import time

def main():

	def cnt(s):
		ans = 0
		for i in range(3, len(s)):
			if s[i - 3] == 'h' and s[i - 2] == 'a' and (s[i - 1] == 'h') and (s[i] == 'a'):
				ans += 1
		return ans

	def concat(t1, t2):
		mid = t1[2] + t2[0]
		return (t1[0] if len(t1[0]) == 3 else mid[:3], t1[1] + t2[1] + cnt(mid), t2[2] if len(t2[2]) == 3 else mid[-3:])
	t = i_input()
	for tt in range(t):
		n = i_input()
		d = {}
		last = ''
		for nn in range(n):
			c = l_input()
			if c[1] == ':=':
				d[c[0]] = (c[2][:3], cnt(c[2]), c[2][-3:])
			else:
				d[c[0]] = concat(d[c[2]], d[c[4]])
			last = c[0]
		print(d[last][1])

def i_input():
	return int(input())

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

def li_input():
	return list(map(int, l_input()))

def il_input():
	return list(map(int, l_input()))
TT = time.time()
main()


import sys, re
input = lambda : sys.stdin.readline().rstrip('\r\n')
for _ in range(int(input())):
	n = int(input())
	d = {}
	for q in range(n):
		s = [x for x in input().split()]
		if s[1] == ':=':
			d[s[0]] = (s[2][:min(3, len(s[2]))], s[2][max(-3, -len(s[2])):], s[2].count('haha'))
			ans = d[s[0]][2]
		else:
			now = len(re.findall('(?=haha)', d[s[2]][1] + d[s[4]][0]))
			f = d[s[2]][0] + d[s[4]][0]
			se = d[s[2]][1] + d[s[4]][1]
			d[s[0]] = (f[:min(3, len(f))], se[max(-3, -len(se)):], now + d[s[2]][2] + d[s[4]][2])
			ans = d[s[0]][2]
	print(ans)


import os, sys
from io import BytesIO, IOBase

def coun(st):
	ans = 0
	for i in range(len(st) - 3):
		if st[i:i + 4] == 'haha':
			ans += 1
	return ans

def suff(st):
	s = 'haha'
	for i in range(3, 0, -1):
		if st[len(st) - i:] == s[:i]:
			return i
	return 0

def pref(st):
	s = 'haha'
	for i in range(3, 0, -1):
		if st[:i] == s[4 - i:]:
			return i
	return 0

def main():
	for _ in range(int(input())):
		n = int(input())
		dct = {}
		end = {}
		start = {}
		string = {}
		ls = -1
		for _ in range(n):
			op = input().strip()
			if ':=' in op:
				x = op.split(':=')
				tt = x[0].strip()
				ls = tt
				ls1 = x[1].strip()
				dct[tt] = coun(ls1)
				end[tt] = suff(ls1)
				start[tt] = pref(ls1)
				string[tt] = ls1
			else:
				x = op.split('=')
				y = x[1].split('+')
				(a, b) = (y[0].strip(), y[1].strip())
				ls = x[0].strip()
				(tt1, tt2) = (string.get(a), string.get(b))
				if tt1 and tt2 and (len(tt1) + len(tt2) <= 5):
					an = tt1 + tt2
					string[ls] = an
					start[ls] = pref(an)
					end[ls] = suff(an)
					dct[ls] = coun(an)
				else:
					dct[ls] = dct[a] + dct[b] + (end[a] + start[b] == 4) + 2 * (end[a] == 3 and start[b] == 3)
					start[ls] = start[a]
					end[ls] = end[b]
					string[ls] = 0
		print(dct[ls])
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
lines = sys.stdin.read().strip().split('\n')

def process(commands):
	state = dict()
	for command in commands:
		execute(command, state)
	target = commands[-1].strip().split()[0]
	return state[target][0]

def execute(command, state):
	tokens = command.strip().split()
	if len(tokens) == 3:
		val = tokens[2]
		state[tokens[0]] = (1 if 'haha' in val else 0, val[:3], val[-3:])
	else:
		(target, op1, op2) = (tokens[0], tokens[2], tokens[4])
		(count1, head1, tail1) = state[op1]
		(count2, head2, tail2) = state[op2]
		total = count1 + count2
		if tail1 == 'hah' and head2 == 'aha':
			total += 2
		elif 'haha' in tail1 + head2:
			total += 1
		if len(head1) < 3:
			head1 = (head1 + head2)[:3]
		if len(tail2) < 3:
			tail2 = (tail1 + tail2)[-3:]
		state[target] = (total, head1, tail2)
t = int(lines[0])
current = 1
for _ in range(t):
	n = int(lines[current])
	current += 1
	print(process(lines[current:current + n]))
	current += n


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

def solve(x):
	(n, su) = (len(x), 0)
	for i in range(n - 3):
		if x[i] == 'h' and x[i + 1] == 'a' and (x[i + 2] == 'h') and (x[i + 3] == 'a'):
			su += 1
	return su

def solve1(x):
	for i in range(len(x)):
		x[i] = x[i].strip()
	return x

def main():
	for _ in range(int(input())):
		n = int(input())
		b = Counter()
		for i in range(n):
			x = input().rstrip()
			if ':=' in x:
				x = solve1(x.split(':='))
				b[x[0]] = (x[1][:3], x[1][max(0, len(x[1]) - 3):], solve(x[1]))
			else:
				x = solve1(x.split('='))
				y = solve1(x[1].split('+'))
				(xx, yy) = (b[y[0]], b[y[1]])
				(lxx, lyy) = (len(xx[0]), len(yy[1]))
				if lxx + lyy > 5:
					b[x[0]] = (xx[0], yy[1], xx[2] + yy[2] + solve(xx[1] + yy[0]))
				elif lyy > 2:
					z = xx[1] + yy[0]
					b[x[0]] = (z[:3], yy[1], xx[2] + yy[2] + solve(xx[1] + yy[0]))
				elif lxx > 2:
					z = xx[1] + yy[0]
					b[x[0]] = (xx[0], z[len(z) - 3:], xx[2] + yy[2] + solve(xx[1] + yy[0]))
				else:
					z = xx[1] + yy[0]
					b[x[0]] = (z[:3], z[max(0, len(z) - 3):], xx[2] + yy[2] + solve(xx[1] + yy[0]))
		print(b[x[0]][2])
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
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

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

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

def LI1():
	return list(map(int1, sys.stdin.buffer.readline().split()))

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

def LLI1(rows_number):
	return [LI1() for _ in range(rows_number)]

def BI():
	return sys.stdin.buffer.readline().rstrip()

def SI():
	return sys.stdin.buffer.readline().rstrip().decode()
dij = [(0, 1), (-1, 0), (0, -1), (1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]
inf = 10 ** 16
md = 998244353

class haha:

	def __init__(self, s=''):
		self.val = self.cnt(s)
		self.pre = s[:3]
		self.suf = s[-3:]
		self.size = len(s)

	def cnt(self, s):
		res = 0
		for i in range(len(s) - 3):
			if s[i:i + 4] == 'haha':
				res += 1
		return res

	def __add__(self, other):
		if self.size < 6 and other.size < 6:
			s = self.pre if self.size < 4 else self.pre + self.suf[6 - self.size:]
			t = other.pre if other.size < 4 else other.pre + other.suf[6 - other.size:]
			return haha(s + t)
		res = haha()
		if self.size < 6:
			s = self.pre if self.size < 4 else self.pre + self.suf[6 - self.size:]
			res.pre = (s + other.pre)[:3]
			res.suf = other.suf
		elif other.size < 6:
			t = other.pre if other.size < 4 else other.pre + other.suf[6 - other.size:]
			res.pre = self.pre
			res.suf = (self.suf + t)[-3:]
		else:
			res.pre = self.pre
			res.suf = other.suf
		res.val = self.cnt(self.suf + other.pre) + self.val + other.val
		res.size = self.size + other.size
		return res
for testcase in range(II()):
	n = II()
	var = {}
	last = ''
	for _ in range(n):
		task = SI().split()
		if task[1] == ':=':
			var[task[0]] = haha(task[2])
		else:
			var[task[0]] = var[task[2]] + var[task[4]]
		last = task[0]
	print(var[last].val)


import sys
input = sys.stdin.readline

def haha_count(s):
	ans = 0
	for i in range(len(s) - 3):
		ans += s[i:i + 4] == 'haha'
	return ans

def solve():
	n = int(input())
	d = {}
	l = 1
	for i in range(n):
		e = input().strip()
		if ':' in e:
			(l, r) = e.split(' := ')
			d[l] = [haha_count(r), r[:3], r[max(-3, -len(r)):]]
		else:
			(l, r) = e.split(' = ')
			(a, b) = r.split(' + ')
			new_pref = d[a][1]
			new_pref += d[b][1][:len(new_pref) - 3]
			new_suff = ''
			if len(d[b][2]) < 3:
				new_suff += d[a][2][max(-len(a), -(3 - len(d[b][2]))):]
			new_suff += d[b][2]
			d[l] = [d[a][0] + d[b][0] + haha_count(d[a][2] + d[b][1]), new_pref, new_suff]
	print(d[l][0])
for _ in range(int(input())):
	solve()


from collections import defaultdict
poss = [['h', 'aha'], ['ha', 'ha'], ['hah', 'a']]
for _ in range(int(input())):
	n = int(input())
	l = defaultdict(lambda : [])
	d = defaultdict(lambda : 0)
	pre = defaultdict(lambda : [])
	suff = defaultdict(lambda : [])
	last = ''
	for j in range(n):
		b = input().split(' ')
		if b[1] != '=':
			last = b[0]
			d[last] = 0
			pre[last] = []
			suff[last] = []
			s = ''
			for j in range(min(len(b[2]), 3)):
				s += b[2][j]
				pre[last].append(s)
			s1 = ''
			new = b[2][::-1]
			for j in range(min(len(b[2]), 3)):
				s1 += new[j]
				suff[last].append(s1[::-1])
			if b[2] == 'haha':
				d[last] = 1
			elif len(b[2]) == 5:
				if b[2][:4] == 'haha':
					d[last] += 1
				if b[2][1:5] == 'haha':
					d[last] += 1
			l[last] = [len(b[2]), b[2]]
		else:
			last = b[0]
			v1 = b[2]
			v2 = b[4]
			p1 = d[v1] + d[v2]
			if l[v1][0] >= 3 and l[v2][0] >= 3:
				for j in poss:
					if j[0] in suff[v1] and j[1] in pre[v2]:
						p1 += 1
				ps = []
				for j in suff[v2]:
					ps.append(j)
				pr = []
				for j in pre[v1]:
					pr.append(j)
				pre[last] = pr
				suff[last] = ps
				d[last] = p1
				l[last] = [3, '']
			elif l[v1][0] >= 3:
				for j in poss:
					if j[0] in suff[v1] and j[1] in pre[v2]:
						p1 += 1
				pr = []
				for j in pre[v1]:
					pr.append(j)
				ps = []
				for j in suff[v2]:
					ps.append(j)
				for k in suff[v1]:
					if len(ps) > 3:
						break
					else:
						ps.append(k + j)
				pre[last] = pr
				suff[last] = ps
				d[last] = p1
				l[last] = [3, '']
			elif l[v2][0] >= 3:
				for j in poss:
					if j[0] in suff[v1] and j[1] in pre[v2]:
						p1 += 1
				ps = []
				for j in suff[v2]:
					ps.append(j)
				pr = []
				for j in pre[v1]:
					pr.append(j)
				for k in pre[v2]:
					if len(pr) > 3:
						break
					else:
						pr.append(j + k)
				pre[last] = pr
				suff[last] = ps
				d[last] = p1
				l[last] = [3, '']
			else:
				s2 = l[v1][1] + l[v2][1]
				s = ''
				pre[last] = []
				suff[last] = []
				d[last] = 0
				for j in range(min(len(s2), 3)):
					s += s2[j]
					pre[last].append(s)
				s1 = ''
				new = s2[::-1]
				for j in range(min(len(s2), 3)):
					s1 += new[j]
					suff[last].append(s1[::-1])
				if s2 == 'haha':
					d[last] = 1
				elif len(s2) == 5:
					if s2[:4] == 'haha':
						d[last] += 1
					if s2[1:5] == 'haha':
						d[last] += 1
				l[last] = [len(s2), s2]
	print(d[last])


def f(a):
	Res = 0
	for i in range(len(a) - 3):
		if a[i:i + 4] == 'haha':
			Res += 1
	return Res
for m in range(int(input())):
	X = {}
	for k in range(int(input())):
		A = input().split()
		if len(A) == 3:
			X[A[0]] = [A[2][:3], A[2][-3:], f(A[2])]
		else:
			tmp1 = X[A[2]][0] + X[A[4]][0][:3 - len(X[A[2]][0])]
			if len(X[A[4]][1]) < 3:
				tmp2 = X[A[2]][1][-(3 - len(X[A[4]][1])):] + X[A[4]][1]
			else:
				tmp2 = X[A[4]][1]
			X[A[0]] = [tmp1, tmp2, X[A[2]][2] + X[A[4]][2] + f(X[A[2]][1] + X[A[4]][0])]
	print(X[A[0]][2])


import os
import sys
from math import *
from collections import *
from heapq import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
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')
ALPHA = 'abcdefghijklmnopqrstuvwxyz'
M = 998244353
EPS = 1e-06

def Ceil(a, b):
	return a // b + int(a % b > 0)

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]

def Count(s):
	ans = 0
	for i in range(len(s)):
		if s[i:i + 4] == 'haha':
			ans += 1
	return ans
for _ in range(Int()):
	n = Int()
	C = defaultdict(int)
	first = defaultdict(str)
	last = defaultdict(str)
	for i in range(n):
		exp = input().split()
		x = exp[0]
		if exp[1] == ':=':
			val = exp[-1]
			C[x] = Count(val)
			first[x] = val[:3]
			last[x] = val[-3:]
		else:
			a = exp[2]
			b = exp[4]
			C[x] = C[a] + C[b] + Count(last[a] + first[b])
			val = first[a]
			if len(val) < 3:
				val = first[a] + first[b]
			first[x] = val[:3]
			val = last[b]
			if len(val) < 3:
				val = last[a] + last[b]
			last[x] = val[-3:]
	print(C[x])


import sys
t = int(sys.stdin.readline())

def count_haha(a, b):
	last_a = 'ha' if a[-4:] == 'haha' else a[-4:]
	beg_b = 'ha' if b[:4] == 'haha' else b[:4]
	s = last_a + beg_b
	n = len(s)
	c = 0
	for i in range(0, n - 3):
		if s[i:i + 4] == 'haha':
			c += 1
	return c

def count(s):
	n = len(s)
	c = 0
	for i in range(0, n - 3):
		if s[i:i + 4] == 'haha':
			c += 1
	return c
for _ in range(t):
	n = int(sys.stdin.readline())
	track_var = {}
	for i in range(n):
		ess = sys.stdin.readline()
		if ':=' in ess:
			(var, __, val) = ess.split()
			c = count(val)
			track_var[var] = [val, c]
			if i == n - 1:
				print(track_var[var][1])
		if ' = ' in ess:
			(var, __, a, ___, b) = ess.split()
			c = count_haha(track_var[a][0], track_var[b][0])
			old = track_var[a][1] + track_var[b][1]
			if var not in track_var:
				track_var[var] = ['', 0]
			track_var[var][0] = track_var[a][0][:4] + track_var[b][0][-4:]
			track_var[var][1] = old + c
			if i == n - 1:
				print(track_var[var][1])


def count_haha(s):
	c = 0
	for i in range(len(s) - 3):
		if s[i] == 'h' and s[i + 1] == 'a' and (s[i + 2] == 'h') and (s[i + 3] == 'a'):
			c += 1
	return c
for T in range(int(input())):
	n = int(input())
	dic = {}
	for i in range(n):
		s = input().split()
		if s[1] == ':=':
			dic[s[0]] = (s[2][:3], s[2][-3:], count_haha(s[2]))
		else:
			dic[s[0]] = ((dic[s[2]][0] + dic[s[4]][0])[:3], (dic[s[2]][1] + dic[s[4]][1])[-3:], dic[s[2]][2] + dic[s[4]][2] + count_haha(dic[s[2]][1] + dic[s[4]][0]))
	print(dic[s[0]][2])


import os
import sys
from io import BytesIO, IOBase

def main():
	T = int(input())
	for _ in range(T):
		n = int(input())
		ls = ''
		G = {}
		s1 = 'haha'
		fans = 0
		for i in range(n):
			s = input()
			try:
				v = s.index(':')
				val = s[:v - 1]
				ls = s[v + 3:]
				ans = 0
				for i in range(len(ls) - 3):
					if ls[i:i + 4] == s1:
						ans = ans + 1
				G[val] = [ans, ls[:3], ls[-3:]]
				fans = ans
			except:
				v = s.index('=')
				var = s[:v - 1]
				v1 = s.index('+')
				ls = G[s[v + 2:v1 - 1]][2] + G[s[v1 + 2:]][1]
				ans = 0
				for i in range(len(ls) - 3):
					if ls[i:i + 4] == s1:
						ans = ans + 1
				ls = G[s[v + 2:v1 - 1]][1] + G[s[v1 + 2:]][2]
				G[var] = [ans + G[s[v + 2:v1 - 1]][0] + G[s[v1 + 2:]][0], ls[:3], ls[-3:]]
				fans = G[var][0]
		print(fans)
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()


def occ(temp_string):
	count = 0
	start = 0
	while True:
		start = temp_string.find('haha', start) + 1
		if start > 0:
			count += 1
		else:
			return count
t = int(input())
for _ in range(t):
	n = int(input())
	var = {}
	val = {}
	li = []
	s = 'lol'
	for i in range(n):
		s = list(input().split())
		if len(s) == 3:
			var[s[0]] = s[2]
			val[s[0]] = occ(s[2])
		else:
			temp = val[s[2]] + val[s[4]]
			string = var[s[2]][-1:-4:-1][::-1] + var[s[4]][0:3:1]
			temp += occ(string)
			val[s[0]] = temp
			string = var[s[2]] + var[s[4]]
			if len(string) > 6:
				string = string[0:3:1] + string[-1:-4:-1][::-1]
			var[s[0]] = string
	print(val[s[0]])


from sys import stdin
from collections import defaultdict as dd

def cnt(s):
	res = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			res += 1
	return res
t = int(stdin.readline())
for _ in range(t):
	n = int(stdin.readline())
	s = ''
	dp = dd(lambda : 0)
	vs = dd(lambda : '')
	ss = dd(lambda : '')
	for i in range(n):
		s = stdin.readline().split()
		if s[1] == ':=':
			rs = ''.join(s[2:])
			vs[s[0]] = rs[-3:]
			ss[s[0]] = rs[:3]
			dp[s[0]] = cnt(rs)
		else:
			dp[s[0]] = dp[s[2]] + dp[s[4]]
			dp[s[0]] += cnt(vs[s[2]] + ss[s[4]])
			vs[s[0]] = (vs[s[2]] + vs[s[4]])[-3:]
			ss[s[0]] = (ss[s[2]] + ss[s[4]])[:3]
	print(dp[s[0]])


def basic_count_occurences(t, p='haha'):
	cnt = 0
	n = len(t)
	m = len(p)
	for i in range(n - m + 1):
		if t[i:i + m] == p:
			cnt += 1
	return cnt

def get_s(s0):
	if len(s0) >= 6:
		s = s0[:3] + s0[-3:]
	else:
		s = s0
	return s

def solve(n):
	latest = None
	v = {}
	for i in range(n):
		exp = input().split(' ')
		if len(exp) == 3:
			latest = exp[0]
			occs = basic_count_occurences(exp[2])
			s = get_s(exp[2])
			v[exp[0]] = [s, occs]
		else:
			(target, var1, var2) = (exp[0], exp[2], exp[4])
			latest = target
			old_occs = v[var1][1] + v[var2][1]
			new_occs = basic_count_occurences(v[var1][0][-3:] + v[var2][0][:3])
			occs = old_occs + new_occs
			s = get_s(v[var1][0] + v[var2][0])
			v[target] = [s, occs]
	return v[latest][1]

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


def solve():
	n = int(input())
	first4 = {}
	last4 = {}
	no = {}
	L = {}
	Var = ''
	for _t in range(n):
		s = input()
		if ':' in s:
			l = s.split(' := ')
			var = l[0]
			Var = var
			st = l[1]
			if len(st) >= 4:
				first4[var] = st[:4]
				last4[var] = st[-4:]
			else:
				first4[var] = st
				last4[var] = st
			c = 0
			for i in range(0, len(st) - 3):
				if st[i:i + 4] == 'haha':
					c += 1
			no[var] = c
			L[var] = len(st)
		else:
			l1 = s.split(' = ')
			var = l1[0]
			Var = var
			l2 = l1[1].split(' + ')
			var1 = l2[0]
			var2 = l2[1]
			if L[var1] + L[var2] >= 4:
				L[var] = L[var1] + L[var2]
				cnt = 0
				if len(last4[var1]) >= 1 and len(first4[var2]) >= 3:
					if last4[var1][-1] == 'h' and first4[var2][:3] == 'aha':
						cnt += 1
				if len(last4[var1]) >= 2 and len(first4[var2]) >= 2:
					if last4[var1][-2:] == 'ha' and first4[var2][:2] == 'ha':
						cnt += 1
				if len(last4[var1]) >= 3 and len(first4[var2]) >= 1:
					if last4[var1][-3:] == 'hah' and first4[var2][:1] == 'a':
						cnt += 1
				f = first4[var1]
				l = last4[var2]
				if len(f) < 4:
					extra = 4 - len(f)
					first4[var] = f + first4[var2][:extra]
				else:
					first4[var] = f
				if len(l) < 4:
					extra = 4 - len(l)
					last4[var] = last4[var1][-extra:] + l
				else:
					last4[var] = l
				no[var] = no[var1] + no[var2] + cnt
			else:
				L[var] = L[var1] + L[var2]
				first4[var] = first4[var1] + first4[var2]
				last4[var] = last4[var2] + last4[var2]
				no[var] = no[var1] + no[var2]
	print(no[Var])
for _ in range(int(input())):
	solve()


t = int(input())
for _ in range(t):
	n = int(input())
	d = {}
	for i in range(n):
		s = input()
		if ':' in s:
			col = s.index(':')
			eq = s.index('=')
			st = s[0:col - 1]
			d[st] = [s[eq + 2:][:3], s[eq + 2:][-3:], s[eq + 2:].count('haha')]
		else:
			plus = s.index('+')
			eq = s.index('=')
			st = s[0:eq - 1]
			a = s[eq + 2:plus - 1]
			b = s[plus + 2:]
			res = 0
			if d[a][1].endswith('h') and d[b][0].startswith('aha'):
				res += 1
			if d[a][1].endswith('ha') and d[b][0].startswith('ha'):
				res += 1
			if d[a][1].endswith('hah') and d[b][0].startswith('a'):
				res += 1
			d[st] = [(d[a][0] + d[b][0])[:3], (d[a][1] + d[b][1])[-3:], d[a][2] + d[b][2] + res]
		if i == n - 1:
			print(d[st][2])


def cou(s):
	res = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			res += 1
	return res

def solve():
	var = dict()
	for i in range(int(input())):
		s = input().split()
		if s[1] == ':=':
			var[s[0]] = (cou(s[2]), s[2][:3], s[2][-3:])
		else:
			var[s[0]] = (cou(var[s[2]][2] + var[s[4]][1]) + var[s[2]][0] + var[s[4]][0], (var[s[2]][1] + var[s[4]][1])[:3], (var[s[2]][2] + var[s[4]][2])[-3:])
	print(var[s[0]][0])
t = int(input())
for i in range(t):
	solve()


def counthaha(n):
	count = 0
	for i in range(len(n)):
		if n[i:i + 4] == 'haha':
			count += 1
	return [count, len(n), n[:3], n[-3:]]

def plus(a, b):
	tempcount = varnames[a][0] + varnames[b][0]
	tempconnection = varnames[a][3] + varnames[b][2]
	for i in range(len(tempconnection)):
		if tempconnection[i:i + 4] == 'haha':
			tempcount += 1
	first = varnames[a][2]
	if len(first) < 3:
		first += varnames[b][2][:3 - len(first)]
	last = varnames[b][3]
	if len(last) < 3:
		newlast = ''
		newlast += varnames[a][3][3 - len(first) + 1:]
		newlast += last
		last = newlast
	return [tempcount, varnames[a][1] + varnames[b][1], first, last]
t = int(input())
answers = []
for i in range(t):
	varnames = {}
	n = int(input())
	for x in range(n):
		line = list(input().split(' '))
		finalvar = line[0]
		if ':=' in line:
			varnames[line[0]] = counthaha(line[2])
		elif '=' in line:
			varnames[line[0]] = plus(line[2], line[4])
	print(varnames[finalvar][0])


t = int(input())
for _ in range(t):
	n = int(input())
	tupleDict = dict()
	for _ in range(n):
		statement = input().split()
		if ':=' in statement:
			variableName = statement[0]
			variable = statement[2]
			numLaughs = 0
			for i in range(len(variable)):
				if variable[i:i + 4] == 'haha':
					numLaughs += 1
			tuple = (variable[:3], variable[-3:], numLaughs)
			tupleDict[variableName] = tuple
			lastVariableName = variableName
		else:
			variableName = statement[0]
			a = statement[2]
			b = statement[4]
			(aStart, aEnd, aLaughs) = tupleDict[a]
			(bStart, bEnd, bLaughs) = tupleDict[b]
			if len(aStart) == 1:
				start = aStart + bStart[:2]
			elif len(aStart) == 2:
				start = aStart + bStart[:1]
			else:
				start = aStart
			if len(bEnd) == 1:
				end = aEnd[-2:] + bEnd
			elif len(bEnd) == 2:
				end = aEnd[-1:] + bEnd
			else:
				end = bEnd
			check = aEnd + bStart
			numLaughs = 0
			for i in range(len(check)):
				if check[i:i + 4] == 'haha':
					numLaughs += 1
			numLaughs += aLaughs
			numLaughs += bLaughs
			newTuple = (start, end, numLaughs)
			tupleDict[variableName] = newTuple
			lastVariableName = variableName
	print(tupleDict[lastVariableName][2])


import os, sys
from io import BytesIO, IOBase
from math import log2, ceil, sqrt, gcd
from _collections import deque
import heapq as hp
from bisect import bisect_left, bisect_right
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')
mod = 10 ** 9 + 7

def count(s):
	ans = 0
	n = len(s)
	for i in range(n - 4 + 1):
		if s[i:i + 4] == 'haha':
			ans += 1
	return ans

def mix(s):
	ans = str()
	for i in range(min(len(s), 3)):
		ans += s[i]
	return ans

def mix2(s):
	ans = str()
	for i in range(min(len(s), 3)):
		ans += s[-(i + 1)]
	return ans[::-1]
for _ in range(int(input())):
	n = int(input())
	d = dict()
	last = str()
	for _ in range(n):
		st = input().split()
		last = st[0]
		if st[1] == ':=':
			f = str()
			l = str()
			for i in range(min(len(st[2]), 3)):
				f += st[2][i]
				l += st[2][-(i + 1)]
			l = l[::-1]
			d[st[0]] = [count(st[2]), f, l]
		else:
			f = d[st[2]][2] + d[st[4]][1]
			ct = count(f)
			f = str()
			l = str()
			if len(d[st[2]][1]) < 3:
				f = mix(d[st[2]][1] + d[st[4]][1])
			else:
				f = d[st[2]][1]
			if len(d[st[4]][2]) < 3:
				l = mix2(d[st[2]][2] + d[st[4]][2])
			else:
				l = d[st[4]][2]
			if st[0] in d:
				d[st[0]][0] = d[st[2]][0] + ct + d[st[4]][0]
				d[st[0]][1] = f
				d[st[0]][2] = l
			else:
				d[st[0]] = [d[st[2]][0] + ct + d[st[4]][0], f, l]
	print(d[last][0])


from sys import stdin, stdout
from math import floor, gcd, fabs, factorial, fmod, sqrt, inf, log
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
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
S1 = 'abcdefghijklmnopqrstuvwxyz'
S2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

def isprime(x):
	if x <= 1:
		return False
	if x in (2, 3):
		return True
	if x % 2 == 0:
		return False
	for i in range(3, int(sqrt(x)) + 1, 2):
		if x % i == 0:
			return False
	return True

def cnt(s):
	c = 0
	for i in range(len(s) - 3):
		c += s[i:i + 4] == 'haha'
	return c
for _ in range(int(inp())):
	n = iinp()
	md = {}
	for i in range(n):
		s = inp()
		if ':=' in s:
			l = s.split(' := ')
			md[l[0]] = (l[1][:3], cnt(l[1]), l[1][-3:])
		else:
			l = s.split(' = ')
			nl = l[1].split(' + ')
			(a, b) = nl
			x = 0
			x = cnt(md[a][2] + md[b][0])
			li = (md[a][0] + md[b][2])[:3]
			ri = (md[a][0] + md[b][2])[-3:]
			md[l[0]] = (li, x + md[a][1] + md[b][1], ri)
	print(md[l[0]][1])


import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
T = int(input())
t = 1
while t <= T:
	n = int(input())
	dic = {}
	hahanum = {}
	for i in range(n):
		s = input().split()
		newv = s[0]
		if len(s) == 3:
			dic[newv] = [s[2], s[2]]
			if b'haha' in s[2]:
				hahanum[newv] = 1
			else:
				hahanum[newv] = 0
		elif len(s) == 5:
			fronts = dic[s[2]]
			rears = dic[s[4]]
			if len(fronts[0]) >= 5 and len(rears[1]) >= 5:
				newfront = fronts[0]
				newrear = rears[1]
			elif len(fronts[0]) < 5 and len(rears[1]) < 5:
				news = fronts[0] + rears[1]
				newfront = news[:5]
				newrear = news[-5:]
			elif len(fronts[0]) == 5 and len(rears[1]) < 5:
				newfront = fronts[0]
				newrear = fronts[1][-(5 - len(rears[1])):] + rears[1]
			elif len(fronts[0]) < 5 and len(rears[1]) == 5:
				newrear = rears[1]
				newfront = fronts[0] + rears[0][:5 - len(fronts[0])]
			base = 0
			for i in [1, 2, 3]:
				if fronts[1][-i:] + rears[0][:4 - i] == b'haha':
					base += 1
			base += hahanum[s[2]]
			base += hahanum[s[4]]
			dic[newv] = [newfront, newrear]
			hahanum[newv] = base
	print(hahanum[newv])
	t += 1


from collections import defaultdict, Counter

def main():
	for case in range(int(input())):
		ct = dict()
		start = dict()
		ending = dict()

		def count_s(s):
			c = 0
			for i in range(0, len(s) - 3):
				if s[i:i + 4] == 'haha':
					c += 1
			return c

		def update(var, val):
			ct[var] = count_s(val)
			(pre, suf) = ['', '']
			if len(val) < 4:
				pre = val
				suf = val
			else:
				pre = val[:3]
				suf = val[::-1][:3][::-1]
			start[var] = pre
			ending[var] = suf

		def combine(s1, s2):
			c = ct[s1] + ct[s2]
			tmp = ending[s1] + start[s2]
			c += count_s(tmp)
			pre = start[s1]
			suf = ending[s2]
			if len(pre) < 3:
				pre += start[s2]
				if len(pre) > 3:
					pre = pre[:3]
			if len(suf) < 3:
				suf = ending[s1] + suf
				if len(suf) > 3:
					suf = suf[::-1][:3][::-1]
			return [c, pre, suf]
		ans = 0
		for i in range(int(input())):
			s = [x for x in input().split()]
			if s[1] == ':=':
				update(s[0], s[-1])
				ans = ct[s[0]]
			else:
				(c, pre, suf) = combine(s[2], s[4])
				ct[s[0]] = c
				start[s[0]] = pre
				ending[s[0]] = suf
				ans = ct[s[0]]
		print(ans)
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()


def dem(a):
	res = 0
	if len(a) < 4:
		return 0
	else:
		n = len(a)
		for i in range(3, n):
			if a[i - 3:i + 1] == 'haha':
				res += 1
	return res
T = int(input())
for uwu in range(T):
	n = int(input())
	(dau, cuoi, result) = ({}, {}, {})
	for i in range(n):
		a = input().split()
		if len(a) == 3:
			if len(a[2]) < 3:
				dau[a[0]] = a[2]
				cuoi[a[0]] = a[2]
				result[a[0]] = 0
			else:
				dau[a[0]] = a[2][:3]
				cuoi[a[0]] = a[2][-3:]
				result[a[0]] = dem(a[2])
		else:
			string = cuoi[a[2]] + dau[a[4]]
			if len(dau[a[2]]) < 3:
				dau[a[0]] = dau[a[2]] + dau[a[4]][:min(len(dau[a[4]]), 3 - len(dau[a[2]]))]
			else:
				dau[a[0]] = dau[a[2]]
			if len(cuoi[a[4]]) < 3:
				cuoi[a[0]] = cuoi[a[2]][max(0, len(cuoi[a[2]]) - 3 + len(cuoi[a[4]])):] + cuoi[a[4]]
			else:
				cuoi[a[0]] = cuoi[a[4]]
			result[a[0]] = result[a[2]] + result[a[4]] + dem(string)
		if i == n - 1:
			print(result[a[0]])


import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')

def count(s) -> int:
	cnt = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			cnt += 1
	return cnt
for _ in range(int(input())):
	n = int(input())
	d = {}
	ans = 0
	for i in range(n):
		s = input().split()
		if s[1] == ':=':
			d[s[0]] = (count(s[2]), s[2][:3], s[2][-3:])
		else:
			d[s[0]] = (d[s[2]][0] + d[s[4]][0] + count(d[s[2]][2] + d[s[4]][1]), (d[s[2]][1] + d[s[4]][1])[:3], (d[s[2]][2] + d[s[4]][2])[-3:])
	print(d[s[0]][0])


import sys
input = sys.stdin.readline
import math
import copy
import collections
from collections import deque
import heapq
import itertools
from collections import defaultdict
from collections import Counter

def quer(s):
	arr = s.split()
	type = 0
	if len(arr) == 3:
		type = 1
	else:
		type = 2
	if type == 1:
		return (arr[0], arr[2])
	else:
		return (arr[0], arr[2], arr[4])
for _ in range(int(input())):
	ha = 'haha'
	n = int(input())
	starts = dict()
	ends = dict()
	vals = dict()
	val = 0
	for i in range(n):
		s = input().rstrip()
		temp = quer(s)
		if len(temp) == 2:
			val = 0
			for j in range(len(temp[1]) - 3):
				if temp[1][j:j + 4] == ha:
					val += 1
			vals[temp[0]] = val
			temps = temp[1]
			starts[temp[0]] = temps[:3]
			ends[temp[0]] = temps[-3:]
		else:
			b = ''
			e = ''
			b = (starts[temp[1]] + starts[temp[2]])[:3]
			e = (ends[temp[1]] + ends[temp[2]])[-3:]
			val = vals[temp[1]] + vals[temp[2]]
			temps = ends[temp[1]] + starts[temp[2]]
			for j in range(len(temps) - 3):
				if temps[j:j + 4] == ha:
					val += 1
			starts[temp[0]] = b
			ends[temp[0]] = e
			vals[temp[0]] = val
	print(val)


class Word:

	def __init__(self, s=None):
		if s is None:
			return
		self.value = (s[:4] == 'haha') + (s[1:] == 'haha')
		self.prefix = s[:3]
		self.suffix = s[-3:]

	def __add__(self, other):
		w = Word()
		w.value = self.value + other.value
		t = self.suffix + other.prefix
		w.value += (t[:4] == 'haha') + (t[1:5] == 'haha') + (t[2:] == 'haha')
		w.prefix = (self.prefix + other.prefix)[:3]
		w.suffix = (self.suffix + other.suffix)[-3:]
		return w
var = {}
for _ in range(int(input())):
	for _ in range(int(input())):
		s = input().split()
		if len(s) == 3:
			var[s[0]] = Word(s[2])
		else:
			var[s[0]] = var[s[2]] + var[s[4]]
	print(var[s[0]].value)


def p(s):
	(a0, b0, c0) = (0, '', '')
	a0 = s.count('haha')
	b0 = s[:3]
	c0 = s[-3:]
	return [a0, b0, c0, s]

def solve():
	n = int(input())
	value = {}
	for i in range(n):
		a = list(input().split())
		if len(a) == 3:
			(x, s0) = (a[0], a[2])
			value[x] = p(s0)
		else:
			(x, y, z) = (a[0], a[2], a[4])
			last = value[y][2]
			top = value[z][1]
			if len(last) < 3 or len(top) < 3:
				l_y = value[y][2]
				t_y = value[y][1]
				l_z = value[z][2]
				t_z = value[z][1]
				if len(l_y) < 3 and len(t_z) < 3:
					s0 = value[y][3] + value[z][3]
					value[x] = p(s0)
				elif len(l_y) < 3:
					s0 = l_y + t_z
					(j1, j2, j3) = (value[y][0] + value[z][0] + s0.count('haha'), s0[:3], l_z)
					value[x] = [j1, j2, j3, '']
				else:
					s0 = l_y + t_z
					(j1, j2, j3) = (value[y][0] + value[z][0] + s0.count('haha'), t_y, s0[-1:])
					value[x] = [j1, j2, j3, '']
			else:
				(k, j2, j3) = (value[y][0] + value[z][0], value[y][1], value[z][2])
				s0 = value[y][3] + value[z][3]
				if last[0:] + top[:1] == 'haha':
					k += 1
				if last[1:] + top[:2] == 'haha':
					k += 1
				if last[2:] + top[:3] == 'haha':
					k += 1
				value[x] = [k, j2, j3, '']
		if i == n - 1:
			print(value[a[0]][0])
t = int(input())
for i in range(t):
	solve()


def count(s):
	cnt = 0
	for i in range(len(s) - 3):
		if s[i:i + 4] == 'haha':
			cnt += 1
	return cnt

def merge(d1, d2):
	(prefix1, suffix1, cnt1) = d1
	(prefix2, suffix2, cnt2) = d2
	cnt = cnt1 + cnt2 + count(suffix1 + prefix2)
	return ((prefix1 + prefix2)[:3], (suffix1 + suffix2)[-3:], cnt)
for _ in range(int(input())):
	d = {}
	for _ in range(int(input())):
		tokens = input().split()
		if tokens[1] == ':=':
			(k, _, v) = tokens
			d[k] = (v[:3], v[-3:], v.count('haha'))
		elif tokens[1] == '=':
			(k, _, k1, _, k2) = tokens
			d[k] = merge(d[k1], d[k2])
		else:
			print(tokens)
			raise NotImplementedError
	print(d[k][-1])


def count(s):
	return sum((1 if s[i:].startswith('haha') else 0 for i in range(len(s) - 3)))

def prefix(s):
	return s[:3] if len(s) >= 3 else s

def suffix(s):
	return s[len(s) - 3:] if len(s) >= 3 else s
T = int(input())
for _ in range(T):
	n = int(input())
	V = {}
	for _ in range(n):
		cmd = input().split(' ')
		if cmd[1] == ':=':
			V[cmd[0]] = (count(cmd[2]), prefix(cmd[2]), suffix(cmd[2]))
		else:
			(c1, p1, s1) = V[cmd[2]]
			(c2, p2, s2) = V[cmd[4]]
			c = c1 + c2 + count(s1 + p2)
			V[cmd[0]] = (c, prefix(p1 + p2), suffix(s1 + s2))
	print(V[cmd[0]][0])


import time
import os, sys
from io import BytesIO, IOBase
from types import GeneratorType
from bisect import bisect_left, bisect_right
from collections import defaultdict as dd, deque as dq, Counter as dc
import math, string, heapq as h
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')

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

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

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

def getStr():
	return input()

def listStr():
	return list(input())

def getMat(n):
	return [getInts() for _ in range(n)]

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

def isInt(s):
	return '0' <= s[0] <= '9'

def ceil_(a, b):
	return (a + b - 1) // b
MOD = 10 ** 9 + 7

def solve():
	global case
	case += 1
	memo = dd(int)
	memo2 = dd(str)
	memo3 = dd(str)
	N = getInt()
	for i in range(N):
		S = getStrs()
		if len(S) == 3:
			memo[S[0]] = S[2].count('haha')
			memo2[S[0]] = S[2][:3]
			memo3[S[0]] = S[2][-3:]
		else:
			memo[S[0]] = memo[S[2]] + memo[S[4]]
			tmp = memo3[S[2]] + memo2[S[4]]
			for i in range(len(tmp)):
				if tmp[i:i + 4] == 'haha':
					memo[S[0]] += 1
			(L2, L4) = (len(memo2[S[2]]), len(memo3[S[4]]))
			memo2[S[0]] = memo2[S[2]] + (memo2[S[4]][:3 - L2] if 3 > L2 else '')
			memo3[S[0]] = (memo3[S[2]][-(3 - L4):] if 3 > L4 else '') + memo3[S[4]]
		lst = S[0]
	return memo[lst]
global case
case = 0
for _ in range(getInt()):
	if case <= 5 or case >= 65:
		print(solve())
	else:
		print(solve())


def count(s1, s2):
	return sum((s1[i:i + len(s2)] == s2 for i in range(len(s1))))
T = int(input())
for _ in range(T):
	n = int(input())
	variables = {}
	command = None
	for c in range(n):
		command = input().strip().split()
		if len(command) == 3:
			(x, a) = (command[0], command[-1])
			variables[x] = [a, count(a, 'haha')]
		elif len(command) == 5:
			(x, a, b) = (command[0], command[2], command[4])
			(v1, v2) = (variables[a], variables[b])
			variables[x] = [v1[0] + v2[0], v1[-1] + v2[-1] + count(v1[0][-3:] + v2[0][:3], 'haha')]
			if len(variables[x][0]) > 6:
				variables[x][0] = variables[x][0][:3] + variables[x][0][-3:]
		else:
			raise ValueError('')
	print(variables[command[0]][-1])


t = int(input())

def countSub(x):
	ans = 0
	for i in range(len(x) - 3):
		if x[i:i + 4] == 'haha':
			ans += 1
	return ans

def solve():
	n = int(input())
	d = dict()
	last_cmd = ''
	for i in range(n):
		cmd = input()
		if ':' in cmd:
			args = cmd.split(' := ')
			ft = args[1][0:min(3, len(args[1]))]
			lt = args[1][max(0, len(args[1]) - 3):]
			d[args[0]] = [ft, lt, countSub(args[1])]
			last_cmd = args[0]
		else:
			args = cmd.split(' = ')
			eq = args[1].split(' + ')
			s1 = d[eq[0]]
			s2 = d[eq[1]]
			newCount = s1[2] + s2[2]
			newCount += countSub(s1[1] + s2[0])
			prefix = s1[0]
			suffix = s2[1]
			if len(prefix) < 3:
				prefix += suffix[0:min(len(suffix), 3 - len(prefix))]
			if len(suffix) < 3:
				need = 3 - len(suffix)
				suffix = s1[1][max(0, len(s1[1]) - need):len(s1[1])] + suffix
			d[args[0]] = [prefix, suffix, newCount]
			last_cmd = args[0]
	print(d[last_cmd][2])
for i in range(t):
	solve()


class Factory:

	def __init__(self):
		self.table = []
		self.occurrence = ''
		self.prefix = ''
		self.suffix = ''

	def add_equation(self, string):
		string = string.replace(' ', '')
		if ':=' in string:
			self.assign(string)
		else:
			self.plus(string)

	def assign(self, string):
		(var, val) = string.split(':=')
		i = self.index(var)
		if i != -1:
			(self.table[i][1], self.table[i][2], self.table[i][3]) = self.convert(val)
		else:
			(x, y, z) = self.convert(val)
			self.table.append([var, x, y, z])

	def plus(self, string):
		(var, val) = string.split('=')
		(x, y) = val.split('+')
		(i, j) = (self.index(x), self.index(y))
		count = self.table[i][3] + self.table[j][3] + self._occurrence(self.table[i][2] + self.table[j][1])
		if len(self.table[i][1]) > 2:
			pre = self.table[i][1]
		else:
			remain = 3 - len(self.table[i][1])
			pre = self.table[i][1] + self.table[j][1][:remain]
		if len(self.table[j][2]) > 2:
			suf = self.table[j][2]
		else:
			remain = 3 - len(self.table[j][2])
			suf = self.table[i][2][-remain:] + self.table[i][2]
		idx = self.index(var)
		if idx != -1:
			self.table[idx] = [var, pre, suf, count]
		else:
			self.table.append([var, pre, suf, count])

	def _occurrence(self, string):
		if len(string) < 3:
			return 0
		else:
			count = 0
			for i in range(len(string) - 3):
				if string[i:i + 4] == 'haha':
					count += 1
			return count

	def index(self, var, debug=False):
		for i in range(len(self.table)):
			if debug:
				print('debug', self.table[i][0], var)
			if self.table[i][0] == var:
				return i
		return -1

	def convert(self, string):
		if len(string) < 3:
			return (string, string, 0)
		else:
			count = 0
			for i in range(len(string) - 3):
				if string[i:i + 4] == 'haha':
					count += 1
			return (string[:3], string[-3:], count)
for _ in range(int(input())):
	f = Factory()
	for i in range(int(input())):
		string = input().replace(' ', '')
		f.add_equation(string)
	var = string.split(':=')[0].split('=')[0]
	i = f.index(var)
	print(f.table[i][3])


def count(string):
	c = 0
	for i in range(len(string) - 3):
		k = 0
		va = 0
		for j in 'haha':
			if string[i + k] == j:
				va += 1
			else:
				break
			k += 1
		if va == 4:
			c += 1
	return c

def values(string):
	length = len(string)
	occurance = 0
	if length >= 3:
		prifix = string[:3]
		suffix = string[length - 3:]
		occurance = count(string)
	else:
		prifix = string[:]
		suffix = string[:]
	lis = [length, occurance, prifix, suffix]
	return lis
for _ in range(int(input())):
	n = int(input())
	a = []
	for i in range(n):
		a.append(input())
	d = {}
	e = 0
	for i in a:
		if ':' in i:
			ind = i.index(':')
			lis = values(i[ind + 3:])
			d[i[:ind - 1]] = lis
		else:
			ind = i.index('=')
			plus = i.index('+')
			left = i[ind + 2:plus - 1]
			right = i[plus + 2:]
			le = d[left][0] + d[right][0]
			occ = d[left][1] + d[right][1]
			ts = d[left][3] + d[right][2]
			if d[left][0] < 3 and d[right][0] < 3:
				pr = d[left][2] + d[right][2]
				pri = pr[:3]
				suf = pr[-3:]
			elif d[left][0] < 3 and d[right][0] >= 3:
				pri = d[left][2] + d[right][2]
				pri = pri[:3]
				suf = d[right][3]
			elif d[left][0] >= 3 and d[right][0] < 3:
				pri = d[left][2]
				suf = d[left][3] + d[right][2]
				suf = suf[-3:]
			else:
				pri = d[left][2]
				suf = d[right][3]
			occ += count(ts)
			d[i[:ind - 1]] = [le, occ, pri, suf]
		if e == n - 1:
			print(d[i[:ind - 1]][1])
			break
		e += 1