let rearrange_treeId tree gr edge_id cycle or_id=
    let delete_or_inputs () = 
      let new_gr = graph_from_tree tree
      in let or_node = findnode or_id tree
      in let or_gnode = DG.findnode or_id new_gr
      in let or_inp = DG.nodefoldedges (fun a y -> a::y) or_gnode []
      in let rec delete_or_inp inplist tree1 =
          match inplist with
            (cx,tx,px)::tail -> let g = GrbTrCutStrictCycle.Tr.umake (graph_from_tree tree1) (Right cx.nameforudg)
                                in (match g with
                                      Right _ -> delete_or_inp tail tree1
                                    | Left gra -> let _ = report2 "kustutasin serva"
                                                  in let new_or = (DG.findnode or_id gra)
                                                  in let or_new_inp = DG.nodefoldedges (fun a y -> a::y) new_or []
                                                  in let new_inp = 
                                                    List.filter (fun (cc,_,_)->not (hasnode cc.sourceid tree1)) or_new_inp
                                                  in let (cn,tn,pn) = List.hd new_inp
                                                  in let node = DG.findnode cn.sourceid gra
                                                  in let t1 = 
                                                    {tree1 with 
                                                    treeEdges = IdtMap.remove cx.nameforudg tree1.treeEdges}
                                                  in let t2 = 
                                                    {t1 with 
                                                    treeEdges = IdtMap.add cn.nameforudg {edge = (cn,tn.id,pn); edgeway = Unknown; used = true} t1.treeEdges}
                                                  in let t3 = 
                                                    {t2 with 
                                                    treeNodes = IdtMap.add cn.sourceid {node = node; allDone = true; children = [or_id]; number = NodeNumber.invalid_num} t2.treeNodes}
                                                  in let t4 = 
                                                    {t3 with 
                                                    treeNodes = IdtMap.add or_id {or_node with node = new_or} (IdtMap.remove or_id t3.treeNodes)}
                                                  in delete_or_inp tail t4
                                    )
          | _ -> tree1
        in let tree2 = delete_or_inp or_inp tree
        in (new_tree tree2,[])
    in match gr with
      Right a ->  let graph = graph_from_tree tree
                  in let _ = report2 ("ID teisenduse viga: "^a)
                  in let edge = findedge edge_id tree
                  in let (c,t,p) = edge.edge
                  in let or_node = or_id
                  in let rec try_remove edges gra = 
                    match edges with 
                      (co,_,_)::ta -> let h = GrbTrCutStrictCycle.Tr.umake gra (Right co.nameforudg)
                                      in (match h with
                                        Right _ -> try_remove ta gra
                                      | Left ggm -> let _ = report2 "kustutasin serva" in try_remove ta ggm)
                    | _ -> gra
                  in let (g,second_node) = 
                   (*following is ment for a special case where id transformation fails and there are only one or and one MUX nodes in cycle*)
                    if (is_MUX t tree && has_one_MUX cycle tree && has_one_or cycle tree)
                      then 
                          let id_node1 = DG.findnode c.sourceid graph
                          in let _ = report2 "Or -> Id -> MUX erijuht, kustuta Or sisendserv"
                          in let id_node_inp1 = DG.nodefoldedges (fun y a -> y::a) id_node1 []
                          in let (or_id2,before_or,graph2,no_longor) =
                              let id_bool_inp = List.filter (fun (_,_,px) -> px == PortSingleB) id_node_inp1
                              in let (cx,_,_) = List.hd id_bool_inp
                              in if cx.sourceid == or_id
                              then 
                                let before_or2 = 
                                  let rec find_or_inp cyc =
                                    match cyc with
                                      x::tail -> if x == or_id 
                                                  then List.hd tail 
                                                  else find_or_inp tail
                                    | _ -> NewName.invalid_id
                                  in find_or_inp cycle
                                in (or_id,before_or2,graph,true)
                              else (*longOr*)
                                let before_or2 = 
                                  let rec find_or_inp cyc =
                                    match cyc with
                                      x::tail -> if x == or_id 
                                                  then List.hd tail 
                                                  else find_or_inp tail
                                    | _ -> NewName.invalid_id
                                  in find_or_inp cycle
                                in (or_id,before_or2,graph,false)
                          in let mkcnstlblmap d =
                              RLMap.fold (fun rl k m ->
                                          List.fold_right (fun i mm -> RLMMap.add (rl,i) i mm
                                              ) (intfromto 1 k) m
                                          ) d RLMMap.empty
                          in if no_longor 
                          then
                            let id_node = DG.findnode c.sourceid graph2
                            in let id_node_inp = DG.nodefoldedges (fun y a -> y::a) id_node []
                            in let id_inp_from_op = List.filter (fun (cx,_,_) -> cx.sourceid != or_id2) id_node_inp
                            in let (cop,_,pop) = List.hd id_inp_from_op
                            in let op_node = DG.findnode cop.sourceid graph2
                            in let op_node_inp = DG.nodefoldedges (fun y a -> y::a) op_node []
                            in let op_node_from_or = List.filter (fun (cx,_,_) -> cx.sourceid == or_id2) op_node_inp
                            in let is_or_op = not (List.length op_node_from_or == 0) 
                            in let rec add_inp inp_list not_source target_id gr1 =
                                  match inp_list with
                                    (cx,tx,px)::tail -> if cx.sourceid == not_source 
                                                      then add_inp tail not_source target_id gr1
                                                      else let gm = DG.addedge ({cx with nameforudg = NewName.get ()}, target_id, px) gr1
                                                          in add_inp tail not_source target_id gm
                                  | _ -> gr1
                                                        in let ornode = DG.findnode or_id2 graph2
                            in let ornode_inp = DG.nodefoldedges (fun y a -> y::a) ornode []
                            in let new_or_id = NewName.get ()
                            in let _ = report2 ("uus or "^(NewName.to_string new_or_id))
                            in let new_id_id1 = NewName.get ()
                            in let false_id = NewName.get ()
                            in let mux_node = DG.findnode t graph2
                            in let mux_node_inp = DG.nodefoldedges (fun y a -> y::a) mux_node []
                            in let (cid,_,pid) = List.hd (List.filter (fun (_,_,px) -> px == PortSingleB) id_node_inp)
                            in let (graph3,new_op_id) = if is_or_op
                                then let (corop,_,porop) = List.hd op_node_from_or
                                     in let new_gr = ref graph2
                                     in let new_op_id = NewName.get ()
                                     in 
                                      new_gr := DG.addnode {op_node with inputs = PortMap.empty; id = new_op_id} !new_gr;
                                      new_gr := add_inp op_node_inp or_id2 new_op_id !new_gr;
                                      new_gr := DG.addedge ({corop with sourceid = new_or_id; nameforudg = NewName.get ()}, new_op_id, porop) !new_gr; 
                                      (!new_gr,new_op_id)
                                else (graph2,op_node.id)
                            in let new_gr = ref graph3
                            in 
                             new_gr := DG.remedge c.nameforudg !new_gr;
                             new_gr := DG.remnode mux_node.id !new_gr; 
                             new_gr := DG.addnode {ornode with inputs = PortMap.empty; id=new_or_id} !new_gr; 
                             new_gr := DG.addnode {id_node with inputs = PortMap.empty; id=new_id_id1} !new_gr; 
                             new_gr := DG.addnode {mux_node with inputs = PortMap.empty} !new_gr; 
                             new_gr := add_inp mux_node_inp id_node.id mux_node.id !new_gr; 
                             new_gr := add_inp (List.filter (fun (cx,_,_) -> cx.sourceid != op_node.id) id_node_inp) or_id2 new_id_id1 !new_gr; 
                             new_gr := add_inp ornode_inp before_or new_or_id !new_gr; 
                             new_gr := DG.addedge ({c with sourceid=new_id_id1},t,p) !new_gr; 
                             new_gr := DG.addedge ({cop with sourceid =new_op_id; nameforudg = NewName.get ()}, new_id_id1,pop) !new_gr;
                             new_gr := DG.addedge ({cid with sourceid = new_or_id; nameforudg = NewName.get ()}, new_id_id1, pid) !new_gr; 
                             if (List.length ornode_inp) == 1
                              then
                              begin
                              new_gr := DG.addnode {nname=False; id = false_id; inputs = PortMap.empty; inside=RLMap.empty; updims=RLMap.empty; otherdims=Array.of_list []} !new_gr;
                              new_gr := DG.addedge ({sourceid=false_id; nameforudg = NewName.get ();lblmap = mkcnstlblmap ornode.inside},new_or_id,PortUnstrB) !new_gr;
                              end
                              else
                                begin
                                end;
                            (Left !new_gr,mux_node.id)
                          else (*longOr*)
                            let id_node = DG.findnode c.sourceid graph2
                            in let id_node_inp = DG.nodefoldedges (fun y a -> y::a) id_node []
                            in let id_inp_from_op = List.filter (fun (_,_,px) -> px!=PortSingleB) id_node_inp
                            in let (cop,_,pop) = List.hd id_inp_from_op
                            in let op_node = DG.findnode cop.sourceid graph2
                            in let op_node_inp = DG.nodefoldedges (fun y a -> y::a) op_node []
                            in let op_node_from_or = List.filter (fun (cx,_,_) -> cx.sourceid == or_id2) op_node_inp
                            in let (corop,_,porop) = List.hd op_node_from_or
                            in let ornode = DG.findnode or_id2 graph2
                            in let rec add_inp inp_list not_source target_id gr1 =
                                  match inp_list with
                                    (cx,tx,px)::tail -> if cx.sourceid == not_source 
                                                      then add_inp tail not_source target_id gr1
                                                      else let gm = DG.addedge ({cx with nameforudg = NewName.get ()}, target_id, px) gr1
                                                          in add_inp tail not_source target_id gm
                                  | _ -> gr1
                            in let ornode_inp = DG.nodefoldedges (fun y a -> y::a) ornode []
                            in let new_or_id = NewName.get ()
                            in let _ = report2 ("uus or "^(NewName.to_string new_or_id))
                            in let new_id_id1 = NewName.get ()
                            in let false_id = NewName.get ()
                            in let new_longor_id = NewName.get ()
                            in let new_op_id = NewName.get ()
                            in let mux_node = DG.findnode t graph2
                            in let mux_node_inp = DG.nodefoldedges (fun y a -> y::a) mux_node []
                            in let (cid,_,pid) = List.hd (List.filter (fun (_,_,px) -> px == PortSingleB) id_node_inp)
                            in let longor_node = DG.findnode cid.sourceid graph2
                            in let (clongor,_,plongor) = List.hd (DG.nodefoldedges (fun y a -> y::a) longor_node [])
                            in let new_gr = ref graph2
                            in 
                             new_gr := DG.remedge c.nameforudg !new_gr; 
                             new_gr := DG.remnode mux_node.id !new_gr; 
                             new_gr := DG.addnode {ornode with inputs = PortMap.empty; id=new_or_id} !new_gr; 
                             new_gr := DG.addnode {longor_node with inputs = PortMap.empty; id=new_longor_id} !new_gr;
                             new_gr := DG.addnode {id_node with inputs = PortMap.empty; id=new_id_id1} !new_gr;
                             new_gr := DG.addnode {op_node with inputs = PortMap.empty; id =new_op_id} !new_gr;
                             new_gr := DG.addnode {mux_node with inputs = PortMap.empty} !new_gr;
                             new_gr := add_inp mux_node_inp id_node.id mux_node.id !new_gr;
                             new_gr := add_inp op_node_inp or_id2 new_op_id !new_gr; 
                             new_gr := DG.addedge ({corop with sourceid = new_or_id; nameforudg = NewName.get ()}, new_op_id, porop) !new_gr; 
                             new_gr := DG.addedge ({cop with sourceid =new_op_id; nameforudg = NewName.get ()}, new_id_id1,pop) !new_gr;
                             new_gr := add_inp (List.filter (fun (cx,_,_) -> cx.sourceid != op_node.id) id_node_inp) longor_node.id new_id_id1 !new_gr;
                             new_gr := add_inp ornode_inp before_or new_or_id !new_gr; 
                             new_gr := DG.addedge ({c with sourceid=new_id_id1},t,p) !new_gr; 
                             new_gr := DG.addedge ({cid with sourceid = new_longor_id; nameforudg = NewName.get ()}, new_id_id1, pid) !new_gr;
                             new_gr := DG.addedge ({clongor with sourceid = new_or_id; nameforudg = NewName.get ()}, new_longor_id, plongor) !new_gr;
                             if (List.length ornode_inp) == 1
                              then
                              begin
                              new_gr := DG.addnode {nname=False; id = false_id; inputs = PortMap.empty; inside=RLMap.empty; updims=RLMap.empty; otherdims=Array.of_list []} !new_gr;
                              new_gr := DG.addedge ({sourceid=false_id; nameforudg = NewName.get ();lblmap = mkcnstlblmap ornode.inside},new_or_id,PortUnstrB) !new_gr;
                              end
                              else
                                begin
                                end;
                            (Left !new_gr,mux_node.id)
                    else (*following is not Or->Id->MUX special case*)
                    (*above is a special case, could be uncommented for testing*)
                    if (has_many_MUXOr cycle tree) 
                      then if is_MUX (List.hd (List.rev cycle)) tree 
                          then let edge_id2 = find_edge_id (List.hd (List.rev cycle)) (List.hd (List.tl (List.rev cycle)))  tree
                              in let (cm,target_node_id,p) = (findedge edge_id2 tree).edge 
                              in let target_node = findnode target_node_id tree
                              in let graph_node = target_node.node
                              in if graph_node.nname == ShortMux
                              then (GrbTrFuseTwoAndOr.Tr.umake graph (Right edge_id2),cm.sourceid)
                              else let desc = nodedesc graph_node.nname
                              in if ns_inclvalue desc.outputtype Boolean 
                                then (GrbTrMoveDtoCMux.Tr.umake graph (Right edge_id2),cm.sourceid)
                                else (GrbTrMoveOverMux.Tr.umake graph (Right edge_id2),cm.sourceid)
                          else 
                          let bool_or = not (has_MUX cycle tree)
                          in if bool_or
                            then 
                              if is_OR (List.hd (List.rev cycle)) tree 
                              then 
                                let edge_id2 = find_edge_id (List.hd (List.rev cycle)) (List.hd (List.tl (List.rev cycle)))  tree
                                in let edge_2 = findedge edge_id2 tree
                                in let (cm,tt,_) = edge_2.edge
                                in match (findnode tt tree).node.nname with
                                  And -> (GrbTrMoveOverOr.Tr.umake graph (Right edge_id2),cm.sourceid)
                                | Or -> (GrbTrMoveOverOr.Tr.umake graph (Right edge_id2),cm.sourceid)
                                | LongOr -> (GrbTrMoveOverOr.Tr.umake graph (Right edge_id2),cm.sourceid)
                                | _ -> let gg = GrbTrMoveOverOr.Tr.umake graph (Right edge_id2)
                                      in match gg with
                                        Right a -> (Right a,NewName.invalid_id)
                                      | Left gr_id -> let next_edge_target = 
                                                        let rec other cyc =
                                                          match cyc with
                                                             x::y::tail -> if x == tt then y else other (y::tail)
                                                           | x::tail -> if x == tt then List.hd (List.rev cycle) else other tail
                                                           | _ -> NewName.invalid_id
                                                          in other (List.rev cycle)
                                                      in let next_edge_id = find_edge_id tt next_edge_target tree
                                                      in let node = DG.findnode next_edge_target gr_id
                                                      in let desc = nodedesc node.nname
                                                      in if ns_inclvalue desc.outputtype Boolean  
                                                        then (GrbTrDtoCOverId.Tr.umake gr_id (Right next_edge_id),cm.sourceid)
                                                        else (GrbTrPassOverId.Tr.umake gr_id (Right next_edge_id),cm.sourceid)
                              else 
                              let (other_or,end_n) = 
                                  let rec oo cyc =
                                    match cyc with
                                      x::y::tail -> if is_OR x tree && x != or_node then (x,y) else oo (y::tail)
                                    | x::tail -> if is_OR x tree && x!=or_node then (x,(List.hd (List.rev cycle))) else oo tail
                                    | _ -> (NewName.invalid_id,NewName.invalid_id)
                                  in oo (List.rev cycle)
                              in match (findnode end_n tree).node.nname with
                                And -> (GrbTrMoveOverOr.Tr.umake graph (Right (find_edge_id other_or end_n tree)),other_or)
                              | Or -> (GrbTrMoveOverOr.Tr.umake graph (Right (find_edge_id other_or end_n tree)),other_or)
                              | LongOr -> (GrbTrMoveOverOr.Tr.umake graph (Right (find_edge_id other_or end_n tree)),other_or)
                              | _ -> let gg = GrbTrMoveOverOr.Tr.umake graph (Right (find_edge_id other_or end_n tree))
                                      in match gg with
                                        Right a -> (Right a,NewName.invalid_id)
                                      | Left gr_id -> let next_edge_target = 
                                                        let rec other cyc =
                                                          match cyc with
                                                             x::y::tail -> if x == end_n then y else other (y::tail)
                                                           | x::tail -> if x == end_n then List.hd (List.rev cycle) else other tail
                                                           | _ -> NewName.invalid_id
                                                          in other (List.rev cycle)
                                                      in let next_edge_id = find_edge_id end_n next_edge_target tree
                                                      in let node = DG.findnode next_edge_target gr_id
                                                      in let desc = nodedesc node.nname
                                                      in if ns_inclvalue desc.outputtype Boolean 
                                                        then (GrbTrDtoCOverId.Tr.umake gr_id (Right next_edge_id),other_or)
                                                        else (GrbTrPassOverId.Tr.umake gr_id (Right next_edge_id),other_or)
                            else let edge_id23 = upper_mux_edge cycle tree 
                            in let _ = report2 "teisenda teine MUX"
                            in let edge_id2 = if edge_id23==NewName.invalid_id 
                                  then (find_edge_id (List.hd (List.rev cycle)) (List.hd (List.tl (List.rev cycle))) tree) 
                                  else edge_id23
                            in let (cm,target_node_id,p) = (findedge edge_id2 tree).edge 
                            in let target_node = findnode target_node_id tree
                            in let graph_node = target_node.node
                            in if graph_node.nname == ShortMux
                              then (GrbTrFuseTwoAndOr.Tr.umake graph (Right edge_id2),cm.sourceid)
                              else let desc = nodedesc graph_node.nname
                            in if ns_inclvalue desc.outputtype Boolean 
                                then (GrbTrMoveDtoCMux.Tr.umake graph (Right edge_id2),cm.sourceid)
                                else (GrbTrMoveOverMux.Tr.umake graph (Right edge_id2),cm.sourceid)
                      else let before_or = 
                        let rec next (x::y::t) =
                        if x == or_node then y else next (y::t)
                        in if (List.hd (List.rev cycle))==or_node then List.hd cycle else next cycle
                      in (GrbTrCutStrictCycle.Tr.umake graph (Right (find_edge_id before_or or_node tree)),NewName.invalid_id)
                    in let gg1 = match g with (*general cleaning on graph*)
                                  Right _ -> graph_from_tree tree
                                | Left gg5 -> gg5
                        in let gg2 = if DG.hasnode or_id gg1 
                                    then try_remove (DG.nodefoldedges (fun y a -> y::a) (DG.findnode or_id gg1) []) gg1
 
                                    else gg1
                        in let gg3 = if DG.hasnode second_node gg2 
                                    then try_remove (DG.nodefoldedges (fun y a -> y::a) (DG.findnode second_node gg2) []) gg2
                                    else gg1
                        in let gra2 = match (GrbTrRemoveDead.Tr.umake gg3 (Right NewName.invalid_id)) with
                                      Right _ -> gg3
                                    | Left ggm -> ggm
                        in let gg = gra2
                        in let t = createTree gg;
                        in let be = findBeginnings (nodelist gg)
                        in let _ = NodeNumber.refresh (NodeNumber.from_int 1)
                        in let tree2 = depth t be
                        in (tree2,[]) 
    | Left graph -> 
        let edge = findedge edge_id tree
        in match edge.edgeway with
          Normal -> let (c,t,p) = edge.edge
                    in if c.sourceid == List.hd (List.rev cycle) 
                      then 
                        let _ = report2 "Id sisendserv on back"
                        in delete_or_inputs ()
                      else (*Input and output of Id in cycle are Normal edges*)
                        let op_node = findnode t tree
                        in let _ = report2 "Id normal"
                        in let op_gnode = DG.findnode t graph
                        in let desc = nodedesc (DG.findnode t graph).nname
                        in let op_inp = DG.nodefoldedges (fun y a -> y::a) op_gnode []
                        in let op_tinp = edgefilter tree (fun _ x -> let (_,ta,_) = x.edge in t == ta)
                        in let op_id_inp = List.map (fun (cx,_,_)-> cx.nameforudg) op_inp
                        in let op_id_tinp = List.map (fun x -> let (cx,_,_)=x.edge in cx.nameforudg) op_tinp
                        in if ns_inclvalue desc.outputtype Boolean 
                          then 
                            let (c_out,and_node,p_out) = List.hd (DG.nodefoldoutedges graph (fun y a -> y::a) op_gnode [])
                            in let op_tout = edgefilter tree (fun _ x -> let (ca,ta,_) = x.edge in ca.sourceid == t)
                            in let and_out = DG.nodefoldoutedges graph (fun y a -> y::a) and_node []
                            in let rec add_and_out edgelist tr=
                              match edgelist with
                                x::tail -> let (cx,tx,px) = x.edge
                                           in let (cxx,_,pxx) = List.hd (List.filter (fun (_,tt,_) -> tt.id ==tx) and_out)
                                           in let edges = 
                                              IdtMap.add cxx.nameforudg {edge = (cxx,tx,pxx); used = true; edgeway = x.edgeway} (IdtMap.remove cx.nameforudg tr.treeEdges)
                                           in let t_n = findnode tx tr
                                           in let n = DG.findnode tx graph
                                           in let nodes = 
                                              IdtMap.add tx {node = n; number = t_n.number; allDone=true; children = t_n.children} (IdtMap.remove tx tr.treeNodes)
                                           in add_and_out tail {tr with treeNodes = nodes; treeEdges = edges}
                              | _ -> tr
                            in let tree2 = {tree with 
                                        treeNodes = IdtMap.add t {op_node with node = op_gnode; children = [and_node.id]} (IdtMap.remove t tree.treeNodes); 
                                        treeEdges =IdtMap.remove c.nameforudg tree.treeEdges}
                            in let ttt = {tree2 with 
                                    treeEdges = IdtMap.add c_out.nameforudg {edge = (c_out,and_node.id,p_out); edgeway = Cross; used = true} tree2.treeEdges; 
                                    treeNodes =IdtMap.add and_node.id {node = and_node; allDone = true; number = op_node.number; children= op_node.children} tree2.treeNodes}
                            in let added_and = add_and_out op_tout ttt
                            in let and_or_inp = List.filter (fun (cx,_,_) -> cx.nameforudg != c_out.nameforudg) (DG.nodefoldedges (fun y a -> y::a) and_node [])
                            in let (ca,ta,pa) = List.hd and_or_inp
                            in let or_node = findnode ca.sourceid added_and
                            in let new_nodes =IdtMap.add ca.sourceid {or_node with children = ta.id::or_node.children} (IdtMap.remove ca.sourceid added_and.treeNodes)
                            in let tree3 = {added_and with treeNodes = new_nodes; treeEdges = IdtMap.add ca.nameforudg {edge =(ca,ta.id,pa); edgeway = Normal; used = true} added_and.treeEdges}
                            in let op_new_inp = List.hd (List.filter (fun x -> not (List.mem x op_id_tinp)) op_id_inp)
                            in let (cn,tn,pn) = DG.findedge op_new_inp graph
                            in let old_op = findnode cn.sourceid tree3
                            in let nnodes = IdtMap.add cn.sourceid {old_op with children = tn.id::old_op.children} (IdtMap.remove cn.sourceid tree3.treeNodes)
                            in let tree4 = {tree3 with treeNodes = nnodes; treeEdges = IdtMap.add cn.nameforudg {edge = (cn,tn.id,pn); edgeway = Normal; used = true} tree3.treeEdges}
                            in let rec split cyc seen =
                              match cyc with
                                x::tail -> if x == c.sourceid 
                                          then if seen == [] then ([],(List.rev (List.tl (List.rev tail)))) else (List.rev (List.tl seen),tail)
                                          else split tail (x::seen)
                              | _ -> (List.rev seen,[])
                            in let (f,s) = split cycle []
                            in let cyc = List.concat [f;[and_node.id];s]
                            in (rearrange tree4 (List.hd (List.rev cyc)) cyc,cyc)
                          else (*OP node has bitstring output*)
                            let op_new_inp = List.filter (fun x -> not (List.mem x op_id_tinp)) op_id_inp
                            in let tree2 = {tree with 
                                  treeNodes = IdtMap.add t {op_node with node = op_gnode} (IdtMap.remove t tree.treeNodes); 
                                  treeEdges =IdtMap.remove c.nameforudg tree.treeEdges}
                            in let bool_inp = 
                                  List.filter (fun x -> let (cx,_,_) = DG.findedge x graph in ns_inclvalue (nodedesc (DG.findnode cx.sourceid graph).nname).outputtype Boolean ) op_new_inp
                            in let from_op_inp = List.filter (fun x -> not (List.mem x bool_inp)) op_new_inp 
                            in let (cc,tt,pp) = DG.findedge (List.hd from_op_inp) graph 
                            in let sour = findnode cc.sourceid tree2
                            in let sour_added =IdtMap.add cc.sourceid {sour with children = List.concat [sour.children;[tt.id]]} (IdtMap.remove cc.sourceid tree2.treeNodes)
                            in let tree3 = 
                                {tree2 with 
                                treeNodes = sour_added; 
                                treeEdges =IdtMap.add cc.sourceid {edge=(cc,tt.id,pp); edgeway = Cross; used = true} tree2.treeEdges}
                            in let (cn,_,pn) = DG.findedge (List.hd bool_inp) graph
                            in let and_node = DG.findnode cn.sourceid graph
                            in let tree4 = 
                                {tree3 with 
                                treeNodes =IdtMap.add and_node.id {node = and_node; allDone = true; number = op_node.number; children = [op_gnode.id]} tree3.treeNodes; 
                                treeEdges =IdtMap.add cn.nameforudg {edge= (cn,op_gnode.id,pn); edgeway = Normal; used = true} tree3.treeEdges}
                            in let and_inp = DG.nodefoldedges (fun y a -> y::a) and_node []
                            in let lor_id = 
                                let rec orid cyc =
                                  match cyc with
                                    x::y::tail -> if x == c.sourceid then y else orid (y::tail)
                                  | x::tail -> if x == c.sourceid then List.hd cycle else orid tail
                                  | _ -> NewName.invalid_id
                                in orid cycle
                            in let and_inp_or = List.filter (fun (cx,_,_) -> cx.sourceid ==lor_id) and_inp
                            in let (cand,_,pand) = List.hd and_inp_or
                            in let lor_node = findnode lor_id tree4
                            in let lor_added =
                                IdtMap.add lor_id {lor_node with children = and_node.id::lor_node.children} (IdtMap.remove lor_id tree4.treeNodes) 
                            in let tree5 = 
                                {tree4 with 
                                treeNodes=lor_added; 
                                treeEdges =IdtMap.add cand.nameforudg {edge =(cand, and_node.id,pand); edgeway = Normal; used = true} (tree4.treeEdges)}
                            in let tree6 =if (List.length and_inp) > 1 
                            then 
                              let and_other_inp = List.filter (fun (cx,_,_) -> (cx.nameforudg != cand.nameforudg)) and_inp
                              in let (coth,_,poth) = List.hd and_other_inp 
                              in let tree_edge = find_edge_id coth.sourceid op_gnode.id tree
                              in let coth_node = findnode coth.sourceid tree5
                              in let coth_added =
                                  IdtMap.add coth.sourceid {coth_node with children = List.concat [coth_node.children; [and_node.id]]} (IdtMap.remove coth.sourceid tree5.treeNodes)
                              in {tree5 with 
                                  treeNodes=coth_added; 
                                  treeEdges =IdtMap.add coth.nameforudg {edge = (coth,and_node.id,poth); edgeway = (findedge tree_edge tree).edgeway; used = true} (IdtMap.remove tree_edge tree5.treeEdges)}
                            else let tree_edge = find_edge_id or_id op_gnode.id tree
                                 in if tree_edge != cand.nameforudg
                                      then {tree5 with 
                                            treeNodes=tree5.treeNodes; 
                                            treeEdges =(IdtMap.remove tree_edge tree5.treeEdges)}
                                      else tree5
                            in let rec split cyc seen =
                              match cyc with
                                x::tail -> if x == c.sourceid 
                                          then (List.rev seen,tail)
                                          else split tail (x::seen)
                              | _ -> ([],List.rev seen)
                            in let (f,s) = split cycle []
                            in let cyc = List.concat [f;[and_node.id];s]
                            in (tree6,cyc)
        | Backward -> let _ = report2 "Id back"
                      in delete_or_inputs ()