//#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include "september.h"
using namespace std;
const int sz=100001,INF=1000000000;
vector<int>parent(sz);
int get(int num)
{
if(parent[num]<0)
{
return num;
}
else
{
parent[num]=get(parent[num]);
return get(parent[num]);
}
}
void unite(int num1,int num2)
{
int res1=get(num1),res2=get(num2);
if(res1!=res2)
{
if(parent[res1]>parent[res2])
{
swap(res1,res2);
}
parent[res1]+=parent[res2],parent[res2]=res1;
}
}
int solve(int n,int m,vector<int>Nums,vector<vector<int>>nums)
{
fill(parent.begin(),parent.end(),-1);
int cnt,idx,lstIdx;
bool flag;
set<int>nodes,res;
map<int,vector<int>>Res;
for(int i=0;i<nums.size();i++)
{
Res.clear(),cnt=0,idx=0,lstIdx=0;
while(idx<nums[i].size())
{
nodes.clear(),flag=false;
for(int j=lstIdx;j<=idx;j++)
{
nodes.insert(nums[i][j]);
}
for(int j=idx+1;j<nums[i].size();j++)
{
if(nodes.find(Nums[nums[i][j]])!=nodes.end())
{
flag=true;
break;
}
}
if(!flag)
{
cnt++;
for(int j=lstIdx;j<=idx;j++)
{
Res[cnt].push_back(nums[i][j]);
}
lstIdx=idx+1;
}
idx++;
}
for(auto RES:Res)
{
for(int j=0;j<RES.second.size()-1;j++)
{
unite(RES.second[j],RES.second[j+1]);
}
}
}
for(int i=1;i<=n-1;i++)
{
res.insert(get(i));
}
return res.size();
}