/* 图使用向量数组保存,注意初始化edge
* 每个点对应的 最大分量的序号 保存在sccNub中
* 可以增加一个vector 存储每个 最大分量中的点
* 所有下标都是 1 ~ n
*/
const int SIZE_N = 10050;
vector <int> Edge[SIZE_N];
int pre[SIZE_N] ,
lowlink[SIZE_N] ,
sccNub[SIZE_N] , //每个点对应的最大分量的序号
dfs_clock,
sccCnt; // 最大联通分量的个数
int sccNubCnt[SIZE_N];
stack<int> ST;
int n,m;
//for (int i = 1;i <= n;++i) Edge[i].clear();
inline void init(){
sccCnt = dfs_clock = 0;
memset(pre , 0 , sizeof(pre));
memset( sccNub , 0 , sizeof(sccNub) );
memset( sccNubCnt , 0 , sizeof(sccNubCnt));
while(!ST.empty()) ST.pop();
}
void Tarjan( int u ){
pre[u] = lowlink[u] = ++dfs_clock;
ST.push(u);
for (int i = 0; i < Edge[u].size();++i ){
int v = Edge[u][i];
if ( !pre[v] ){
Tarjan(v);
lowlink[u] = min( lowlink[u] , lowlink[v]);
}else if ( !sccNub[v] )
lowlink[u] = min( lowlink[u] , pre[v] );
}
if ( lowlink[u] == pre[u] ){
sccCnt++;
while ( 1 ){
int x = ST.top() ; ST.pop();
sccNub[x] = sccCnt;
//sccNubCnt[sccCnt]++;
if ( x == u ) break;
}
}
}
void solve(){
init();
for (int i = 1;i <= n ;++i )
if ( !pre[i] ) Tarjan(i);
}
for (int i = 1;i <= n;++i) Edge[i].clear();