                     break;
                 i-=1;
             }
-            /*
-            degree_t u_len = (src_len <= dst_len) ? src_len : dst_len;
-            //degree_t v_len = (src_len > dst_len) ? dst_len : src_len;
-            //unsigned int log_u = 32-__clz(u_len-1);
-            //unsigned int log_v = 32-__clz(v_len-1);
-            int W;
-            while (i > 0) {
-                W = d_queue_info.ptr()->queue_threads_per[i];
-                if ((u_len+W-1)/W >= 3)
-                    break;
-                i-=1;
-            }*/
-
-            //int imbalanced_work_est = ((u_len+W-1)/W)*log_v;
-            //int balanced_work_est = ((total_work+W-1)/W) + log_u;
-            //bin_index = (K*balanced_work_est > imbalanced_work_est);
-            bin_index = i;
-            //bin_index=2;
+            bin_index = METHOD*(MAX_ADJ_UNIONS_BINS/2)+i;
             // Either count or add the item to the appropriate queue
             if (countOnly)
                 atomicAdd(&(d_queue_info.ptr()->queue_sizes[bin_index]), 1ULL);

    // Phase 2: run the operator on each queued edge as appropriate
    for (auto bin = 0; bin < MAX_ADJ_UNIONS_BINS; bin++) {
        if (hd_queue_info().queue_sizes[bin] == 0) continue;
        int threads_per = hd_queue_info().queue_threads_per[bin]; 
        TM.start();
        /*if (bin == 0) { 
            //forAllEdgesAdjUnionBalanced(hornet, hd_queue_info().d_queues[bin], hd_queue_info().queue_pos[bin], op, threads_per, flag);
            forAllEdgesAdjUnionSequential(hornet, hd_queue_info().d_queues[bin], hd_queue_info().queue_pos[bin], op, flag);
        } else if (bin == 1) {
            forAllEdgesAdjUnionImbalanced(hornet, hd_queue_info().d_queues[bin], hd_queue_info().queue_pos[bin], op, threads_per, flag);
        }*/
        
        //threads_per = 256;
        forAllEdgesAdjUnionBalanced(hornet, hd_queue_info().d_queues[bin], hd_queue_info().queue_pos[bin], op, threads_per, 0);
        //forAllEdgesAdjUnionImbalanced(hornet, hd_queue_info().d_queues[bin], hd_queue_info().queue_pos[bin], op, threads_per, 1);
        TM.stop();
        TM.print("queue processing:");
        TM.reset();

            if (src.id() >= dst.id()) return; // imposes ordering
            degree_t src_len = src.degree();
            degree_t dst_len = dst.degree();

            degree_t u_len = (src_len <= dst_len) ? src_len : dst_len;
            degree_t v_len = (src_len > dst_len) ? dst_len : src_len;
            unsigned int log_v = 32-__clz(v_len-1);
            int intersect_work = u_len + v_len - 1;
            int binary_work = u_len * log_v;
            int METHOD = (5*intersect_work >= binary_work);
            total_work = METHOD ? u_len : u_len+v_len-1;
            int cutoff = METHOD ? 3 : 31;
            int i = MAX_ADJ_UNIONS_BINS/2;
            
            int W;
            while (i > 0) {
                W = d_queue_info.ptr()->queue_threads_per[i];
