             if (src.id() >= dst.id()) return; // imposes ordering
             degree_t src_len = src.degree();
             degree_t dst_len = dst.degree();
-            int i = MAX_ADJ_UNIONS_BINS-1;
-            /*
-            if (i > 3)
-                i = 3;
-            */
+
+            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;
             
-            total_work = src_len + dst_len - 1;
             int W;
             while (i > 0) {
                 W = d_queue_info.ptr()->queue_threads_per[i];

//==============================================================================
//==============================================================================
// stub
#define MAX_ADJ_UNIONS_BINS 4
namespace adj_unions {
    struct queue_info {
        unsigned long long queue_sizes[MAX_ADJ_UNIONS_BINS] = {0,};

                    break;
                i-=1;
            }
            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);
