         OffsetT (&segment_indices)[ITEMS_PER_THREAD],
         OffsetT num_segments)
     {
+        // Scatter first key of first tile and then unset the flag so we won't scatter the value
+        if (IS_FIRST_TILE && (threadIdx.x == 0))
+        {
+            segment_flags[0] = 0;
+            d_unique_out[0] = keys[0];
+        }
+
         // Scatter flagged keys and values
         #pragma unroll
         for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM)

        {
            if (segment_flags[ITEM])
            {
                OffsetT scatter_offset = segment_indices[ITEM] - num_tile_segments_prefix - ((IS_FIRST_TILE ? 1 : 0));
                temp_storage.raw_exchange_values.Alias()[scatter_offset] = values[ITEM];
            }
        }

        __syncthreads();

        for (int item = threadIdx.x; item < num_tile_segments + ((IS_LAST_TILE ? 1 : 0)); item += BLOCK_THREADS)
        {
            OffsetT scatter_offset = num_tile_segments_prefix + item - ((IS_FIRST_TILE ? 0 : 1));
            d_aggregates_out[scatter_offset] = temp_storage.raw_exchange_values.Alias()[item];
        }
    }


            // Update tile status if this is not the last tile
            if (!IS_LAST_TILE)
                tile_state.SetInclusive(0, tile_aggregate);

            // Initialize the segment index for the first scan item if necessary (the exclusive prefix for the first item is garbage)
            if (!HAS_IDENTITY_ZERO)
