#include <bits/stdc++.h> 
using namespace std; 

class Graph{ 
	public: 
	int n; int m; 
	int maxEdges;
	bool isDirected; 
	
	vector<vector<int>> adj;
	// int **adj;
	
	Graph(int nodes, bool isDiGraph) : adj(nodes, vector<int>(nodes)){ 
		n = nodes;
		m = 0;
		isDirected = isDiGraph; 
		maxEdges = isDirected ? n*(n-1) : n*(n-1)/2;
		
		// adj = new int*[n];
		
		// for(int i = 0; i < n; ++i)
		//     adj[i] = new int[n];
	}
	
	void insertEdge(int u, int v){ 
		
		if(u >= n || v >=n || u < 0 || v < 0){ 
			cout<<"Either of the vertices doesn't exists in the graph.\n";
			return;
		}
		
		if(m == maxEdges){ 
			cout<<"Maximum allowed edges are already in the graph. Can't insert more.\n";
			return; 
		}
		
		adj[u][v] = 1; ++m; 
		
		if(!isDirected) 
			adj[v][u] = 1; 
	} 
	
	void deleteEdge(int u, int v){ 
		
		if(u >= n || v >=n || u < 0 || v < 0){
			cout<<"Either of the vertices doesn't exists in the graph.\n";
			return;
		}
		
		if(!adj[u][v]){ 
			cout<<"The edge doesn't exists in the graph.\n"; return; 
		} 
		
		adj[u][v] = 0; --m; 
		
		if(!isDirected)
			adj[v][u] = 0; 
		
	} 
	
	void displayGraph(){ 
		
		if(!m){ 
			cout<<"The graph is empty!!"; return;
		} 
		
		cout<<"Total # edges in the graph: "<<m<<"\n";
		
		for(int i = 0; i < n; ++i){ 
			cout<<"The edges from vertex "<<i<<":";
			
			for(int j = 0; j < n; ++j) 
				if(adj[i][j]) 
					cout<<"->"<<j;
					
			cout<<"\n"; 
		} 
	} 
	
};

int main() { 
	int opt, isDir, src, dest; 
	
	cin>>opt;
	cout<<"Please enter # vertices in the graph: "<<opt<<"\n"; 
	cin>>isDir;
	cout<<"Is the graph directed(1/0)? "<<isDir<<"\n"; 
	
	Graph g(opt, isDir); 
	
	cout<<"Operations available on graph:\n"; 
	cout<<"1. Insert an edge\n2. Delete an edge\n3. Print graph\n4. Exit\n"; 
	cout<<"****************************************************\n"; 
	while(true){ 
		cin>>opt; 
		switch(opt){ 
			case 1:
				cin>>src>>dest; 
				cout<<"Enter the source and destination to insert edge,\n"
				"Source: " <<src<<" Destination: "<<dest<<"\n"; g.insertEdge(src, dest); 
				break;
			case 2:
				cin>>src>>dest;
				cout<<"Enter the source and destination to delete edge,\n"
				"Source: " <<src<<" Destination: "<<dest<<"\n"; g.deleteEdge(src, dest);
				break;
			case 3: 
				g.displayGraph();
				break;
			case 4:
				exit(0);
		} 
		cout<<"****************************************************\n";
	} 
	
	return 0;
}