import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
public class Main {
private RoomNode[] rooms;
private final int passages;
private long noOfPairsWhichHaveDraughts = 0;
private long noOfRoomsWithAtleastOneDraught = 0;
String[] roomAndPassage
= in.
readLine().
split(" "); int noOfRooms
= Integer.
parseInt(roomAndPassage
[0]); passages
= Integer.
parseInt(roomAndPassage
[1]); rooms = new RoomNode[noOfRooms];
setRoomsWithOpenWindows(in);
setPairsWithDraughts(in);
findSolution();
}
int i = 0;
String[] line
= in.
readLine().
split(" ");
for (String roomToken
: line
) { boolean openWindow
= Integer.
parseInt(roomToken
) == 1? true:false; rooms[i] = new RoomNode(openWindow);
i++;
if (i>=rooms.length) {break;}
}
}
int i = 0;
while((line = in.readLine()) != null && !line.isEmpty() && i < passages) {
String[] lineTokens
= line.
split(" "); RoomNode room1
= rooms
[Integer.
parseInt(lineTokens
[0]) - 1]; RoomNode room2
= rooms
[Integer.
parseInt(lineTokens
[1]) - 1]; room1.links.add(room2);
room2.parent = room1;
i++;
}
}
private void findSolution() {
prune();
Deque<RoomNode> stack = new ArrayDeque<>();
for (RoomNode room: rooms) {
if (room.visited || !room.openWindow) {continue;}
int openCount = 0;
int draughts = 0;
stack.clear();
stack.push(room);
while(!stack.isEmpty()) {
RoomNode node = stack.pop();
if (node.visited) {continue;}
if (node.parent != null) {stack.add(node.parent);}
if (node.openWindow) {openCount++;}
draughts++;
stack.addAll(node.links);
node.visited = true;
}
if (openCount > 1) {
noOfPairsWhichHaveDraughts += ((openCount * (openCount-1))/2);
noOfRoomsWithAtleastOneDraught += draughts;
}
}
}
private void prune() {
Deque<RoomNode> stack = new ArrayDeque<>();
for (RoomNode room: rooms) {
if(room.openWindow || room.links.size() > 1) {continue;}
stack.push(room);
while(!stack.isEmpty()) {
RoomNode node = stack.pop();
if(node.openWindow || node.links.size() > 1) {continue;}
if(!node.links.isEmpty() && node.parent == null) {
node.links.get(0).parent = null;
}
if(node.parent != null && node.links.isEmpty()) {
node.parent.links.remove(node);
stack.push(node.parent);
}
}
}
}
return noOfPairsWhichHaveDraughts + " " + noOfRoomsWithAtleastOneDraught;
}
public static void main
(String[] args
) { Main draughts;
draughts = new Main(in);
System.
out.
println(draughts.
getSolution()); e.printStackTrace();
}
}
private class RoomNode {
private final boolean openWindow;
private final ArrayList<RoomNode> links = new ArrayList<>();
private RoomNode parent;
private boolean visited;
public RoomNode (boolean openWindow) {
this.openWindow = openWindow;
visited = false;
parent = null;
}
}
}