Greedy Solution || O(m*n) || Faster than 60% || Clean code || Java
Complexity\n- Time complexity: O(mn)\n Add your time complexity here, e.g. O(n) \n\n- Space complexity: O(mn)\n Add your space complexity here, e.g. O(n) \n\n# 
# Complexity\n- Time complexity: $$O(m*n)$$\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity: $$O(m*n)$$\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\nimport java.util.*;\nimport java.util.stream.Collectors;\n\nclass Solution {\n    private final Map<Integer, Set<Integer>> langToPeople = new HashMap<>();\n    private int mostSpoken = -1;\n    private int mostSpokenCount = 0;\n    public int minimumTeachings(int n, int[][] languages, int[][] friendships) {\n        Map<Integer, Set<Integer>> peopleToLanguages = initLanguages(languages);  //O(n)\n        Set<Map.Entry<Integer,Integer>> cantSpeak = getRelationships(friendships, peopleToLanguages); //o(m*n)\n        int learners = 0;\n        for (Map.Entry<Integer, Integer> friends: cantSpeak) { //o(m)\n            Set<Integer> lang1 = peopleToLanguages.getOrDefault(friends.getKey(), new HashSet<>());\n            Set<Integer> lang2 = peopleToLanguages.getOrDefault(friends.getValue(), new HashSet<>());\n            learners += learnLanguage(peopleToLanguages, friends.getKey(), lang1);\n            learners += learnLanguage(peopleToLanguages, friends.getValue(), lang2);\n        }\n        return learners;\n    }\n\n    private Map<Integer, Set<Integer>> initLanguages(int[][] languages) {\n        Map<Integer, Set<Integer>> peopleToLanguages = new HashMap<>();\n        for (int i = 0; i < languages.length; i++) {\n            peopleToLanguages.put(i + 1, Arrays.stream(languages[i]).boxed().collect(Collectors.toSet()));\n        }\n        return peopleToLanguages;\n    }\n\n    private Set<Map.Entry<Integer,Integer>> getRelationships(int[][] friendships, Map<Integer, Set<Integer>> peopleToLanguages) {\n        Set<Map.Entry<Integer,Integer>> cantSpeak = new HashSet<>();\n        for (int[] friendship: friendships) {\n            Set<Integer> lang1 = peopleToLanguages.getOrDefault(friendship[0], new HashSet<>());\n            Set<Integer> lang2 = peopleToLanguages.getOrDefault(friendship[1], new HashSet<>());\n            if (Collections.disjoint(lang1, lang2)) {\n                cantSpeak.add(new AbstractMap.SimpleEntry<>(friendship[0], friendship[1]));\n                addPeopleToLang(friendship[0], lang1);\n                addPeopleToLang(friendship[1], lang2);\n            }\n        }\n        return cantSpeak;\n    }\n\n    private void addPeopleToLang(int friend, Set<Integer> languages) {\n        for (int lang: languages) {\n            langToPeople.computeIfAbsent(lang, e-> new HashSet<>()).add(friend);\n            if (mostSpokenCount < langToPeople.get(lang).size()) {\n                mostSpoken = lang;\n                mostSpokenCount = langToPeople.get(lang).size();\n            }\n        }\n    }\n\n    private int learnLanguage(Map<Integer, Set<Integer>> peopleToLanguages, int friend, Set<Integer> lang) {\n        if (!lang.contains(mostSpoken)) {\n            peopleToLanguages.computeIfAbsent(friend, e-> new HashSet<>()).add(mostSpoken);\n            return 1;\n        }\n        return 0;\n    }\n}\n```
['Java']