Zurikela is creating a graph with a special graph maker. At the begining, it is empty and has no nodes or edges. He can perform $3$ types of operations:    

$\mbox{A}$ $\boldsymbol{x}$: Create a set of $\boldsymbol{x}$ new nodes and name it $\boldsymbol{set}$-$\mbox{K}$.    
$\mbox{B}$ $\boldsymbol{x}$ $y$: Create edges between nodes of $\boldsymbol{set}$-$\boldsymbol{x}$ and $\boldsymbol{set}$-$y$.      
$\mbox{C}$ $\boldsymbol{x}$: Create a set composed of nodes from $\boldsymbol{set}$-$\boldsymbol{x}$ and its directly and indirectly connected nodes, called $\boldsymbol{set}$-$\mbox{K}$. Note that each node can only exist in one set, so other sets become empty.     

The first $\boldsymbol{set}$'s name will be $\boldsymbol{set}$-$\mbox{1}$. In first and third operation $\mbox{K}$ is referring to the index of new set:

K = [index of last created set] + 1

Create the graph by completing the $\mbox{Q}$ operations specified during input. Then calculate the maximum number of independent nodes (i.e.:how many nodes in the final graph which don't have direct edge between them).

Input Format

The first line contains $\mbox{Q}$. 

The $\mbox{Q}$ subsequent lines each contain an operation to be performed.

Constraints 

$1\leq Q\leq10^5$.

For the first operation, $1\leq x\leq10^4$. 

For the second operation, $x<y$ and all $y$s are distinct.

For the second and third operation, it's guaranteed that $\boldsymbol{set}$-$\boldsymbol{x}$ and $\boldsymbol{set}$-$y$ exist.     

Output Format

Print maximum number of independent nodes in the final graph (i.e.: nodes which have no direct connection to one another).

Sample Input
8
A 1
A 2
B 1 2
C 1
A 2
A 3
B 3 4
B 4 5

Sample Output
5

Explanation

There are $8$ operations.

After first operation$\left({A\mbox{1}}\right)$:

After second operation$\left({A\mbox{2}}\right)$:

After third operation$(B\:1\:2)$:

After fourth operation$\left({C1}\right)$:

After fifth and sixth operation $\left({A\mbox{2}}\right)$ and $(A3)$:

After seventh operation$\left({B\:\:3\:\:4}\right)$:

After eigth operation$\left(B\:4\:5\right)$:

There are $2$ independent nodes in $\boldsymbol{set}$-$3$ and $3$ independent nodes in $\boldsymbol{set}$-$5$, so we print their sum ($5$) as our answer.

Source: hackerrank | Difficulty: MEDIUM_HARD
Tags: Dynamic programming


Solutions:
from collections import deque

class IndepSet:

	def __init__(self, seed):
		self.value = self.bestfor(0, {seed}, set())

	def bestfor(self, value, fringe, visited):
		if not fringe:
			self.visited = visited
			return value
		v = fringe.pop()
		adj = {a for a in v.adjacent if a not in visited}
		incl_vis = visited.union({v}, adj)
		incl = self.bestfor(value + v.value, fringe.union(adj, *[a.adjacent for a in adj]).difference(incl_vis), incl_vis)
		excl = self.bestfor(value, fringe.union(adj), visited.union({v}))
		return max(incl, excl)

class MetaNode:

	def __init__(self, value, id):
		self.value = value
		self.adjacent = set()
		self.id = id

	def __repr__(self):
		return '<%d: value %d%s>' % (self.id, self.value, ' LINKED: ' + ','.join([str(a.id) for a in self.adjacent]) if self.adjacent else '')

class Main:

	def __init__(self):
		self.v = [None]
		ops = int(input())
		for i in range(ops):
			self.readcommand()
		print(self.indep())

	def readcommand(self):
		(cmd, *params) = input().split()
		if cmd == 'A':
			num = int(params[0])
			node = MetaNode(num, len(self.v))
			self.v.append(node)
		elif cmd == 'B':
			(xi, yi) = map(int, params)
			self.v[xi].adjacent.add(self.v[yi])
			self.v[yi].adjacent.add(self.v[xi])
		elif cmd == 'C':
			xi = int(params[0])
			i = IndepSet(self.v[xi])
			for n in i.visited:
				self.v[n.id] = None
			new = MetaNode(i.value, len(self.v))
			self.v.append(new)

	def indep(self):
		visited = set()
		value = 0
		for i in range(len(self.v)):
			if self.v[i]:
				if self.v[i] in visited:
					continue
				if self.v[i].adjacent:
					s = IndepSet(self.v[i])
					visited = visited.union(s.visited)
					value += s.value
				else:
					value += self.v[i].value
		return value
Main()


import sys

def main():
	allsets = Nodeset.sets
	while True:
		try:
			line = input()
		except EOFError:
			break
		(command, *args) = line.split()
		if command == 'A':
			Nodeset(int(args[0]))
		elif command == 'B':
			(parent, child) = [allsets[int(arg)] for arg in args]
			assert child.parent is None
			parent.children.append(child)
			child.parent = parent
		elif command == 'C':
			comprise(allsets[int(args[0])])
	oldlen = len(allsets)
	for i in range(oldlen):
		s = allsets[i]
		if s is None:
			continue
		comprise(s)
	print(sum((s.indepsize for s in allsets[oldlen:])))

def comprise(s):
	while s.parent is not None:
		s = s.parent
	unregister(s)
	Nodeset(max(bestindep(s)))

def unregister(s):
	Nodeset.sets[s.index] = None
	for child in s.children:
		unregister(child)

def bestindep(s):
	bestwith = s.indepsize
	bestwithout = 0
	for child in s.children:
		(w, wo) = bestindep(child)
		bestwith += wo
		bestwithout += max(w, wo)
	return (bestwith, bestwithout)

class Nodeset:
	sets = [None]

	def __init__(self, size):
		self.index = len(Nodeset.sets)
		Nodeset.sets.append(self)
		self.parent = None
		self.children = []
		self.indepsize = size
main()


from itertools import repeat
M = 200010
AdjList = [[] for i in repeat(None, M)]
dppp = [0 for i in range(M)]
dpp1 = [0 for i in range(M)]
my_str = ''
done = [0 for i in range(M)]
max_ind = [0 for i in range(M)]
N = 0

def dfs(node, dad):
	dpp1[node] = max_ind[node]
	for i in range(len(AdjList[node])):
		v = AdjList[node][i]
		if v != dad:
			dfs(v, node)
			dppp[node] = dppp[node] + max(dppp[v], dpp1[v])
			dpp1[node] = dpp1[node] + dppp[v]
	done[node] = 0
Q = int(input())
for q in range(Q):
	my_str = str(input())
	u = my_str.split(' ')
	if my_str[0] == 'A':
		x = int(u[1])
		N = N + 1
		max_ind[N] = x
		done[N] = 1
	elif my_str[0] == 'B':
		x = int(u[1])
		y = int(u[2])
		AdjList[x].append(y)
		AdjList[y].append(x)
	elif my_str[0] == 'C':
		x = int(u[1])
		dfs(x, x)
		N = N + 1
		max_ind[N] = max(dppp[x], dpp1[x])
		done[N] = 1
ans = 0
for i in range(N):
	if done[i + 1] == 1:
		dfs(i + 1, i + 1)
		ans = ans + max(dppp[i + 1], dpp1[i + 1])
print(str(ans))


import os
import sys

def find_all(in_list, value):
	result = []
	offset = 0
	while True:
		try:
			newind = in_list.index(value, offset)
		except ValueError:
			return result
		result.append(newind)
		offset = newind + 1

class zgraph:

	def __init__(self):
		self.SetList = []
		self.AdjList = []
		self.SizeList = []
		self.TypeList = []

	def getAlive(self):
		return [x for (x, name) in enumerate(self.TypeList) if not name.endswith('no')]

	def rev(self, node_set):
		node_set = set(node_set)
		return {node: node_set - self.AdjList[node] for node in node_set}

	def compTF(self, node_set, adjlist):
		for node in node_set:
			if not node_set.issubset(adjlist[node]):
				return False
		return True

	def mis(self, node_set):
		if not node_set:
			return 0
		rev_adjlist = self.rev(node_set)
		max_size = {}
		while node_set:
			root = node_set.pop()
			max_size[root] = self.SizeList[root] + self.mis(rev_adjlist[root] - set([root]))
		return max(max_size.values())

	def pre_mis(self):
		self.alive = self.getAlive()
		self.AdjMat = [[0] * len(self.alive) for _ in range(len(self.alive))]
		self.alive_size = [0] * len(self.alive)
		for (i, node) in enumerate(self.alive):
			self.alive_size[i] = self.SizeList[node]
			self.AdjMat[i][i] = 1
			for node_b in self.AdjList[node]:
				node_b_ind = self.alive.index(node_b)
				self.AdjMat[i][node_b_ind] = 1
				self.AdjMat[node_b_ind][i] = 1
		self.alive_adjlist = {i: set(find_all(self.AdjMat[i], 0)) for i in range(len(self.alive))}

	def mis_all(self, node_set):
		if not node_set:
			return 0
		base_size = 0
		single_node = set([node for node in node_set if len(node_set & self.alive_adjlist[node]) == len(node_set) - 1])
		for node in single_node:
			base_size += self.alive_size[node]
		node_set = node_set - single_node
		max_size = 0
		while node_set:
			root = node_set.pop()
			max_size = max(max_size, self.alive_size[root] + self.mis_all(node_set & self.alive_adjlist[root]))
		return base_size + max_size

	def get_mis_all(self):
		self.pre_mis()
		return self.mis_all(set(range(len(self.alive))))

	def opA(self, x):
		K = len(self.SetList)
		self.SetList.append(set([K]))
		self.SizeList.append(x)
		self.AdjList.append(set())
		self.TypeList.append('A')
		assert len(self.SetList) == len(self.SizeList) == len(self.AdjList) == len(self.TypeList)

	def opB(self, x, y):
		kx = x - 1
		ky = y - 1
		self.AdjList[kx].add(ky)
		self.AdjList[ky].add(kx)

	def opC_sub(self, kx, y):
		for yy in self.AdjList[y]:
			if yy not in self.SetList[kx]:
				self.TypeList[yy] += 'no'
				self.SetList[kx].add(yy)
				self.opC_sub(kx, yy)

	def opC(self, x):
		kx = x - 1
		K = len(self.SetList)
		self.SetList.append(set())
		self.AdjList.append(set())
		self.opC_sub(K, kx)
		size = self.mis(self.SetList[K])
		self.SizeList.append(size)
		self.TypeList.append('C')
		assert len(self.SetList) == len(self.SizeList) == len(self.AdjList) == len(self.TypeList)

	def readOPs(self, op):
		if op[0] == 'A':
			self.opA(int(op[2:]))
		elif op[0] == 'B':
			(x, y) = list(map(int, op[2:].split(' ')))
			self.opB(x, y)
		elif op[0] == 'C':
			self.opC(int(op[2:]))
		else:
			print('invalid operation ignored: ' + op)

	def get_mis_all_2(self):
		self.alive = self.getAlive()
		for node in self.alive:
			if self.TypeList[node].endswith('no'):
				continue
			self.opC(node + 1)
		return sum([self.SizeList[node] for node in self.getAlive()])
n = int(input())
zg = zgraph()
for _ in range(n):
	op = input()
	zg.readOPs(op)
print(zg.get_mis_all_2())


from itertools import repeat
M = 200010
adjList = [[] for i in repeat(None, M)]
dppp = [0 for i in range(M)]
dpp1 = [0 for i in range(M)]
myStr = ''
done = [0 for i in range(M)]
maxInd = [0 for i in range(M)]
N = 0

def dfs(node, dad):
	dpp1[node] = maxInd[node]
	for i in range(len(adjList[node])):
		v = adjList[node][i]
		if v != dad:
			dfs(v, node)
			dppp[node] = dppp[node] + max(dppp[v], dpp1[v])
			dpp1[node] = dpp1[node] + dppp[v]
	done[node] = 0
Q = int(input())
for q in range(Q):
	myStr = str(input())
	u = myStr.split(' ')
	if myStr[0] == 'A':
		x = int(u[1])
		N += 1
		maxInd[N] = x
		done[N] = 1
	elif myStr[0] == 'B':
		x = int(u[1])
		y = int(u[2])
		adjList[x].append(y)
		adjList[y].append(x)
	elif myStr[0] == 'C':
		x = int(u[1])
		dfs(x, x)
		N += 1
		maxInd[N] = max(dppp[x], dpp1[x])
		done[N] = 1
ans = 0
for i in range(N):
	if done[i + 1] == 1:
		dfs(i + 1, i + 1)
		ans += max(dppp[i + 1], dpp1[i + 1])
print(str(ans))


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


class Set:
	id = 0
	nr_vertices = 0
	neighbors = set()

	def __init__(self, id, v):
		self.id = id
		self.nr_vertices = v
		self.neighbors = set()

	def printout(self):
		pass
		print(self.id, self.nr_vertices, self.neighbors)

class Solver:
	sets = {}
	next_id = 1
	visited = set()
	values = {}

	def __init__(self):
		pass

	def execute(self):
		nr_ops = int(input().rstrip())
		for i in range(nr_ops):
			op = input().rstrip().split()
			if op[0] == 'A':
				self.A(int(op[1]))
			elif op[0] == 'B':
				self.B(int(op[1]), int(op[2]))
			elif op[0] == 'C':
				self.C(int(op[1]))
			else:
				print('Unknown operation')
		all_ids = [x for x in self.sets]
		total = 0
		while True:
			if len(all_ids) == 0:
				break
			i = all_ids[0]
			self.visited = {i}
			self.bfs(i)
			v = self.getMax(self.visited)
			for x in self.visited:
				all_ids.remove(x)
			total += v
		print(total)

	def A(self, v):
		id = self.getId()
		s = Set(id, v)
		self.sets[id] = s

	def B(self, v1, v2):
		s1 = self.sets[v1]
		s2 = self.sets[v2]
		s1.neighbors.add(v2)
		s2.neighbors.add(v1)

	def C(self, v):
		s = self.sets[v]
		self.visited = {v}
		self.bfs(v)
		max = self.getMax(self.visited)
		id = self.getId()
		self.sets[id] = Set(id, max)
		for s in self.visited:
			del self.sets[s]

	def getId(self):
		self.next_id += 1
		return self.next_id - 1

	def printout(self):
		pass
		for s in self.sets:
			self.sets[s].printout()

	def bfs(self, s):
		process = set()
		for n in self.sets[s].neighbors:
			if n not in self.visited:
				self.visited.add(n)
				process.add(n)
		for n in process:
			self.bfs(n)

	def checkIfDone(self, sets):
		l = list(sets)
		l.sort()
		key = '-'.join(map(str, l))
		if key in self.values:
			return self.values[key]
		else:
			return None

	def getMax(self, sets):
		if len(sets) == 0:
			return 0
		if len(sets) == 1:
			return self.sets[list(sets)[0]].nr_vertices
		v = self.checkIfDone(sets)
		if v is not None:
			return v
		v = 0
		for x in sets:
			x_neighbors = self.sets[x].neighbors.intersection(sets)
			sets_without_x = sets.copy()
			sets_without_x.remove(x)
			reduced_set = sets_without_x - x_neighbors
			t = max(self.sets[x].nr_vertices + self.getMax(reduced_set), self.getMax(sets_without_x))
			if t > v:
				v = t
		return v
s = Solver()
s.execute()


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


from collections import deque

class IndepSet:

	def __init__(self, seed):
		self.value = self.bestfor(0, {seed}, set())

	def bestfor(self, value, fringe, visited):
		if not fringe:
			self.visited = visited
			return value
		v = fringe.pop()
		adj = {a for a in v.adjacent if a not in visited}
		incl_vis = visited.union({v}, adj)
		incl = self.bestfor(value + v.value, fringe.union(adj, *[a.adjacent for a in adj]).difference(incl_vis), incl_vis)
		excl = self.bestfor(value, fringe.union(adj), visited.union({v}))
		return max(incl, excl)

class MetaNode:

	def __init__(self, value, id):
		self.value = value
		self.adjacent = set()
		self.id = id

	def __repr__(self):
		return '<%d: value %d%s>' % (self.id, self.value, ' LINKED: ' + ','.join([str(a.id) for a in self.adjacent]) if self.adjacent else '')

class Main:

	def __init__(self):
		self.v = [None]
		ops = int(input())
		for i in range(ops):
			self.readcommand()
		print(self.indep())

	def readcommand(self):
		(cmd, *params) = input().split()
		if cmd == 'A':
			num = int(params[0])
			node = MetaNode(num, len(self.v))
			self.v.append(node)
		elif cmd == 'B':
			(xi, yi) = map(int, params)
			self.v[xi].adjacent.add(self.v[yi])
			self.v[yi].adjacent.add(self.v[xi])
		elif cmd == 'C':
			xi = int(params[0])
			i = IndepSet(self.v[xi])
			for n in i.visited:
				self.v[n.id] = None
			new = MetaNode(i.value, len(self.v))
			self.v.append(new)

	def indep(self):
		visited = set()
		value = 0
		for i in range(len(self.v)):
			if self.v[i]:
				if self.v[i] in visited:
					continue
				if self.v[i].adjacent:
					s = IndepSet(self.v[i])
					visited = visited.union(s.visited)
					value += s.value
				else:
					value += self.v[i].value
		return value
Main()


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


from itertools import repeat
M = 200010
AdjList = [[] for i in repeat(None, M)]
dppp = [0 for i in range(M)]
dpp1 = [0 for i in range(M)]
my_str = ''
done = [0 for i in range(M)]
max_ind = [0 for i in range(M)]
N = 0

def dfs(node, dad):
	dpp1[node] = max_ind[node]
	for i in range(len(AdjList[node])):
		v = AdjList[node][i]
		if v != dad:
			dfs(v, node)
			dppp[node] = dppp[node] + max(dppp[v], dpp1[v])
			dpp1[node] = dpp1[node] + dppp[v]
	done[node] = 0
Q = int(input())
for q in range(Q):
	my_str = str(input())
	u = my_str.split(' ')
	if my_str[0] == 'A':
		x = int(u[1])
		N = N + 1
		max_ind[N] = x
		done[N] = 1
	elif my_str[0] == 'B':
		x = int(u[1])
		y = int(u[2])
		AdjList[x].append(y)
		AdjList[y].append(x)
	elif my_str[0] == 'C':
		x = int(u[1])
		dfs(x, x)
		N = N + 1
		max_ind[N] = max(dppp[x], dpp1[x])
		done[N] = 1
ans = 0
for i in range(N):
	if done[i + 1] == 1:
		dfs(i + 1, i + 1)
		ans = ans + max(dppp[i + 1], dpp1[i + 1])
print(str(ans))


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


from itertools import repeat
M = 200010
AdjList = [[] for i in repeat(None, M)]
dppp = [0 for i in range(M)]
dpp1 = [0 for i in range(M)]
my_str = ''
done = [0 for i in range(M)]
max_ind = [0 for i in range(M)]
N = 0

def dfs(node, dad):
	dpp1[node] = max_ind[node]
	for i in range(len(AdjList[node])):
		v = AdjList[node][i]
		if v != dad:
			dfs(v, node)
			dppp[node] = dppp[node] + max(dppp[v], dpp1[v])
			dpp1[node] = dpp1[node] + dppp[v]
	done[node] = 0
Q = int(input())
for q in range(Q):
	my_str = str(input())
	u = my_str.split(' ')
	if my_str[0] == 'A':
		x = int(u[1])
		N = N + 1
		max_ind[N] = x
		done[N] = 1
	elif my_str[0] == 'B':
		x = int(u[1])
		y = int(u[2])
		AdjList[x].append(y)
		AdjList[y].append(x)
	elif my_str[0] == 'C':
		x = int(u[1])
		dfs(x, x)
		N = N + 1
		max_ind[N] = max(dppp[x], dpp1[x])
		done[N] = 1
ans = 0
for i in range(N):
	if done[i + 1] == 1:
		dfs(i + 1, i + 1)
		ans = ans + max(dppp[i + 1], dpp1[i + 1])
print(str(ans))


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


from itertools import repeat
M = 200010
AdjList = [[] for i in repeat(None, M)]
dppp = [0 for i in range(M)]
dpp1 = [0 for i in range(M)]
my_str = ''
done = [0 for i in range(M)]
max_ind = [0 for i in range(M)]
N = 0

def dfs(node, dad):
	dpp1[node] = max_ind[node]
	for i in range(len(AdjList[node])):
		v = AdjList[node][i]
		if v != dad:
			dfs(v, node)
			dppp[node] = dppp[node] + max(dppp[v], dpp1[v])
			dpp1[node] = dpp1[node] + dppp[v]
	done[node] = 0
Q = int(input())
for q in range(Q):
	my_str = str(input())
	u = my_str.split(' ')
	if my_str[0] == 'A':
		x = int(u[1])
		N = N + 1
		max_ind[N] = x
		done[N] = 1
	elif my_str[0] == 'B':
		x = int(u[1])
		y = int(u[2])
		AdjList[x].append(y)
		AdjList[y].append(x)
	elif my_str[0] == 'C':
		x = int(u[1])
		dfs(x, x)
		N = N + 1
		max_ind[N] = max(dppp[x], dpp1[x])
		done[N] = 1
ans = 0
for i in range(N):
	if done[i + 1] == 1:
		dfs(i + 1, i + 1)
		ans = ans + max(dppp[i + 1], dpp1[i + 1])
print(str(ans))


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


from itertools import repeat
M = 200010
AdjList = [[] for i in repeat(None, M)]
dppp = [0 for i in range(M)]
dpp1 = [0 for i in range(M)]
my_str = ''
done = [0 for i in range(M)]
max_ind = [0 for i in range(M)]
N = 0

def dfs(node, dad):
	dpp1[node] = max_ind[node]
	for i in range(len(AdjList[node])):
		v = AdjList[node][i]
		if v != dad:
			dfs(v, node)
			dppp[node] = dppp[node] + max(dppp[v], dpp1[v])
			dpp1[node] = dpp1[node] + dppp[v]
	done[node] = 0
Q = int(input())
for q in range(Q):
	my_str = str(input())
	u = my_str.split(' ')
	if my_str[0] == 'A':
		x = int(u[1])
		N = N + 1
		max_ind[N] = x
		done[N] = 1
	elif my_str[0] == 'B':
		x = int(u[1])
		y = int(u[2])
		AdjList[x].append(y)
		AdjList[y].append(x)
	elif my_str[0] == 'C':
		x = int(u[1])
		dfs(x, x)
		N = N + 1
		max_ind[N] = max(dppp[x], dpp1[x])
		done[N] = 1
ans = 0
for i in range(N):
	if done[i + 1] == 1:
		dfs(i + 1, i + 1)
		ans = ans + max(dppp[i + 1], dpp1[i + 1])
print(str(ans))


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


from itertools import repeat
M = 200010
AdjList = [[] for i in repeat(None, M)]
dppp = [0 for i in range(M)]
dpp1 = [0 for i in range(M)]
my_str = ''
done = [0 for i in range(M)]
max_ind = [0 for i in range(M)]
N = 0

def dfs(node, dad):
	dpp1[node] = max_ind[node]
	for i in range(len(AdjList[node])):
		v = AdjList[node][i]
		if v != dad:
			dfs(v, node)
			dppp[node] = dppp[node] + max(dppp[v], dpp1[v])
			dpp1[node] = dpp1[node] + dppp[v]
	done[node] = 0
Q = int(input())
for q in range(Q):
	my_str = str(input())
	u = my_str.split(' ')
	if my_str[0] == 'A':
		x = int(u[1])
		N = N + 1
		max_ind[N] = x
		done[N] = 1
	elif my_str[0] == 'B':
		x = int(u[1])
		y = int(u[2])
		AdjList[x].append(y)
		AdjList[y].append(x)
	elif my_str[0] == 'C':
		x = int(u[1])
		dfs(x, x)
		N = N + 1
		max_ind[N] = max(dppp[x], dpp1[x])
		done[N] = 1
ans = 0
for i in range(N):
	if done[i + 1] == 1:
		dfs(i + 1, i + 1)
		ans = ans + max(dppp[i + 1], dpp1[i + 1])
print(str(ans))


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)


Q = int(input().strip())
neighbors = {}
weights = []

def flood_fill(x, vis):
	vis.add(x)
	for y in neighbors[x]:
		if not y in vis:
			flood_fill(y, vis)
	return vis

def compute_indep(graph, curr, n):
	if n == len(graph):
		return sum(map(lambda x: weights[x], curr))
	elif weights[graph[n]] == 0:
		return compute_indep(graph, curr, n + 1)
	ans = compute_indep(graph, curr, n + 1)
	x = graph[n]
	possible = True
	for y in curr:
		if y in neighbors[x]:
			possible = False
			break
	if possible:
		ans = max(ans, compute_indep(graph, curr + [x], n + 1))
	return ans
for i in range(Q):
	query = input().strip()
	if query[0] == 'A':
		weights.append(int(query[1:]))
		neighbors[len(weights) - 1] = set()
	elif query[0] == 'B':
		(x, y) = map(int, query[1:].split())
		neighbors[x - 1].add(y - 1)
		neighbors[y - 1].add(x - 1)
	else:
		component = list(flood_fill(int(query[1:]) - 1, set()))
		weights.append(compute_indep(component, [], 0))
		neighbors[len(weights) - 1] = set()
		for x in component:
			weights[x] = 0
			neighbors[x] = set()
counted = set()
ans = 0
for i in range(len(weights)):
	if weights[i] > 0 and i not in counted:
		component = list(flood_fill(i, set()))
		for x in component:
			counted.add(x)
		ans += compute_indep(component, [], 0)
print(ans)