def remove_edge(self, u, v):
        print('Dynamically removing uv=(%r, %r)' % (u, v))
        self.graph.remove_edge(u, v)
        e = (u, v)
        if not self.forests[0].has_edge(u, v):
            return
        for i in reversed(range(0, self.level[e] + 1)):
            self.forests[i].remove_edge(u, v)
        for i in reversed(range(0, self.level[e] + 1)):
            Tu = self.forests[i].subtree(u)
            print('Tu = %r' % (list(Tu.nodes()),))
            Tv = self.forests[i].subtree(v)
            print('Tv = %r' % (list(Tv.nodes()),))
            if len(Tu) > len(Tv):
                Tu, Tv = Tv, Tu
            seen_ = set([])
            for x in Tu.nodes():
                seen_.add(x)
                for y in self.graph.neighbors(x):
                    if y in seen_:
                        continue
                    if y in Tv:
                        print('* Found replacement xy=(%r, %r)' % (x, y))
                        if len(self.forests) == i + 1:
                            self.forests.append(DummyEulerTourForest(self.graph.nodes()))
                        for j in range(0, i + 2):
                            print('* Add replacment to F[j=%r]' % (j,))
                            self.forests[j].add_edge(x, y)
                        return
                    else:
                        print('* Charging xy=(%r, %r)' % (x, y))
                        if len(self.forests) == i + 1:
                            self.forests.append(DummyEulerTourForest(self.graph.nodes()))
                        if self.forests[i].has_edge(x, y):
                            self.forests[i + 1].add_edge(x, y)
                        self.level[(x, y)] = i + 1