#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, q, L, R, nowdep, treenum = 0;
int father[N], tr[N], c[N], f[N], d_max[N];
vector<int> v[N], tree[N], dis[N], g[N];
set<int> st;
map<int, int> mp;
map<pair<int, int>, double> ans;
map<pair<int, int>, int> flag;
int getfather(int x) {
  return father[x] ? father[x] = getfather(father[x]) : x;
}
void dfs(int x, int fa, int dep) {
  f[x] = max(f[x], dep);
  for (auto u : v[x]) {
    if (u == fa) continue;
    dfs(u, x, dep + 1);
  }
}
void dfs1(int x, int fa, int dep) {
  if (dep > nowdep) {
    L = x;
    nowdep = dep;
  }
  for (auto u : v[x]) {
    if (u == fa) continue;
    dfs1(u, x, dep + 1);
  }
}
void dfs2(int x, int fa, int dep) {
  if (dep > nowdep) {
    R = x;
    nowdep = dep;
  }
  for (auto u : v[x]) {
    if (u == fa) continue;
    dfs2(u, x, dep + 1);
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &q);
  memset(father, 0, sizeof father);
  for (int i(1); i <= (m); ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    v[x].push_back(y);
    v[y].push_back(x);
    int fa = getfather(x), fb = getfather(y);
    if (fa != fb) father[fa] = fb;
  }
  for (int i(1); i <= (n); ++i) st.insert(getfather(i));
  for (auto u : st) {
    mp[u] = ++treenum;
    tr[treenum] = u;
  }
  for (int i(1); i <= (n); ++i) {
    int x = getfather(i);
    tree[mp[x]].push_back(i);
    c[i] = mp[x];
  }
  memset(f, 0, sizeof f);
  for (int i(1); i <= (treenum); ++i) {
    L = 0;
    nowdep = -1;
    dfs1(tree[i][0], 0, 0);
    R = 0, nowdep = -1;
    dfs2(L, 0, 0);
    dfs(L, 0, 0);
    dfs(R, 0, 0);
    for (auto u : tree[i]) dis[i].push_back(f[u]);
    sort(dis[i].begin(), dis[i].end());
    for (int j(0); j <= ((int)tree[i].size() - 1); ++j) {
      if (j == 0)
        g[i].push_back(dis[i][j]);
      else
        g[i].push_back(g[i][j - 1] + dis[i][j]);
    }
    d_max[i] = dis[i][(int)tree[i].size() - 1];
  }
  ans.clear();
  flag.clear();
  for (; q--;) {
    int x, y;
    scanf("%d%d", &x, &y);
    if (c[x] == c[y]) {
      puts("-1");
      continue;
    }
    int na = c[x], nb = c[y];
    if ((int)tree[na].size() > (int)tree[nb].size()) swap(na, nb);
    if (flag[{na, nb}]) {
      printf("%.12f\n", ans[{na, nb}]);
      continue;
    }
    long long X = 0;
    long long Y = (long long)tree[na].size() * tree[nb].size();
    long long Z = max(d_max[na], d_max[nb]);
    for (auto u1 : tree[na]) {
      long long A = lower_bound(dis[nb].begin(), dis[nb].end(), Z - 1 - f[u1]) -
                    dis[nb].begin();
      X += (long long)A * Z +
           (long long)(g[nb][(int)tree[nb].size() - 1] + (int)tree[nb].size() -
                       A - (A ? g[nb][A - 1] : 0)) +
           (f[u1]) * ((long long)tree[nb].size() - A);
    }
    double cnt_ans = (double)X / (double)Y;
    printf("%.12f\n", cnt_ans);
    flag[{na, nb}] = 1;
    ans[{na, nb}] = cnt_ans;
  }
  return 0;
}
