#include <algorithm>
#include <cmath>
#include <cstdio>
#include <map>
#include <random>
#include <vector>

const int TRIALS = 20000;

struct CubeCoord
{
    int x, y, z;
};

static int dstsqr(const CubeCoord &a, const CubeCoord &b)
{
    int dx = a.x - b.x;
    int dy = a.y - b.y;
    int dz = a.z - b.z;
    return dx * dx + dy * dy + dz * dz;
}

static int match(std::vector<std::pair<int, int>> edges, int verts, std::mt19937 &rng)
{
    std::shuffle(edges.begin(), edges.end(), rng);
    std::vector<char> used(verts, 0);
    int matched = 0;
    for (auto &e : edges)
    {
        if (!used[e.first] && !used[e.second])
        {
            used[e.first] = used[e.second] = 1;
            matched++;
        }
    }
    return matched;
}

static int bestMatching(const std::vector<CubeCoord> &pts,
                        const std::vector<int> &color,
                        std::mt19937 &rng)
{
    int best = 0;
    for (int c = 0; c < 3; c++)
    {
        std::vector<int> group;
        for (int i = 0; i < (int)pts.size(); i++)
        {
            if (color[i] == c)
                group.push_back(i);
        }

        if ((int)group.size() < 2)
            continue;

        std::map<int, std::vector<std::pair<int, int>>> byDist;
        for (int i = 0; i < (int)group.size(); i++)
        {
            for (int j = i + 1; j < (int)group.size(); j++)
            {
                byDist[dstsqr(pts[group[i]], pts[group[j]])].push_back({i, j});
            }
        }

        for (auto &[dist, edges] : byDist)
        {
            if ((int)edges.size() < best)
                continue;
            int m = match(edges, (int)group.size(), rng);
            best = std::max(best, m);
        }
    }
    return best;
}

int main()
{
    std::vector<CubeCoord> pts;
    for (int x = 0; x < 4; x++)
        for (int y = 0; y < 4; y++)
            for (int z = 0; z < 4; z++)
                pts.push_back(CubeCoord{x, y, z});

    std::mt19937 rng(std::random_device{}());
    std::uniform_int_distribution<int> colorDist(0, 2);
    std::vector<int> color(pts.size());

    std::vector<long long> histogram(33, 0);
    double sum = 0.0;

    for (int t = 0; t < TRIALS; t++)
    {
        for (auto &c : color)
            c = colorDist(rng);

        sum += bestMatching(pts, color, rng);
    }

    std::printf("\n%.5f", sum / TRIALS);

    return 0;
}