// File: sharmaeklavya2[P]ddos-on-anycast/src/lib/graph_gen.cpp
// Function: make_random_connected_graph(int, int, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>&, int)
void make_random_connected_graph(int n, int approx_m, ipvec& l, int seed) {
    // Make a connected graph with (n vertices and approximately approx_m edges).
    // Returns the number of nodes in this graph. Returns the anti-symmetric edge list in l.
    // int n = std::max(1, int(std::normal_distribution<double>(n, n * 0.25)(rng));

    rng_t rng(seed);

    int max_edges = n * (n-1) / 2;
    if(approx_m >= max_edges) {
        for(int i=0; i<n; ++i) {
            for(int j=i+1; j<n; ++j) {
                l.emplace_back(i, j);
            }
        }
        return;
    }

    // get distance between all points
    vector<double> xcoords(n, 0.0), ycoords(n, 0.0);
    for(int i=0; i<n; ++i) {
        xcoords[i] = runidist(0, 1, rng);
        ycoords[i] = runidist(0, 1, rng);
    }

    typedef std::tuple<double, int, int> diitrip;
    vector<diitrip> all_edges;
    all_edges.reserve(max_edges);
    for(int i=0; i<n; ++i) {
        for(int j=i+1; j<n; ++j) {
            diitrip t(norm(xcoords[i]-xcoords[j], ycoords[i]-ycoords[j]), i, j);
            all_edges.push_back(t);
        }
    }
    std::sort(all_edges.begin(), all_edges.end());

    // create MST
    DisjointSets ds(n);
    int n_components = n;
    ipvec edges2; vector<double> weights2;
    edges2.reserve(all_edges.size());
    weights2.reserve(all_edges.size());
    double weight_sum = 0;
    // all_edges2.reserve(all_edges.size());
    for(const diitrip& t: all_edges) {
        int i, j; double norm;
        std::tie(norm, i, j) = t;
        int i2 = ds.find(i), j2 = ds.find(j);
        if(i2 == j2) {
            double weight = std::exp(-norm/2);
            weight_sum += weight;
            edges2.emplace_back(i, j);
            weights2.push_back(weight);
        }
        else {
            n_components--;
            ds.unite(i, j);
            l.emplace_back(i, j);
        }
    }
    approx_m -= n-1;

    ivec indices;
    multi_sample(weights2, approx_m, indices, rng);
    for(int index: indices) {
        l.push_back(edges2[index]);
    }
}

// Assembly:
subq $0x298, %rsp            # imm = 0x298
movl %edi, 0x294(%rsp)
movl %esi, 0x290(%rsp)
movq %rdx, 0x288(%rsp)
movl %ecx, 0x284(%rsp)
movslq 0x284(%rsp), %rsi
leaq 0x278(%rsp), %rdi
callq 0x9f10
movl 0x294(%rsp), %eax
movl 0x294(%rsp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, 0x274(%rsp)
movl 0x290(%rsp), %eax
cmpl 0x274(%rsp), %eax
jl 0xc4d6
movl $0x0, 0x270(%rsp)
movl 0x270(%rsp), %eax
cmpl 0x294(%rsp), %eax
jge 0xc4d1
movl 0x270(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x26c(%rsp)
movl 0x26c(%rsp), %eax
cmpl 0x294(%rsp), %eax
jge 0xc4bc
movq 0x288(%rsp), %rdi
leaq 0x270(%rsp), %rsi
leaq 0x26c(%rsp), %rdx
callq 0xce90
movl 0x26c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x26c(%rsp)
jmp 0xc47c
jmp 0xc4be
movl 0x270(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x270(%rsp)
jmp 0xc45b
jmp 0xccaf
movslq 0x294(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq $0x0, 0x248(%rsp)
leaq 0x247(%rsp), %rdi
movq %rdi, 0xb0(%rsp)
callq 0xcf10
movq 0xa8(%rsp), %rsi
movq 0xb0(%rsp), %rcx
leaq 0x250(%rsp), %rdi
leaq 0x248(%rsp), %rdx
callq 0xcf20
jmp 0xc52e
leaq 0x247(%rsp), %rdi
callq 0xcfa0
movslq 0x294(%rsp), %rax
movq %rax, 0x98(%rsp)
movq $0x0, 0x210(%rsp)
leaq 0x20f(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0xcf10
movq 0x98(%rsp), %rsi
movq 0xa0(%rsp), %rcx
leaq 0x218(%rsp), %rdi
leaq 0x210(%rsp), %rdx
callq 0xcf20
jmp 0xc593
leaq 0x20f(%rsp), %rdi
callq 0xcfa0
movl $0x0, 0x208(%rsp)
movl 0x208(%rsp), %eax
cmpl 0x294(%rsp), %eax
jge 0xc6bc
xorl %edi, %edi
movl $0x1, %esi
leaq 0x278(%rsp), %rdx
callq 0xcd20
movsd %xmm0, 0x90(%rsp)
jmp 0xc5de
movslq 0x208(%rsp), %rsi
leaq 0x250(%rsp), %rdi
callq 0xcfb0
movsd 0x90(%rsp), %xmm0
movsd %xmm0, (%rax)
xorl %edi, %edi
movl $0x1, %esi
leaq 0x278(%rsp), %rdx
callq 0xcd20
movsd %xmm0, 0x88(%rsp)
jmp 0xc61f
movslq 0x208(%rsp), %rsi
leaq 0x218(%rsp), %rdi
callq 0xcfb0
movsd 0x88(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x208(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x208(%rsp)
jmp 0xc5ab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x247(%rsp), %rdi
callq 0xcfa0
jmp 0xcd05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x20f(%rsp), %rdi
callq 0xcfa0
jmp 0xccf8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xcceb
leaq 0x1f0(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0xcfd0
movq 0x80(%rsp), %rdi
movslq 0x274(%rsp), %rsi
callq 0xcfe0
jmp 0xc6e8
movl $0x0, 0x1ec(%rsp)
movl 0x1ec(%rsp), %eax
cmpl 0x294(%rsp), %eax
jge 0xc863
movl 0x1ec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1e8(%rsp)
movl 0x1e8(%rsp), %eax
cmpl 0x294(%rsp), %eax
jge 0xc84b
movslq 0x1ec(%rsp), %rsi
leaq 0x250(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0xcfb0
movq 0x50(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x58(%rsp)
movslq 0x1e8(%rsp), %rsi
callq 0xcfb0
movsd 0x58(%rsp), %xmm0
movsd (%rax), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x70(%rsp)
movslq 0x1ec(%rsp), %rsi
leaq 0x218(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0xcfb0
movq 0x60(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x68(%rsp)
movslq 0x1e8(%rsp), %rsi
callq 0xcfb0
movsd 0x68(%rsp), %xmm1
movsd 0x70(%rsp), %xmm0
movsd (%rax), %xmm2
subsd %xmm2, %xmm1
callq 0xcd60
movsd %xmm0, 0x78(%rsp)
jmp 0xc7cd
movsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x1d0(%rsp)
leaq 0x1d8(%rsp), %rdi
movq %rdi, 0x48(%rsp)
leaq 0x1d0(%rsp), %rsi
leaq 0x1ec(%rsp), %rdx
leaq 0x1e8(%rsp), %rcx
callq 0xd0f0
movq 0x48(%rsp), %rsi
leaq 0x1f0(%rsp), %rdi
callq 0xd130
jmp 0xc81a
jmp 0xc81c
movl 0x1e8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1e8(%rsp)
jmp 0xc718
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xccde
jmp 0xc84d
movl 0x1ec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1ec(%rsp)
jmp 0xc6f3
leaq 0x1f0(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0xd1e0
movq 0x40(%rsp), %rdi
movq %rax, 0x1c8(%rsp)
callq 0xd210
movq %rax, 0x1c0(%rsp)
movq 0x1c8(%rsp), %rdi
movq 0x1c0(%rsp), %rsi
callq 0xd1a0
jmp 0xc8a6
movl 0x294(%rsp), %esi
leaq 0x188(%rsp), %rdi
callq 0xd240
jmp 0xc8bc
movl 0x294(%rsp), %eax
movl %eax, 0x184(%rsp)
leaq 0x168(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x4a50
leaq 0x150(%rsp), %rdi
callq 0xd2c0
leaq 0x1f0(%rsp), %rdi
callq 0xd3e0
movq 0x38(%rsp), %rdi
movq %rax, %rsi
callq 0xd2d0
jmp 0xc905
leaq 0x1f0(%rsp), %rdi
callq 0xd3e0
movq %rax, %rsi
leaq 0x150(%rsp), %rdi
callq 0xd400
jmp 0xc924
xorps %xmm0, %xmm0
movsd %xmm0, 0x148(%rsp)
leaq 0x1f0(%rsp), %rax
movq %rax, 0x140(%rsp)
movq 0x140(%rsp), %rdi
callq 0xd1e0
movq %rax, 0x138(%rsp)
movq 0x140(%rsp), %rdi
callq 0xd210
movq %rax, 0x130(%rsp)
leaq 0x138(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0xd510
testb $0x1, %al
jne 0xc988
jmp 0xcb36
leaq 0x138(%rsp), %rdi
callq 0xd550
movq %rax, 0x128(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x100(%rsp), %rdi
movq %rdi, 0x20(%rsp)
leaq 0x118(%rsp), %rsi
leaq 0x124(%rsp), %rdx
leaq 0x120(%rsp), %rcx
callq 0xd560
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0xd5a0
movl 0x124(%rsp), %esi
leaq 0x188(%rsp), %rdi
callq 0xd5e0
movl %eax, 0x34(%rsp)
jmp 0xc9fd
movl 0x34(%rsp), %eax
movl %eax, 0xfc(%rsp)
movl 0x120(%rsp), %esi
leaq 0x188(%rsp), %rdi
callq 0xd5e0
movl %eax, 0x1c(%rsp)
jmp 0xca22
movl 0x1c(%rsp), %eax
movl %eax, 0xf8(%rsp)
movl 0xfc(%rsp), %eax
cmpl 0xf8(%rsp), %eax
jne 0xcad4
movsd 0x118(%rsp), %xmm0
movsd 0x14b8e(%rip), %xmm1    # 0x215e0
mulsd %xmm1, %xmm0
callq 0x2200
movsd %xmm0, 0xf0(%rsp)
movsd 0xf0(%rsp), %xmm1
movsd 0x148(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x148(%rsp)
leaq 0x168(%rsp), %rdi
leaq 0x124(%rsp), %rsi
leaq 0x120(%rsp), %rdx
callq 0xce90
jmp 0xcaa2
leaq 0x150(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0xd670
jmp 0xcab9
jmp 0xcb22
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xccb7
movl 0x184(%rsp), %eax
decl %eax
movl %eax, 0x184(%rsp)
movl 0x124(%rsp), %esi
movl 0x120(%rsp), %edx
leaq 0x188(%rsp), %rdi
callq 0xd6e0
jmp 0xcb01
movq 0x288(%rsp), %rdi
leaq 0x124(%rsp), %rsi
leaq 0x120(%rsp), %rdx
callq 0xce90
jmp 0xcb20
jmp 0xcb22
jmp 0xcb24
leaq 0x138(%rsp), %rdi
callq 0xd7c0
jmp 0xc96a
movl 0x294(%rsp), %ecx
movl 0x290(%rsp), %eax
subl %ecx, %eax
incl %eax
movl %eax, 0x290(%rsp)
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x6950
movq 0x10(%rsp), %rdx
movl 0x290(%rsp), %esi
leaq 0x150(%rsp), %rdi
leaq 0x278(%rsp), %rcx
callq 0x204c0
jmp 0xcb84
leaq 0xd8(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x5bf0
movq %rax, 0xc8(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x5a70
movq %rax, 0xc0(%rsp)
leaq 0xc8(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x9fe0
testb $0x1, %al
jne 0xcbd9
jmp 0xcc54
leaq 0xc8(%rsp), %rdi
callq 0xa020
movl (%rax), %eax
movl %eax, 0xbc(%rsp)
movq 0x288(%rsp), %rax
movq %rax, 0x8(%rsp)
movslq 0xbc(%rsp), %rsi
leaq 0x168(%rsp), %rdi
callq 0xd850
movq 0x8(%rsp), %rdi
movq %rax, %rsi
callq 0xd7e0
jmp 0xcc20
jmp 0xcc22
leaq 0xc8(%rsp), %rdi
callq 0xa0b0
jmp 0xcbbe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x5020
jmp 0xccb7
leaq 0xd8(%rsp), %rdi
callq 0x5020
leaq 0x150(%rsp), %rdi
callq 0xd870
leaq 0x168(%rsp), %rdi
callq 0x4ae0
leaq 0x188(%rsp), %rdi
callq 0xd8d0
leaq 0x1f0(%rsp), %rdi
callq 0xd900
leaq 0x218(%rsp), %rdi
callq 0xd870
leaq 0x250(%rsp), %rdi
callq 0xd870
addq $0x298, %rsp            # imm = 0x298
retq
leaq 0x150(%rsp), %rdi
callq 0xd870
leaq 0x168(%rsp), %rdi
callq 0x4ae0
leaq 0x188(%rsp), %rdi
callq 0xd8d0
leaq 0x1f0(%rsp), %rdi
callq 0xd900
leaq 0x218(%rsp), %rdi
callq 0xd870
leaq 0x250(%rsp), %rdi
callq 0xd870
movq 0x238(%rsp), %rdi
callq 0x21f0
nopw %cs:(%rax,%rax)