import java.util.*;
import java.io.*;

// Задача "Ничего и не терялось"
// 8-ая Интернет-олимпиада сезона 2006-2007, базовый уровень
// Автор условия: Федор Царев, tsarev@rain.ifmo.ru
// Автор решения: Максим Буздалов, buzdalov@rain.ifmo.ru

// Использует массивы строк, хранимые в отсортированном виде.
// Использует сортировку вставками при добавлении строки в массив, чтобы избежать пересортировки при выводе.
// Быстрое.

public class giggle_mb_insertion {
    
    static void myAssert(boolean exp, String message) {
        if (!exp) throw new AssertionError(message);
    }

    static final int MAX_REQ = 2500;

    static String[] keywords = new String[MAX_REQ];
    static String[][] sites = new String[MAX_REQ][MAX_REQ];
    static int[] sizes = new int[MAX_REQ + 1];
    static int keyCount = 0;

    static int indexOfKeyword(String s) {
        for (int i = 0; i < MAX_REQ; i++) {
            if (keywords[i] == null) break;
            if (keywords[i].equals(s)) return i;
        }
        return -1;
    }

    static boolean contains(String[] array, String data) {
        for (int i = 0; i < array.length; i++) {
            if (array[i] == null) return false;
            if (array[i].equals(data)) return true;
        }
        return false;
    }

    static boolean add(String site, String keyword) {
        int iok = indexOfKeyword(keyword);
        if (iok == -1) {
            iok = keyCount++;
            keywords[iok] = keyword;
        }
        String[] siteList = sites[iok];
        if (contains(siteList, site)) return false;
        int last = sizes[iok];
        siteList[sizes[iok]++] = site;
        while (last > 0) {
            String first = siteList[last - 1];
            String second = siteList[last];
            if (first.compareTo(second) < 0) break;
            siteList[last] = first;
            siteList[last - 1] = second;
            last--;
        }
        return true;
    }

    static boolean remove(String site, String keyword) {
        int iok = indexOfKeyword(keyword);
        if (iok == -1) {
            return false;
        }
        String[] siteList = sites[iok];
        int iof = 0;
        for (; iof < sizes[iok]; iof++) {
            if (siteList[iof].equals(site)) break;
        }
        if (iof == sizes[iok]) return false;

        while (iof < sizes[iok] - 1) {
            String first = siteList[iof];
            String second = siteList[iof + 1];
            siteList[iof] = second;
            siteList[iof + 1] = first;
            iof++;
        }
        sizes[iok]--;
        return true;        
    }
    
    static int search(String keyword) {
        int iok = indexOfKeyword(keyword);
        if (iok == -1) return MAX_REQ;
        return iok;            
    }

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new FileReader("giggle.in"));
        PrintWriter out = new PrintWriter("giggle.out");

        int n = Integer.parseInt(in.readLine());

        for (int j = 0; j < n; j++) {
            StringTokenizer st = new StringTokenizer(in.readLine());
            String cmd = st.nextToken();
            if (cmd.equals("Add")) {
                myAssert(st.nextToken().equals("keyword"), "Add-format damaged");

                String keyword = st.nextToken();
                myAssert(keyword.charAt(0) == '"' && keyword.charAt(keyword.length() - 1) == '"' && keyword.length() > 2, "Wrong keyword input: " + keyword);

                myAssert(st.nextToken().equals("to"), "Add-format damaged");

                String site = st.nextToken();
                myAssert(!st.hasMoreTokens(), "Extra tokens");

                boolean reply = add(site, keyword);

                out.println(reply ? "OK" : "Already exists");
            } else if (cmd.equals("Remove")) {
                myAssert(st.nextToken().equals("keyword"), "Remove-format damaged");

                String keyword = st.nextToken();
                myAssert(keyword.charAt(0) == '"' && keyword.charAt(keyword.length() - 1) == '"' && keyword.length() > 2, "Wrong keyword input: " + keyword);

                myAssert(st.nextToken().equals("from"), "Remove-format damaged");

                String site = st.nextToken();
                myAssert(!st.hasMoreTokens(), "Extra tokens");

                boolean reply = remove(site, keyword);

                out.println(reply ? "OK" : "Not found");
            } else if (cmd.equals("Search")) {
                String keyword = st.nextToken();
                myAssert(keyword.charAt(0) == '"' && keyword.charAt(keyword.length() - 1) == '"' && keyword.length() > 2, "Wrong keyword input: " + keyword);
                myAssert(!st.hasMoreTokens(), "Extra tokens");

                int found = search(keyword);

                out.printf("Results: %d site(s) found\n", sizes[found]);
                for (int i = 0; i < sizes[found] && i < 10; i++) {
                    String siteAt = sites[found][i];
                    out.printf("%d) %s\n", i + 1, siteAt);
                }
            } else myAssert(false, "Unknown option: " + cmd);
            if (j != n - 1) {
                out.println("=====");
            }
        }

        out.close();
        in.close();
    }
}