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

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

// Использует ассоциативные массивы.
// Медленное (сортировка перед выводом).

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

    static HashMap<String, HashSet<String>> hash = new HashMap<String, HashSet<String>>();

    static boolean add(String site, String keyword) {
        HashSet<String> sites = hash.get(keyword);
        if (sites == null) {
            sites = new HashSet<String>();
            hash.put(keyword, sites);            
        }
        if (sites.contains(site)) return false;
        sites.add(site);
        return true;
    }

    static boolean remove(String site, String keyword) {
        HashSet<String> sites = hash.get(keyword);
        if (sites == null) return false;
        if (!sites.contains(site)) return false;
        sites.remove(site);
        return true;        
    }

    static ArrayList<String> search(String keyword) {
        HashSet<String> sites = hash.get(keyword);
        if (sites == null) return new ArrayList<String>();
        return new ArrayList<String> (sites);
    }

    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");

                ArrayList<String> found = search(keyword);
                Collections.sort(found);

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

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