using
System;
using
System.Collections.Generic;
public
class
Graph {
int
V;
List<List<
int
> > adj;
public
Graph(
int
V)
{
this
.V = V;
adj =
new
List<List<
int
> >();
for
(
int
i = 0; i < V; i++) {
adj.Add(
new
List<
int
>());
}
}
void
DFSUtil(
int
v,
bool
[] visited)
{
visited[v] =
true
;
foreach
(
int
i
in
adj[v])
{
if
(!visited[i]) {
DFSUtil(i, visited);
}
}
}
Graph GetTranspose()
{
Graph g =
new
Graph(V);
for
(
int
v = 0; v < V; v++) {
foreach
(
int
i
in
adj[v]) { g.adj[i].Add(v); }
}
return
g;
}
void
AddEdge(
int
v,
int
w) { adj[v].Add(w); }
void
FillOrder(
int
v,
bool
[] visited, Stack<
int
> stack)
{
visited[v] =
true
;
foreach
(
int
i
in
adj[v])
{
if
(!visited[i]) {
FillOrder(i, visited, stack);
}
}
stack.Push(v);
}
void
CountSCCs()
{
Stack<
int
> stack =
new
Stack<
int
>();
bool
[] visited =
new
bool
[V];
for
(
int
i = 0; i < V; i++) {
visited[i] =
false
;
}
for
(
int
i = 0; i < V; i++) {
if
(!visited[i]) {
FillOrder(i, visited, stack);
}
}
Graph gr = GetTranspose();
for
(
int
i = 0; i < V; i++) {
visited[i] =
false
;
}
int
cnt = 0;
while
(stack.Count > 0) {
int
v = stack.Peek();
stack.Pop();
if
(!visited[v]) {
gr.DFSUtil(v, visited);
cnt++;
}
}
Console.WriteLine(cnt);
}
public
static
void
Solve(List<
string
> A,
List<List<
string
> > P)
{
Graph g =
new
Graph(A.Count);
Dictionary<
string
,
int
> um
=
new
Dictionary<
string
,
int
>();
for
(
int
i = 0; i < A.Count; i++) {
um[A[i]] = i;
}
for
(
int
i = 0; i < P.Count; i++) {
int
x = um[P[i][0]];
int
y = um[P[i][1]];
g.AddEdge(x, y);
}
g.CountSCCs();
}
static
void
Main(
string
[] args)
{
List<
string
> A
=
new
List<
string
>{
"geeks"
,
"for"
,
"code"
,
"run"
,
"compile"
};
List<List<
string
> > P =
new
List<List<
string
> >{
new
List<
string
>{
"geeks"
,
"for"
},
new
List<
string
>{
"for"
,
"code"
},
new
List<
string
>{
"code"
,
"run"
},
new
List<
string
>{
"run"
,
"compile"
},
new
List<
string
>{
"run"
,
"for"
},
};
Solve(A, P);
}
}