#include<algorithm>
#include<vector>
#include<iostream>
#include<math.h>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
#include<queue>
#define qcin; ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define clr(x) memset(x,0,sizeof x)
#define fmax(x) memset(x,0x3f,sizeof x)
#define finit(x) memset(x,-1,sizeof x)
#define dis(l,r) r-l+1
#define gstr(str) scanf("%s",str)
#define glen(str) strlen(str)
using namespace std;
typedef long long ll;
const int maxn = 100000+10;
const int inf = 0x3f3f3f3f;
typedef int arr[maxn];
typedef char str[maxn];
void file(int x){if(x&&fopen("123.in","r")){freopen("123.in","r",stdin);}}
const int mod=1e9+7;
struct Edge{
int to,next,cap,flow,cost;
}edge[maxn];
int head[maxn],pre[maxn],dis[maxn],vis[maxn];
int tot;
int n,m,x,cnt,st,en,L,u,v,q,cst,len,t;
const double pi=acos(-1);
unordered_map<string,int>M;
string su,sv;
int e[maxn][3];
int gid(string x){
if(M.find(x)!=M.end())return M[x];
M[x]=++cnt;
return M[x];
}
void addedge(int u,int v,int cap,int cost){
edge[tot].to=v;
edge[tot].cap=cap;
edge[tot].cost=cost;
edge[tot].flow=0;
edge[tot].next=head[u];
head[u]=tot++;
edge[tot].to=u;
edge[tot].cap=0;
edge[tot].cost=-cost;
edge[tot].flow=0;
edge[tot].next=head[v];
head[v]=tot++;
}
int spfa(int st,int en){
queue<int>q;
for(int i=0;i<2*cnt+5;i++){
dis[i]=inf;
vis[i]=false;
pre[i]=-1;
}
dis[st]=0;
vis[st]=1;
q.push(st);
while(q.size()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
if(~pre[en])return 1;
else return 0;
}
int c_f(int st,int en,int&cost){
int flow=0;
cost=0;
while(spfa(st,en)){
int mi=inf;
for(int i=pre[en];~i;i=pre[edge[i^1].to]){
if(mi>edge[i].cap-edge[i].flow)
mi=edge[i].cap-edge[i].flow;
}
for(int i=pre[en];~i;i=pre[edge[i^1].to]){
edge[i].flow+=mi;
edge[i^1].flow-=mi;
cost+=edge[i].cost*mi;
}
flow+=mi;
}
return flow;
}
int main(){
file(1);
qcin;
for(cin>>t;t--;){
M.clear();
M["Dalian"]=1;
M["Shanghai"]=2;
M["Xian"]=3;
cnt=3;
cin>>m;
tot=0;
finit(head);
for(int i=0;i<m;i++){
cin>>su>>sv>>cst;
e[i][0]=gid(su);
e[i][1]=gid(sv);
e[i][2]=cst;
}
st=2*cnt+1;
en=2*cnt+2;
addedge(st,2,2,0);
addedge(1+cnt,en,1,0);
addedge(3+cnt,en,1,0);
for(int i=1;i<=cnt;i++){
if(i==2)addedge(i,i+cnt,2,0);
else addedge(i,i+cnt,1,0);
}
for(int i=0;i<m;i++){
addedge(e[i][0]+cnt,e[i][1],inf,e[i][2]);
addedge(e[i][1]+cnt,e[i][0],inf,e[i][2]);
}
int cost=0,flow;
flow=c_f(st,en,cost);
if(flow!=2)cout<<-1<<endl;
else cout<<cost<<endl;
}
return 0;
}
#include<algorithm>
#include<vector>
#include<iostream>
#include<math.h>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
#include<queue>
#define qcin; ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define clr(x) memset(x,0,sizeof x)
#define fmax(x) memset(x,0x3f,sizeof x)
#define finit(x) memset(x,-1,sizeof x)
#define dis(l,r) r-l+1
#define gstr(str) scanf("%s",str)
#define glen(str) strlen(str)
using namespace std;
typedef long long ll;
const int maxn = 100000+10;
const int inf = 0x3f3f3f3f;
typedef int arr[maxn];
typedef char str[maxn];
void file(int x){if(x&&fopen("123.in","r")){freopen("123.in","r",stdin);}}
const int mod=1e9+7;
struct Edge{
int to,next,cap,flow,cost;
}edge[maxn];
int head[maxn],pre[maxn],dis[maxn],vis[maxn];
int tot;
int n,m,x,cnt,st,en,L,u,v,q,cst,len,t;
const double pi=acos(-1);
unordered_map<string,int>M;
string su,sv;
int e[maxn][3];
int gid(string x){
if(M.find(x)!=M.end())return M[x];
M[x]=++cnt;
return M[x];
}
void addedge(int u,int v,int cap,int cost){
edge[tot].to=v;
edge[tot].cap=cap;
edge[tot].cost=cost;
edge[tot].flow=0;
edge[tot].next=head[u];
head[u]=tot++;
edge[tot].to=u;
edge[tot].cap=0;
edge[tot].cost=-cost;
edge[tot].flow=0;
edge[tot].next=head[v];
head[v]=tot++;
}
int spfa(int st,int en){
queue<int>q;
for(int i=0;i<2*cnt+5;i++){
dis[i]=inf;
vis[i]=false;
pre[i]=-1;
}
dis[st]=0;
vis[st]=1;
q.push(st);
while(q.size()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
if(~pre[en])return 1;
else return 0;
}
int c_f(int st,int en,int&cost){
int flow=0;
cost=0;
while(spfa(st,en)){
int mi=inf;
for(int i=pre[en];~i;i=pre[edge[i^1].to]){
if(mi>edge[i].cap-edge[i].flow)
mi=edge[i].cap-edge[i].flow;
}
for(int i=pre[en];~i;i=pre[edge[i^1].to]){
edge[i].flow+=mi;
edge[i^1].flow-=mi;
cost+=edge[i].cost*mi;
}
flow+=mi;
}
return flow;
}
int main(){
file(1);
qcin;
for(cin>>t;t--;){
M.clear();
M["Xian"]=1;
M["Hongqiao"]=2;
M["Pudong"]=3;
M["Qingdao"]=4;
cnt=4;
cin>>m;
tot=0;
finit(head);
for(int i=0;i<m;i++){
cin>>su>>sv>>cst;
e[i][0]=gid(su);
e[i][1]=gid(sv);
e[i][2]=cst;
}
st=2*cnt+1;
en=2*cnt+2;
addedge(st,1,1,0);
addedge(st,4,2,0);
addedge(2+cnt,en,2,0);
addedge(3+cnt,en,1,0);
for(int i=1;i<=cnt;i++){
if(i==2||i==4)addedge(i,i+cnt,2,0);
else addedge(i,i+cnt,1,0);
}
for(int i=0;i<m;i++){
addedge(e[i][0]+cnt,e[i][1],inf,e[i][2]);
addedge(e[i][1]+cnt,e[i][0],inf,e[i][2]);
}
int cost=0,flow;
flow=c_f(st,en,cost);
if(flow!=3)cout<<-1<<endl;
else cout<<cost<<endl;
}
return 0;
}