 
     // Create and initialize CUDA thread output structs
     std::vector<EDGE_OUTPUT> outputs(E_num);
-    outputs.resize(E_num, {0, 0});
+    outputs.resize(E_num, {0});
 
     // Pointers of V, E_u, E_v, and edge outputs in GPU memory
     int* V_ptr;
+    int* E_ptr;
     int* E_u_ptr;
     int* E_v_ptr;
     EDGE_OUTPUT* outputs_ptr;

    // Return immediately if thread index is greater than maximum edge index
    if (i >= E_num) return;

    // Lookup the endpoints of the current edge
    int u = E_u[i];
    int v = E_v[i];

    // Lookup starting and ending indices for u and v in the edge list array
    int u_start = V[u], u_end = V[u + 1], v_start = V[v], v_end = V[v + 1];
    int iu = u_start, iv = v_start;
    int tri_e = 0, star_e = 0;

    while (iu < u_end || iv < v_end) {
        if (E_v[iu] == v) {
            // If current neighbor of u is v, skip by incrementing iu
            iu++;
        } else if (E_v[iv] == u) {
            // If current neighbor of v is u, skip by incrementing iv
            iv++;
        } else if (E_v[iu] < E_v[iv]) {
            // If current neighbor of u is less than current neighbor of v, star is found
            star_e++;
            iu++;
        } else if (E_v[iv] < E_v[iu]) {
            // If current neighbor of v is less than current neighbor of u, star is found
            star_e++;
            iv++;
        } else if (E_v[iu] == E_v[iv]) {
            // If u and v have the same current neighbor, triangle is found
            tri_e++;
            iu++;
            iv++;
        }
    }

    outputs[i].tri_e = tri_e;
    outputs[i].star_e = star_e;
}

int main(int argc, char *argv[])

        for (int j = 0; j < adj_list[i].size(); j++) {
            E_u.push_back(i);
            E_v.push_back(adj_list[i][j]);

            if (i < adj_list[i][j]) {
                E.push_back(E_u.size() - 1);
            }
        }

        edge_index += adj_list[i].size();
