#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 1000;
struct Point
{
	double x, y;
	Point (){}
	Point (double _x, double _y)
	{
		x = _x;
		y = _y;
	}
	void read()
	{
		scanf("%lf%lf", &x, &y);
	}
	Point operator - (const Point &a)
	{
		return Point(x - a.x, y - a.y);
	}
	double operator % (const Point &a)
	{
		return x * a.x + y * a.y;
	}
	double mol()
	{
		return sqrt((double)((*this) % (*this)));
	}
	double disto(const Point &a)
	{
		return (*this - a).mol();
	}
}point[1000];
struct Edge
{
	int u, v; 
	double len;
	bool flag;
	Edge(){}
	Edge(int _u, int _v, double _len)
	{
		u = _u;
		v = _v;
		len = _len;
		flag = 0;
	}
	bool operator < (const Edge &a) const
	{
		return len < a.len;
	}
};
int fa[MAXN];
int find(int x)
{
	if (fa[x] == x)
		return x;
	else
		return fa[x] = find(fa[x]);
}
int head[MAXN], L;
struct Ed
{
	int to, next; 
	double len, maxs;
}ed[MAXN * 2 - 2];
void init(int n)
{
	memset(head, -1, 4 * n);
	L = 0;
}
void add_edge(int u, int v, double len)
{
	ed[L].to = v;
	ed[L].len = len;
	ed[L].maxs = -1;
	ed[L].next = head[u];
	head[u] = L ++;
}
int deg[MAXN], pre[MAXN];
void dfs(int u, int fu)
{
	for (int i = head[u]; i != -1; i = ed[i].next)
	{
		int v = ed[i].to;
		if (v == fu)
			continue;
		deg[v] = deg[u] + 1;
		pre[v] = i;
		dfs(v, u);
	}
}
int LCA[MAXN][MAXN];
void bfs(int s)
{
	queue <pair <int, int> > que;
	que.push(make_pair(s, -1));
	LCA[s][s] = s;
	while (!que.empty())
	{
		int u = que.front().first, fu = que.front().second;
		que.pop();
		for (int i = head[u]; i != -1; i = ed[i].next)
		{
			int v = ed[i].to;
			if (v == fu)
				continue;
			LCA[s][v] = LCA[s][u];
			if (deg[v] < deg[u])
				LCA[s][v] = v;
			else
				LCA[s][v] = LCA[s][u];
		}
	}
}
int next[MAXN];
int getNext(int u)
{
	if (u == next[u])
		return u;
	else
		return next[u] = getNext(next[u]);
}
void cover(int u, int fu, double len)
{
	for (u = getNext(u); deg[u] > deg[fu]; u = getNext(u))
	{
		ed[pre[u]].maxs = ed[pre[u] ^ 1].maxs = len;
		next[u] = ed[pre[u] ^ 1].to;
	}
}
int main()
{
	int T;
	scanf("%d", &T);
	while (T --)
	{
		int n, m;
		scanf("%d%d", &n, &m);
		for (int i = 0; i < n; ++ i)
			point[i].read();
		vector <Edge> edge;
		for (int i = 0; i < n; ++ i)
			for (int j = 0; j < i; ++ j)
				edge.push_back(Edge(j, i, point[i].disto(point[j])));
		sort(edge.begin(), edge.end());
		for (int i = 0; i < n; ++ i)
			next[i] = fa[i] = i;
		double ans = 0;
		init(n);
		for (int i = 0; i < (int) edge.size(); ++ i)
			if (find(edge[i].u) != find(edge[i].v))
			{
				edge[i].flag = 1;
				fa[find(edge[i].u)] = find(edge[i].v);
				ans += edge[i].len;
				add_edge(edge[i].u, edge[i].v, edge[i].len);
				add_edge(edge[i].v, edge[i].u, edge[i].len);
			}
		deg[0] = 0;
		dfs(0, -1);
		for (int i = 0; i < n; ++ i)
			bfs(i);
		for (int i = 0; i < (int) edge.size(); ++ i)
			if (!edge[i].flag && edge[i].u)
			{
				int lca = LCA[edge[i].u][edge[i].v];
				cover(edge[i].u, lca, edge[i].len);
				cover(edge[i].v, lca, edge[i].len);
			}
		double maxs = 0;
		for (int i = 0; i < L; i += 2)
			maxs = max(maxs, ed[i].maxs - ed[i].len);
		printf("%.2f\n", (ans + maxs) * m);
	}
	return 0;
}