#include <iostream>
#include <list>

using namespace std;

class Graph {
public:
  Graph(int n, bool directed);
  Graph(const Graph &g);
  Graph &operator=(const Graph &g); 
  ~Graph();
  void insertEdge(int a, int b);
  list<int> neighbors(int a);
  bool connected(int a, int b);
  int size();

private:
  int n;
  bool directed;
  list<int> *edges;
};

Graph::Graph(int n, bool directed) {
  this->n = n;
  this->directed = directed;
  this->edges = new list<int>[n];
}

Graph::Graph(const Graph &g) {
  n = g.n;
  directed = g.directed;
  edges = new list<int>[n];
  for (int i = 0; i < n; i++) 
    edges[i] = g.edges[i];
}

Graph &Graph::operator=(const Graph &g) {
  if (this != &g) {
    n = g.n;
    directed = g.directed;
    delete [] edges;
    edges = new list<int>[n];
    for (int i = 0; i < n; i++)
      edges[i] = g.edges[i];
  }
  return *this;
}

Graph::~Graph() {
  delete [] edges;
}

void Graph::insertEdge(int a, int b) { 
  edges[a].push_back(b);
  if (!directed)
    edges[b].push_back(a);
}

list<int> Graph::neighbors(int a) {
  return edges[a];
}

bool Graph::connected(int a, int b) {
  list<int>::iterator cur = edges[a].begin();
  while (cur != edges[a].end()) {
    if (*cur == b)
      return true;
    cur++;
  }
  return false;
}

int Graph::size() {
  return n;
}

int main() {
  Graph g(5, false);

  g.insertEdge(3,4);
  g.insertEdge(2,3);
  g.insertEdge(0,3);
  
  list<int> n = g.neighbors(3);
  list<int>::iterator cur = n.begin();
  while (cur != n.end()) {
    cout << *cur << '\n';
    cur++;
  }

  return 0;
}

