#include <iostream>
#include <string>
using namespace std;

const int MAXSIZE = 50;

int bcount;

int match[MAXSIZE];

struct vertex {
	string word;
	int indeg, outdeg;
	bool used;
} lang1[MAXSIZE], lang2[MAXSIZE];

struct graph {
	bool edges[MAXSIZE][MAXSIZE];
	vertex words[MAXSIZE];
	int numV;
} graph1, graph2;

void initMatch(int n)
{
	for(int i=0; i<n; i++) {
		match[i] = -1;
	}
}

void initGraph(graph &g)
{
	for(int i=0; i<MAXSIZE; i++) {
		for(int j=0; j<MAXSIZE; j++) {
			g.edges[i][j] = false;
		}
		g.words[i].indeg = g.words[i].outdeg = 0;
		g.words[i].used = false;
	}
	g.numV = 0;
}

int findVertex(string w1, graph &g)
{
	int i;
	for(i=0; i<g.numV; i++) {
		if (g.words[i].word == w1)
			return i;
	}
	g.words[i].word = w1;
	g.words[i].indeg = g.words[i].outdeg = 0;
	g.numV++;
	return i;
}

void addEdge(string w1, string w2, graph &g)
{
	int v1 = findVertex(w1, g);
	int v2 = findVertex(w2, g);
	if (g.edges[v1][v2]) {
		cout << "ERROR: repeated input: " << w1 << ' ' << w2 << endl;
//		exit(-1);
	}
	g.edges[v1][v2] = true;
	g.words[v1].outdeg++;			// but keep track of in and out degree
	g.words[v2].indeg++;
}

bool canMatch(int v1, int v2, int n)
{
	if (graph2.words[v2].used)
		return false;
	if (graph1.words[v1].outdeg != graph2.words[v2].outdeg)
		return false;
	if (graph1.words[v1].indeg != graph2.words[v2].indeg)
		return false;
	for(int i=0; i<n; i++) {
		if (match[i] != -1) {
//cout << "  in match[i] != -1 check, v1, i, v2, match[i] = " << v1 << ',' << i << ',' << v2 << ',' << match[i] << endl;
			if (graph1.edges[v1][i] && !graph2.edges[v2][match[i]]) 
				return false;
			if (graph1.edges[i][v1] && !graph2.edges[match[i]][v2])
				return false;
		}
		if (i == v1) {
//cout << "  in i == v1" << endl;
			if (graph1.edges[v1][v1] && !graph2.edges[v2][v2])
				return false;
			if (!graph1.edges[v1][v1] && graph2.edges[v2][v2])
				return false;
		}
	}
	return true;
}

bool findMatching(int v, int count, int n)
{
	if (count == n)
		return true;
	else {
		for(int i=0; i<n; i++) {
//cout << "trying " << graph1.words[v].word << " matched to " << graph2.words[i].word << endl;
			if (canMatch(v, i, n)) {
//cout << "   success" << endl;
				match[v] = i;
				graph2.words[i].used = true;
				if (findMatching(v+1, count+1, n))
					return true;
				graph2.words[i].used = false;
				match[v] = -1;
			}
		}
		match[v] = -1;
//cout << "backtracking on word " << graph1.words[v].word << endl;
bcount++;
		return false;
	}
}

int main()
{
	int n;
	string word1, word2;
	cin >> n;
	while (n != 0) {
bcount=0;
		initGraph(graph1);
		initGraph(graph2);
		for(int i=0; i<n; i++) {
			cin >> word1 >> word2;
			addEdge(word1, word2, graph1);
		}
		for(int i=0; i<n; i++) {
			cin >> word1 >> word2;
			addEdge(word1, word2, graph2);
		}

		initMatch(graph1.numV);
		if (findMatching(0,0,graph1.numV)) {
			for(int i=0; i<graph1.numV; i++) {
				string best = "~";
				int index = -1;
				for(int j=0; j<graph1.numV; j++) {
					if (graph1.words[j].word < best) {
						best = graph1.words[j].word;
						index = j;
					}
				}
				cout << best << '/' << graph2.words[match[index]].word << endl;
				graph1.words[index].word = "~";
			}
		}
		else
			cout << "no matching" << endl;
//cout << bcount << endl;
//cout << endl;
		cin >> n;
if(n>0) cout<<endl;
	}
return 0;
}
