

from collections import deque
from math import floor
from random import random
from time import time

class 				a  :


						def __init__(       self	):







										'''simple docstring'''


										_UpperCAmelCase       :		str 		=    {}


						def        _UpperCAmelCase				(       self						,					A_						,					A_						,					A_=1	):







										'''simple docstring'''


										if self.graph.get(lowerCamelCase_	):
														if self.graph[u].count([w, v]	) == 0:
																		self.graph[u].append([w, v]	)
										else:
														_UpperCAmelCase       :		str 		=    [[w, v]]
										if not self.graph.get(lowerCamelCase_	):
														_UpperCAmelCase       :		Tuple 		=    []


						def        _UpperCAmelCase				(       self	):







										'''simple docstring'''


										return list(self.graph	)


						def        _UpperCAmelCase				(       self						,					A_						,					A_	):







										'''simple docstring'''


										if self.graph.get(lowerCamelCase_	):
														for _ in self.graph[u]:
																		if _[1] == v:
																						self.graph[u].remove(lowerCamelCase_	)


						def        _UpperCAmelCase				(       self						,					A_=-2						,					A_=-1	):







										'''simple docstring'''


										if s == d:
														return []
										_UpperCAmelCase       :		List[str] 		=    []
										_UpperCAmelCase       :		List[str] 		=    []
										if s == -2:
														_UpperCAmelCase       :		Tuple 		=    list(self.graph	)[0]
										stack.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										_UpperCAmelCase       :		Any 		=    s

										while True:
														# check if there is any non isolated nodes
														if len(self.graph[s]	) != 0:
																		_UpperCAmelCase       :		Optional[Any] 		=    s
																		for node in self.graph[s]:
																						if visited.count(node[1]	) < 1:
																										if node[1] == d:
																														visited.append(lowerCamelCase_	)
																														return visited
																										else:
																														stack.append(node[1]	)
																														visited.append(node[1]	)
																														_UpperCAmelCase       :		Tuple 		=    node[1]
																														break

            # check if all the children are visited
														if s == ss:
																		stack.pop()
																		if len(lowerCamelCase_	) != 0:
																						_UpperCAmelCase       :		int 		=    stack[len(lowerCamelCase_	) - 1]
														else:
																		_UpperCAmelCase       :		Any 		=    ss

														# check if se have reached the starting point
														if len(lowerCamelCase_	) == 0:
																		return visited


						def        _UpperCAmelCase				(       self						,					A_=-1	):







										'''simple docstring'''


										if c == -1:
														_UpperCAmelCase       :		str 		=    floor(random() * 10000	) + 10
										for i in range(lowerCamelCase_	):
														# every vertex has max 100 edges
														for _ in range(floor(random() * 102	) + 1	):
																		_UpperCAmelCase       :		Union[str, Any] 		=    floor(random() * c	) + 1
																		if n != i:
																						self.add_pair(lowerCamelCase_						,					lowerCamelCase_						,					1	)


						def        _UpperCAmelCase				(       self						,					A_=-2	):







										'''simple docstring'''


										_UpperCAmelCase       :		str 		=    deque()
										_UpperCAmelCase       :		List[str] 		=    []
										if s == -2:
														_UpperCAmelCase       :		int 		=    list(self.graph	)[0]
										d.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										while d:
														_UpperCAmelCase       :		Dict 		=    d.popleft()
														if len(self.graph[s]	) != 0:
																		for node in self.graph[s]:
																						if visited.count(node[1]	) < 1:
																										d.append(node[1]	)
																										visited.append(node[1]	)
										return visited


						def        _UpperCAmelCase				(       self						,					A_	):







										'''simple docstring'''


										_UpperCAmelCase       :		Dict 		=    0
										for x in self.graph:
														for y in self.graph[x]:
																		if y[1] == u:
																						count += 1
										return count


						def        _UpperCAmelCase				(       self						,					A_	):







										'''simple docstring'''


										return len(self.graph[u]	)


						def        _UpperCAmelCase				(       self						,					A_=-2	):







										'''simple docstring'''


										_UpperCAmelCase       :		List[Any] 		=    []
										_UpperCAmelCase       :		List[str] 		=    []
										if s == -2:
														_UpperCAmelCase       :		Union[str, Any] 		=    list(self.graph	)[0]
										stack.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										_UpperCAmelCase       :		Union[str, Any] 		=    s
										_UpperCAmelCase       :		List[str] 		=    []

										while True:
														# check if there is any non isolated nodes
														if len(self.graph[s]	) != 0:
																		_UpperCAmelCase       :		Optional[Any] 		=    s
																		for node in self.graph[s]:
																						if visited.count(node[1]	) < 1:
																										stack.append(node[1]	)
																										visited.append(node[1]	)
																										_UpperCAmelCase       :		int 		=    node[1]
																										break

            # check if all the children are visited
														if s == ss:
																		sorted_nodes.append(stack.pop()	)
																		if len(lowerCamelCase_	) != 0:
																						_UpperCAmelCase       :		List[Any] 		=    stack[len(lowerCamelCase_	) - 1]
														else:
																		_UpperCAmelCase       :		int 		=    ss

														# check if se have reached the starting point
														if len(lowerCamelCase_	) == 0:
																		return sorted_nodes


						def        _UpperCAmelCase				(       self	):







										'''simple docstring'''


										_UpperCAmelCase       :		List[Any] 		=    []
										_UpperCAmelCase       :		Any 		=    []
										_UpperCAmelCase       :		List[Any] 		=    list(self.graph	)[0]
										stack.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										_UpperCAmelCase       :		Any 		=    -2
										_UpperCAmelCase       :		int 		=    []
										_UpperCAmelCase       :		Union[str, Any] 		=    s
										_UpperCAmelCase       :		Tuple 		=    False
										_UpperCAmelCase       :		Union[str, Any] 		=    set()

										while True:
														# check if there is any non isolated nodes
														if len(self.graph[s]	) != 0:
																		_UpperCAmelCase       :		Union[str, Any] 		=    s
																		for node in self.graph[s]:
																						if (
																						    visited.count(node[1]	) > 0
																						    and node[1] != parent
																						    and indirect_parents.count(node[1]	) > 0
																						    and not on_the_way_back
																						):
																										_UpperCAmelCase       :		Any 		=    len(lowerCamelCase_	) - 1
																										while len_stack >= 0:
																														if stack[len_stack] == node[1]:
																																		anticipating_nodes.add(node[1]	)
																																		break
																														else:
																																		anticipating_nodes.add(stack[len_stack]	)
																																		len_stack -= 1
																						if visited.count(node[1]	) < 1:
																										stack.append(node[1]	)
																										visited.append(node[1]	)
																										_UpperCAmelCase       :		int 		=    node[1]
																										break

            # check if all the children are visited
														if s == ss:
																		stack.pop()
																		_UpperCAmelCase       :		int 		=    True
																		if len(lowerCamelCase_	) != 0:
																						_UpperCAmelCase       :		Any 		=    stack[len(lowerCamelCase_	) - 1]
														else:
																		_UpperCAmelCase       :		List[str] 		=    False
																		indirect_parents.append(lowerCamelCase_	)
																		_UpperCAmelCase       :		List[Any] 		=    s
																		_UpperCAmelCase       :		List[Any] 		=    ss

														# check if se have reached the starting point
														if len(lowerCamelCase_	) == 0:
																		return list(lowerCamelCase_	)


						def        _UpperCAmelCase				(       self	):







										'''simple docstring'''


										_UpperCAmelCase       :		Tuple 		=    []
										_UpperCAmelCase       :		int 		=    []
										_UpperCAmelCase       :		Any 		=    list(self.graph	)[0]
										stack.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										_UpperCAmelCase       :		Union[str, Any] 		=    -2
										_UpperCAmelCase       :		List[Any] 		=    []
										_UpperCAmelCase       :		Tuple 		=    s
										_UpperCAmelCase       :		Dict 		=    False
										_UpperCAmelCase       :		Optional[Any] 		=    set()

										while True:
														# check if there is any non isolated nodes
														if len(self.graph[s]	) != 0:
																		_UpperCAmelCase       :		str 		=    s
																		for node in self.graph[s]:
																						if (
																						    visited.count(node[1]	) > 0
																						    and node[1] != parent
																						    and indirect_parents.count(node[1]	) > 0
																						    and not on_the_way_back
																						):
																										_UpperCAmelCase       :		str 		=    len(lowerCamelCase_	) - 1
																										while len_stack_minus_one >= 0:
																														if stack[len_stack_minus_one] == node[1]:
																																		anticipating_nodes.add(node[1]	)
																																		break
																														else:
																																		return True
																						if visited.count(node[1]	) < 1:
																										stack.append(node[1]	)
																										visited.append(node[1]	)
																										_UpperCAmelCase       :		Optional[Any] 		=    node[1]
																										break

            # check if all the children are visited
														if s == ss:
																		stack.pop()
																		_UpperCAmelCase       :		Dict 		=    True
																		if len(lowerCamelCase_	) != 0:
																						_UpperCAmelCase       :		List[str] 		=    stack[len(lowerCamelCase_	) - 1]
														else:
																		_UpperCAmelCase       :		List[Any] 		=    False
																		indirect_parents.append(lowerCamelCase_	)
																		_UpperCAmelCase       :		Optional[int] 		=    s
																		_UpperCAmelCase       :		Optional[int] 		=    ss

														# check if se have reached the starting point
														if len(lowerCamelCase_	) == 0:
																		return False


						def        _UpperCAmelCase				(       self						,					A_=-2						,					A_=-1	):







										'''simple docstring'''


										_UpperCAmelCase       :		Optional[Any] 		=    time()
										self.dfs(lowerCamelCase_						,					lowerCamelCase_	)
										_UpperCAmelCase       :		List[str] 		=    time()
										return end - begin





						def        _UpperCAmelCase				(       self						,					A_=-2	):







										'''simple docstring'''


										_UpperCAmelCase       :		Optional[int] 		=    time()
										self.bfs(lowerCamelCase_	)
										_UpperCAmelCase       :		List[str] 		=    time()
										return end - begin







class 				a  :


						def __init__(       self	):







										'''simple docstring'''


										_UpperCAmelCase       :		Tuple 		=    {}


						def        _UpperCAmelCase				(       self						,					A_						,					A_						,					A_=1	):







										'''simple docstring'''


										if self.graph.get(lowerCamelCase_	):
														# if there already is a edge
														if self.graph[u].count([w, v]	) == 0:
																		self.graph[u].append([w, v]	)
										else:
														# if u does not exist
														_UpperCAmelCase       :		Any 		=    [[w, v]]
										# add the other way
										if self.graph.get(lowerCamelCase_	):
														# if there already is a edge
														if self.graph[v].count([w, u]	) == 0:
																		self.graph[v].append([w, u]	)
										else:
														# if u does not exist
														_UpperCAmelCase       :		Any 		=    [[w, u]]


						def        _UpperCAmelCase				(       self						,					A_						,					A_	):







										'''simple docstring'''


										if self.graph.get(lowerCamelCase_	):
														for _ in self.graph[u]:
																		if _[1] == v:
																						self.graph[u].remove(lowerCamelCase_	)
        # the other way round
										if self.graph.get(lowerCamelCase_	):
														for _ in self.graph[v]:
																		if _[1] == u:
																						self.graph[v].remove(lowerCamelCase_	)


						def        _UpperCAmelCase				(       self						,					A_=-2						,					A_=-1	):







										'''simple docstring'''


										if s == d:
														return []
										_UpperCAmelCase       :		List[str] 		=    []
										_UpperCAmelCase       :		Any 		=    []
										if s == -2:
														_UpperCAmelCase       :		List[Any] 		=    list(self.graph	)[0]
										stack.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										_UpperCAmelCase       :		List[str] 		=    s

										while True:
														# check if there is any non isolated nodes
														if len(self.graph[s]	) != 0:
																		_UpperCAmelCase       :		Union[str, Any] 		=    s
																		for node in self.graph[s]:
																						if visited.count(node[1]	) < 1:
																										if node[1] == d:
																														visited.append(lowerCamelCase_	)
																														return visited
																										else:
																														stack.append(node[1]	)
																														visited.append(node[1]	)
																														_UpperCAmelCase       :		Any 		=    node[1]
																														break

            # check if all the children are visited
														if s == ss:
																		stack.pop()
																		if len(lowerCamelCase_	) != 0:
																						_UpperCAmelCase       :		Any 		=    stack[len(lowerCamelCase_	) - 1]
														else:
																		_UpperCAmelCase       :		List[str] 		=    ss

														# check if se have reached the starting point
														if len(lowerCamelCase_	) == 0:
																		return visited


						def        _UpperCAmelCase				(       self						,					A_=-1	):







										'''simple docstring'''


										if c == -1:
														_UpperCAmelCase       :		Any 		=    floor(random() * 10000	) + 10
										for i in range(lowerCamelCase_	):
														# every vertex has max 100 edges
														for _ in range(floor(random() * 102	) + 1	):
																		_UpperCAmelCase       :		List[str] 		=    floor(random() * c	) + 1
																		if n != i:
																						self.add_pair(lowerCamelCase_						,					lowerCamelCase_						,					1	)


						def        _UpperCAmelCase				(       self						,					A_=-2	):







										'''simple docstring'''


										_UpperCAmelCase       :		List[Any] 		=    deque()
										_UpperCAmelCase       :		Tuple 		=    []
										if s == -2:
														_UpperCAmelCase       :		Any 		=    list(self.graph	)[0]
										d.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										while d:
														_UpperCAmelCase       :		List[Any] 		=    d.popleft()
														if len(self.graph[s]	) != 0:
																		for node in self.graph[s]:
																						if visited.count(node[1]	) < 1:
																										d.append(node[1]	)
																										visited.append(node[1]	)
										return visited


						def        _UpperCAmelCase				(       self						,					A_	):







										'''simple docstring'''


										return len(self.graph[u]	)


						def        _UpperCAmelCase				(       self	):







										'''simple docstring'''


										_UpperCAmelCase       :		List[str] 		=    []
										_UpperCAmelCase       :		Any 		=    []
										_UpperCAmelCase       :		Optional[Any] 		=    list(self.graph	)[0]
										stack.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										_UpperCAmelCase       :		Optional[int] 		=    -2
										_UpperCAmelCase       :		Tuple 		=    []
										_UpperCAmelCase       :		Any 		=    s
										_UpperCAmelCase       :		Optional[Any] 		=    False
										_UpperCAmelCase       :		Optional[Any] 		=    set()

										while True:
														# check if there is any non isolated nodes
														if len(self.graph[s]	) != 0:
																		_UpperCAmelCase       :		Optional[Any] 		=    s
																		for node in self.graph[s]:
																						if (
																						    visited.count(node[1]	) > 0
																						    and node[1] != parent
																						    and indirect_parents.count(node[1]	) > 0
																						    and not on_the_way_back
																						):
																										_UpperCAmelCase       :		Optional[Any] 		=    len(lowerCamelCase_	) - 1
																										while len_stack >= 0:
																														if stack[len_stack] == node[1]:
																																		anticipating_nodes.add(node[1]	)
																																		break
																														else:
																																		anticipating_nodes.add(stack[len_stack]	)
																																		len_stack -= 1
																						if visited.count(node[1]	) < 1:
																										stack.append(node[1]	)
																										visited.append(node[1]	)
																										_UpperCAmelCase       :		str 		=    node[1]
																										break

            # check if all the children are visited
														if s == ss:
																		stack.pop()
																		_UpperCAmelCase       :		Optional[int] 		=    True
																		if len(lowerCamelCase_	) != 0:
																						_UpperCAmelCase       :		int 		=    stack[len(lowerCamelCase_	) - 1]
														else:
																		_UpperCAmelCase       :		Union[str, Any] 		=    False
																		indirect_parents.append(lowerCamelCase_	)
																		_UpperCAmelCase       :		List[str] 		=    s
																		_UpperCAmelCase       :		str 		=    ss

														# check if se have reached the starting point
														if len(lowerCamelCase_	) == 0:
																		return list(lowerCamelCase_	)


						def        _UpperCAmelCase				(       self	):







										'''simple docstring'''


										_UpperCAmelCase       :		Optional[Any] 		=    []
										_UpperCAmelCase       :		int 		=    []
										_UpperCAmelCase       :		Any 		=    list(self.graph	)[0]
										stack.append(lowerCamelCase_	)
										visited.append(lowerCamelCase_	)
										_UpperCAmelCase       :		Dict 		=    -2
										_UpperCAmelCase       :		int 		=    []
										_UpperCAmelCase       :		int 		=    s
										_UpperCAmelCase       :		Union[str, Any] 		=    False
										_UpperCAmelCase       :		Tuple 		=    set()

										while True:
														# check if there is any non isolated nodes
														if len(self.graph[s]	) != 0:
																		_UpperCAmelCase       :		Any 		=    s
																		for node in self.graph[s]:
																						if (
																						    visited.count(node[1]	) > 0
																						    and node[1] != parent
																						    and indirect_parents.count(node[1]	) > 0
																						    and not on_the_way_back
																						):
																										_UpperCAmelCase       :		Optional[Any] 		=    len(lowerCamelCase_	) - 1
																										while len_stack_minus_one >= 0:
																														if stack[len_stack_minus_one] == node[1]:
																																		anticipating_nodes.add(node[1]	)
																																		break
																														else:
																																		return True
																						if visited.count(node[1]	) < 1:
																										stack.append(node[1]	)
																										visited.append(node[1]	)
																										_UpperCAmelCase       :		Tuple 		=    node[1]
																										break

            # check if all the children are visited
														if s == ss:
																		stack.pop()
																		_UpperCAmelCase       :		Any 		=    True
																		if len(lowerCamelCase_	) != 0:
																						_UpperCAmelCase       :		str 		=    stack[len(lowerCamelCase_	) - 1]
														else:
																		_UpperCAmelCase       :		Optional[Any] 		=    False
																		indirect_parents.append(lowerCamelCase_	)
																		_UpperCAmelCase       :		Any 		=    s
																		_UpperCAmelCase       :		Tuple 		=    ss

														# check if se have reached the starting point
														if len(lowerCamelCase_	) == 0:
																		return False


						def        _UpperCAmelCase				(       self	):







										'''simple docstring'''


										return list(self.graph	)


						def        _UpperCAmelCase				(       self						,					A_=-2						,					A_=-1	):







										'''simple docstring'''


										_UpperCAmelCase       :		str 		=    time()
										self.dfs(lowerCamelCase_						,					lowerCamelCase_	)
										_UpperCAmelCase       :		Tuple 		=    time()
										return end - begin





						def        _UpperCAmelCase				(       self						,					A_=-2	):







										'''simple docstring'''


										_UpperCAmelCase       :		Optional[Any] 		=    time()
										self.bfs(lowerCamelCase_	)
										_UpperCAmelCase       :		Dict 		=    time()
										return end - begin





from __future__ import annotations

import pandas as pd

def 							__SCREAMING_SNAKE_CASE							(				lowerCAmelCase:  list[int]  ,      lowerCAmelCase:  list[int]  ,      lowerCAmelCase:  int )   ->       list[int]:
				_UpperCAmelCase       :		List[Any] 		=    [0] * no_of_processes
				_UpperCAmelCase       :		Dict 		=    [0] * no_of_processes
				# Copy the burst time into remaining_time[]
				for i in range(lowerCAmelCase ):
								_UpperCAmelCase       :		List[str] 		=    burst_time[i]

				_UpperCAmelCase       :		Any 		=    0
				_UpperCAmelCase       :		Union[str, Any] 		=    0
				_UpperCAmelCase       :		str 		=    9_9999_9999
				_UpperCAmelCase       :		List[Any] 		=    0
				_UpperCAmelCase       :		Any 		=    False

				# Process until all processes are completed
				while complete != no_of_processes:
								for j in range(lowerCAmelCase ):
												if arrival_time[j] <= increment_time and remaining_time[j] > 0:
																if remaining_time[j] < minm:
																				_UpperCAmelCase       :		Optional[int] 		=    remaining_time[j]
																				_UpperCAmelCase       :		int 		=    j
																				_UpperCAmelCase       :		Tuple 		=    True

								if not check:
												increment_time += 1
												continue
								remaining_time[short] -= 1

								_UpperCAmelCase       :		List[Any] 		=    remaining_time[short]
								if minm == 0:
												_UpperCAmelCase       :		List[Any] 		=    9_9999_9999

								if remaining_time[short] == 0:
												complete += 1
												_UpperCAmelCase       :		int 		=    False

												# Find finish time of current process
												_UpperCAmelCase       :		Optional[int] 		=    increment_time + 1

												# Calculate waiting time
												_UpperCAmelCase       :		str 		=    finish_time - arrival_time[short]
												_UpperCAmelCase       :		Union[str, Any] 		=    finar - burst_time[short]

												if waiting_time[short] < 0:
																_UpperCAmelCase       :		Optional[int] 		=    0

        # Increment time
								increment_time += 1
				return waiting_time

def 							__SCREAMING_SNAKE_CASE							(				lowerCAmelCase:  list[int]  ,      lowerCAmelCase:  int  ,      lowerCAmelCase:  list[int] )   ->       list[int]:
				_UpperCAmelCase       :		str 		=    [0] * no_of_processes
				for i in range(lowerCAmelCase ):
								_UpperCAmelCase       :		str 		=    burst_time[i] + waiting_time[i]
				return turn_around_time

def 							__SCREAMING_SNAKE_CASE							(				lowerCAmelCase:  list[int]  ,      lowerCAmelCase:  list[int]  ,      lowerCAmelCase:  int )   ->       None:
				_UpperCAmelCase       :		Dict 		=    0
				_UpperCAmelCase       :		List[str] 		=    0
				for i in range(lowerCAmelCase ):
								_UpperCAmelCase       :		Union[str, Any] 		=    total_waiting_time + waiting_time[i]
								_UpperCAmelCase       :		int 		=    total_turn_around_time + turn_around_time[i]
				print(F'Average waiting time = {total_waiting_time / no_of_processes:.5f}' )
				print("Average turn around time ="  ,      total_turn_around_time / no_of_processes )


if __name__ == "__main__":
					print('Enter how many process you want to analyze')
					SCREAMING_SNAKE_CASE_        =      int(input())
					SCREAMING_SNAKE_CASE_        =      [0] * no_of_processes
					SCREAMING_SNAKE_CASE_        =      [0] * no_of_processes
					SCREAMING_SNAKE_CASE_        =      list(range(1, no_of_processes + 1))

					for i in range(no_of_processes):
										print('Enter the arrival time and burst time for process:--' + str(i + 1))
										SCREAMING_SNAKE_CASE_    ,SCREAMING_SNAKE_CASE_        =      map(int, input().split())

					SCREAMING_SNAKE_CASE_        =      calculate_waitingtime(arrival_time, burst_time, no_of_processes)

					SCREAMING_SNAKE_CASE_        =      burst_time
					SCREAMING_SNAKE_CASE_        =      no_of_processes
					SCREAMING_SNAKE_CASE_        =      waiting_time
					SCREAMING_SNAKE_CASE_        =      calculate_turnaroundtime(bt, n, wt)

					calculate_average_times(waiting_time, turn_around_time, no_of_processes)

					SCREAMING_SNAKE_CASE_        =      pd.DataFrame(
					    list(zip(processes, burst_time, arrival_time, waiting_time, turn_around_time)),
					    columns=[
					        'Process',
					        'BurstTime',
					        'ArrivalTime',
					        'WaitingTime',
					        'TurnAroundTime',
					    ],
					)

					# Printing the dataFrame
					pd.set_option('display.max_rows', fcfs.shape[0] + 1)
					print(fcfs)


