C# Beats 100% Space/Time
IntuitionUse dictionaries to simplify comparisons.
Don't double-count a users language needs.
Accumulate wanted languages when the user's can't speak.ApproachEa
# Intuition
Use dictionaries to simplify comparisons.
Don't double-count a users language needs.
Accumulate wanted languages when the user's can't speak.

# Approach
Each user has a bool[n] indicating what languages they speak.
Keep track of a user's wanted languages so we only count them once.
Accumulates the wanted language counts. 


# Complexity
- Time complexity:
$$O(m * n)$$

- Space complexity:
$$O(m * n)$$

# Code
```csharp []
public class Solution {
    public int MinimumTeachings(int n, int[][] languages, int[][] friendships) {
        
        // Each user has a bool[n] indicating what languages they speak.
        var userLangMaskDict = new Dictionary<int, bool[]>();

        // Keeps track of a user's wanted languages so we only count them once.
        var userLangHandledDict = new Dictionary<int, bool[]>();

        // Accumulates the wanted language counts. 
        var langWantedArr = new int[n];

        // Initialize Dictionaries.
        for (var i = 0; i < languages.Length; i++) {
            var userLanguages = languages[i];
            var langMask = new bool[n];
            foreach (var language in userLanguages) {
                langMask[language - 1] = true;
            }
            userLangMaskDict[i] = langMask;
            userLangHandledDict[i] = new bool[n];
        }

        // Iterate over friendships.
        foreach (var friendShip in friendships) {
            var u1 = friendShip[0] - 1;
            var u2 = friendShip[1] - 1;

            var langMask1 = userLangMaskDict[u1];
            var langMask2 = userLangMaskDict[u2];

            // Check if the users can speak.
            bool canSpeak = false;
            for (var i = 0; i < n; i++) {
                if (langMask1[i] && langMask2[i]) {
                    canSpeak = true;
                    break;
                }
            }

            // If the users can't speak, accumulate the languages they may need.
            // Only accumulate a language once per user.
            if (!canSpeak) {
                var langHandled1 = userLangHandledDict[u1];
                var langHandled2 = userLangHandledDict[u2];
                for (var i = 0; i < n; i++) {
                    if (!langHandled1[i] && !langMask1[i]) {
                        langWantedArr[i]++;
                        langHandled1[i] = true;
                    }
                    if (!langHandled2[i] && !langMask2[i]) {
                        langWantedArr[i]++;
                        langHandled2[i] = true;
                    }
                }
            }
        }

        var minUsers = int.MaxValue;
        for (var i = 0; i < n; i++) {
            minUsers = Math.Min(minUsers, langWantedArr[i]);
        }

        return minUsers;
    }
}

```
['C#']