private boolean undirectedAdd(UndirectedWeightedEdge e, UndirectedNode s) {
    HashMap<Node, Node> parent = parents.get(s);
    HashMap<Node, Integer> height = heights.get(s);

    IntWeight eWeight = (IntWeight) e.getWeight();

    UndirectedNode n1 = e.getNode1();
    UndirectedNode n2 = e.getNode2();

    if (height.get(n1) > height.get(n2)) {
      n1 = e.getNode2();
      n2 = e.getNode1();
    }

    if (height.get(n1) + (int) eWeight.getWeight() >= height.get(n2)
        || height.get(n1) + (int) eWeight.getWeight() < 0) {
      return true;
    }
    if (height.get(n2) != Integer.MAX_VALUE) apsp.decr(height.get(n2));
    apsp.incr(height.get(n1) + (int) eWeight.getWeight());
    height.put(n2, height.get(n1) + (int) eWeight.getWeight());
    parent.put(n2, n1);
    PriorityQueue<Node> q = new PriorityQueue<>();
    q.add(n2);
    while (!q.isEmpty()) {
      Node current = q.poll();

      if (height.get(current) == Integer.MAX_VALUE) {
        break;
      }

      for (IElement edge : current.getEdges()) {
        UndirectedWeightedEdge d = (UndirectedWeightedEdge) edge;

        Node neighbor = d.getDifferingNode(current);
        IntWeight dWeight = (IntWeight) d.getWeight();

        int alt = height.get(current) + (int) dWeight.getWeight();

        if (alt < height.get(neighbor)) {
          if (height.get(neighbor) != Integer.MAX_VALUE) apsp.decr(height.get(neighbor));
          apsp.incr(alt);
          height.put(neighbor, alt);
          parent.put(neighbor, current);
          if (q.contains(neighbor)) {
            q.remove(neighbor);
          }
          q.add(neighbor);
        }
      }
    }
    return true;
  }
  private boolean applyAfterUndirectedEdgeWeight(Update u) {
    UndirectedWeightedEdge e = (UndirectedWeightedEdge) ((EdgeWeight) u).getEdge();
    UndirectedNode n1 = e.getNode1();
    UndirectedNode n2 = e.getNode2();

    IntWeight eWeight = (IntWeight) e.getWeight();

    for (IElement ie : g.getNodes()) {
      UndirectedNode s = (UndirectedNode) ie;
      HashMap<Node, Node> parent = parents.get(s);
      HashMap<Node, Integer> height = heights.get(s);

      UndirectedNode src;
      UndirectedNode dst;
      if (height.get(n1) > height.get(n2)) {
        src = n2;
        dst = n1;
      } else {
        src = n1;
        dst = n2;
      }

      if (!parent.containsKey(dst)
          || height.get(src) + (int) eWeight.getWeight() == height.get(dst)) {
        continue;
      }

      if (height.get(src) + (int) eWeight.getWeight() > height.get(dst)
          || height.get(src) + (int) eWeight.getWeight() < 0) {
        if (parent.get(dst).equals(src)) {
          undirectedDelete(s, e);
        }
      } else {
        undirectedAdd(e, s);
      }
      apsp.truncate();
    }
    return true;
  }