<p>On a social network consisting of <code>m</code> users and some friendships between users, two users can communicate with each other if they know a common language.</p>

<p>You are given an integer <code>n</code>, an array <code>languages</code>, and an array <code>friendships</code> where:</p>

<ul>
	<li>There are <code>n</code> languages numbered <code>1</code> through <code>n</code>,</li>
	<li><code>languages[i]</code> is the set of languages the <code>i<sup>​​​​​​th</sup></code>​​​​ user knows, and</li>
	<li><code>friendships[i] = [u<sub>​​​​​​i</sub>​​​, v<sub>​​​​​​i</sub>]</code> denotes a friendship between the users <code>u<sup>​​​​​</sup><sub>​​​​​​i</sub></code>​​​​​ and <code>v<sub>i</sub></code>.</li>
</ul>

<p>You can choose <strong>one</strong> language and teach it to some users so that all friends can communicate with each other. Return <i data-stringify-type="italic">the</i> <i><strong>minimum</strong> </i><i data-stringify-type="italic">number of users you need to teach.</i></p>
Note that friendships are not transitive, meaning if <code>x</code> is a friend of <code>y</code> and <code>y</code> is a friend of <code>z</code>, this doesn&#39;t guarantee that <code>x</code> is a friend of <code>z</code>.
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> n = 2, languages = [[1],[2],[1,2]], friendships = [[1,2],[1,3],[2,3]]
<strong>Output:</strong> 1
<strong>Explanation:</strong> You can either teach user 1 the second language or user 2 the first language.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> n = 3, languages = [[2],[1,3],[1,2],[3]], friendships = [[1,4],[1,2],[3,4],[2,3]]
<strong>Output:</strong> 2
<strong>Explanation:</strong> Teach the third language to users 1 and 3, yielding two users to teach.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>2 &lt;= n &lt;= 500</code></li>
	<li><code>languages.length == m</code></li>
	<li><code>1 &lt;= m &lt;= 500</code></li>
	<li><code>1 &lt;= languages[i].length &lt;= n</code></li>
	<li><code>1 &lt;= languages[i][j] &lt;= n</code></li>
	<li><code>1 &lt;= u<sub>​​​​​​i</sub> &lt; v<sub>​​​​​​i</sub> &lt;= languages.length</code></li>
	<li><code>1 &lt;= friendships.length &lt;= 500</code></li>
	<li>All tuples <code>(u<sub>​​​​​i, </sub>v<sub>​​​​​​i</sub>)</code> are unique</li>
	<li><code>languages[i]</code> contains only unique values</li>
</ul>

class Solution {
public:
    int minimumTeachings(int n, vector<vector<int>>& lang, vector<vector<int>>& friendships) {
        int mn = INT_MAX;
        for(auto& l: lang) sort(l.begin(),l.end());
        for(int i = 1; i<=n; i++){
            unordered_set<int> st{};
            for(auto const& fship: friendships){
                int f1 = fship[0]-1;
                int f2 = fship[1]-1;
                if(st.count(f1)+st.count(f2)==2) continue;

                int l = 1;
                int index1 = 0; 
                int index2 = 0;
                while(index1<lang[f1].size() && index2<lang[f2].size() && lang[f1][index1]!=lang[f2][index2]){
                    if(lang[f1][index1]<lang[f2][index2])
                        index1 = lower_bound(lang[f1].begin()+index1, lang[f1].end(), lang[f2][index2]) - lang[f1].begin();
                    else
                        index2 = lower_bound(lang[f2].begin()+index2, lang[f2].end(), lang[f1][index1]) - lang[f2].begin();
                }
                if(index1==lang[f1].size() || index2==lang[f2].size()){
                    auto it2 = lower_bound(lang[f2].begin(), lang[f2].end(), i);
                    if(it2==lang[f2].end() || (*it2)!=i) st.insert(f2); 
                    auto it1 = lower_bound(lang[f1].begin(), lang[f1].end(), i);
                    if(it1==lang[f1].end() || (*it1)!=i) st.insert(f1);
                }
            }
            mn = min(mn, (int)st.size());
        }
        return mn;
    }
};
68800