Ruby || UnionFind
\n# Code\nruby\nclass NilClass\n    def >(v) = true\nend\n\nclass Graph\n    class UnionFind\n        attr_reader :parents\n\n        def initialize(n) = @paren
\n# Code\n```ruby\nclass NilClass\n    def >(v) = true\nend\n\nclass Graph\n    class UnionFind\n        attr_reader :parents\n\n        def initialize(n) = @parents = (0...n).to_a\n    \n        def find_parent(i) = (parents[i] == i ? i : (@parents[i] = find_parent(parents[i])))\n\n        def union(*uv)\n            pu, pv = uv.collect {|e| find_parent(e) }\n            @parents[pu] = pv\n        end\n\n    end\n\n    attr_reader :n, :edges\n\n    def initialize(n, edges)\n        @n = n\n        (@edges = edges.each_with_index.collect {|a, idx| a << idx }).sort_by! {|e| e[2] }\n    end\n\n    def findMST(blk = nil, e = nil)\n        w, uf = 0, UnionFind.new(n)\n        unless e.nil? then\n            w += edges[e][2]\n            uf.union(*edges[e][0..1])\n        end\n        edges.each_with_index {|e, i|\n            unless i == blk || uf.find_parent(e[0]) == uf.find_parent(e[1]) then\n                uf.union(*e[0..1])\n                w += e[2]\n            end\n        }\n        p0 = uf.find_parent(0)\n        (1...n).any? {|i| uf.find_parent(i) != p0 } ? nil : w\n    end\n\n    def solve\n        mstw = findMST\n        edges.each_with_index.each_with_object([[], []]) {|(e, i), (c, pc)|\n            if findMST(i) > mstw then\n                c << e.last\n            else\n                pc << e.last if mstw == findMST(nil, i)\n            end\n        }\n    end\nend\n\ndef find_critical_and_pseudo_critical_edges(n, edges)\n    Graph.new(n, edges).solve\nend\n```
['Ruby']