#include <bits/stdc++.h>
using namespace std;
template <typename T>
T gcd(T first, T second) {
  while (second > 0) {
    first %= second;
    swap(first, second);
  }
  return first;
}
template <class _T>
inline _T sqr(const _T &first) {
  return first * first;
}
template <class _T>
inline string tostr(const _T &a) {
  ostringstream os("");
  os << a;
  return os.str();
}
const long double PI = 3.1415926535897932384626433832795L;
template <typename T>
inline void input(T &a) {
  static int ed;
  a = 0;
  while (!isdigit(ed = getchar()) && ed != '-') {
  }
  char neg = 0;
  if (ed == '-') {
    neg = 1;
    ed = getchar();
  }
  while (isdigit(ed)) {
    a = 10 * a + ed - '0';
    ed = getchar();
  }
  if (neg) a = -a;
}
template <typename T = int>
inline T nxt() {
  T res;
  input(res);
  return res;
}
long long mod = 1000 * 1000 * 1000 + 7;
long long pw(long long a, long long n) {
  long long res = 1;
  while (n) {
    if (n & 1ll) {
      res = res * a % mod;
    }
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}
long long inv(long long a) { return pw(a, mod - 2); }
struct pt {
  long long first, second;
  pt() {}
  pt(long long first, long long second) : first(first), second(second) {}
  inline pt operator+(const pt &r) const {
    return pt(first + r.first, second + r.second);
  }
  inline pt operator-(const pt &r) const {
    return pt(first - r.first, second - r.second);
  }
  inline bool operator<(const pt &r) const {
    if (first != r.first) return first < r.first;
    return second < r.second;
  }
  inline bool operator==(const pt &r) const {
    return first == r.first && second == r.second;
  }
};
inline long long dot(const pt &l, const pt &r) {
  return l.first * r.first + l.second * r.second;
}
inline long long cross(const pt &l, const pt &r) {
  return l.first * r.second - l.second * r.first;
}
const int N = 100 * 1000;
const int LG = 18;
vector<int> g[N];
int up[N][LG];
int h[N];
int tin[N];
int tout[N];
int timer;
long long sz[N];
long long dp1[N];
long long dp[N];
int n;
void dfs1(int v, int p, int hh = 0) {
  up[v][0] = p;
  for (int i = 1; i < LG; ++i) {
    up[v][i] = up[up[v][i - 1]][i - 1];
  }
  tin[v] = timer++;
  h[v] = hh;
  sz[v] = 1;
  for (int to : g[v]) {
    if (to == p) continue;
    dfs1(to, v, hh + 1);
    dp1[v] += dp1[to] + sz[to];
    sz[v] += sz[to];
  }
  tout[v] = timer++;
}
void dfs2(int v, int p, long long add) {
  dp[v] = dp1[v] + add;
  for (int to : g[v]) {
    if (to == p) continue;
    dfs2(to, v, n - sz[to] + dp[v] - sz[to] - dp1[to]);
  }
}
inline bool isUpper(int a, int b) {
  return tin[a] <= tin[b] && tout[b] <= tout[a];
}
int lca(int a, int b) {
  if (isUpper(a, b)) return a;
  if (isUpper(b, a)) return b;
  for (int i = LG - 1; i >= 0; --i) {
    if (!isUpper(up[a][i], b)) {
      a = up[a][i];
    }
  }
  return up[a][0];
}
double query(int a, int b) {
  int l = lca(a, b);
  int dist = h[a] + h[b] - 2 * h[l];
  if (l != a && l != b) {
    return dist + 1 + (double)dp1[a] / sz[a] + (double)dp1[b] / sz[b];
  }
  if (l == b) swap(a, b);
  int c = b;
  for (int i = LG - 1; i >= 0; --i) {
    if (!isUpper(up[c][i], a)) {
      c = up[c][i];
    }
  }
  long long sza = n - sz[c];
  long long szb = sz[b];
  long long dpb = dp1[b];
  long long dpa = dp[a] - dp1[c] - sz[c];
  return dist + 1 + (double)dpa / sza + (double)dpb / szb;
}
void solve() {
  n = nxt();
  int m = nxt();
  for (int i = 0; i + 1 < n; ++i) {
    int a = nxt() - 1;
    int b = nxt() - 1;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  dfs1(0, 0);
  dfs2(0, 0, 0);
  for (int i = 0; i < m; ++i) {
    int u = nxt() - 1;
    int v = nxt() - 1;
    cout << setprecision(10) << fixed;
    cout << query(u, v) << "\n";
  }
}
int main() {
  solve();
  return 0;
}
