#include <iostream>
#include <cmath>

using namespace std;


/*
Существенная часть задачи

Исходя из условий, я понял, что фамилии похожи, если они: 
1) Различаются по длине не более, чем на 1 букву
2) Отличаются только последней буквой

Здесть важное уточнение: мой алгоритм считает, что "ааб" и "аав" - похожие. 
Из задания не ясно, похожи они, или нет

*/
bool isSimilar(string left, string right, size_t diff_chars = 1) {

	auto a = left.begin(); 
	auto b = right.begin();

	// Отсекаем фамилии, которые сильно отличаются по длине. 
	// Они точно не будут похожими	
	size_t diff = abs((int)left.length() - (int)right.length());
	if (diff > diff_chars) {		
		return false;
	}

	size_t similar_chars = 0;
	// Пробегаем по строкам посимвольно, пока символы равны.
	// Попутно увеличивая переменную `similar_chars`
	for(;a != left.end() && b != right.end(); a++, b++, similar_chars++) {		
		if (*a != *b) {
			break;
		}
	}

	// Если количество одинаковых символов отличается 
	// от длины самой длинной фамилии не более чем на `diff_chars`, 
	// то они похожи. Если нет, то не похожи
	auto length = max(left.length(), right.length());
	return ((length - similar_chars) <= diff_chars);
}


/* Структура для хранения информации о человеке - фамилия и возраст */
struct Person{
	string name; // Я назвал поле `name`, а не `last_name`, но думаю, что это не принципиально
	uint age;

	/*
	Перегружаем оператор сравнения для удобства.
	В рамках этой задачи можно считать, что два объекта `Person`
	будут равны, если их фамилии похожи.

	Теперь можно писать `p == q` вместо `isSimilar(p.name, q.name)`
	*/
	bool operator ==(const Person& other) const {
	    return isSimilar(this->name, other.name);
	}

	// Здесь я перегружаю операторы ввода-вывода просто для удобства.
	friend ostream& operator<<(ostream& os, const Person& obj) {
		os << obj.name << " (" << obj.age << " y/o)";
		return os;
	}

	friend istream& operator>>(istream& is, Person& obj) {
		is >> obj.name >> obj.age;
		return is;
	}
};


int main(int argc, char** argv) {
	//Читаем количество людей, которое будет вводить пользователь
	int c;
	cin >> c;

	//Создаем массив, чтобы их хранить (см. `struct Person` выше)
	auto p = new Person[c];
	//Читаем 
	for(auto i = 0; i < c; i++) {
		cin >> p[i];
	}

	//Сравниваем людей "каждый с каждым", чтобы найти похожих
	for(auto i = 0; i < c; i++) {
		for(auto j = i+1; j < c; j++) { //здесь j = i+1 чтобы не сравнивать с самим собой			
			if (p[i] == p[j]) { // оператор "==" здесь НЕ означет "равно", см. перегруженный оператор в `Person`
				cout << p[i] << " ~= " << p[j] << endl; // Если похожи - выводим на экран
			}
		}
	}

	/*Подчищаем за собой*/
	delete[] p;
	return EXIT_SUCCESS;
}