#include <bits/stdc++.h>
using namespace std;
const int kMaxN = 3e5 + 10;
const int kMod = 1e9 + 7;
class CentroidOperations {
  int n;
  int farthest;
  vector<vector<int>> tree;
  vector<int> sub, maxSub, from, depth;
  vector<int> sol;

 public:
  void layerDfs(int x, int f) {
    from[x] = f;
    depth[x] = (f == -1 ? 0 : depth[f] + 1);
    if (depth[x] > depth[farthest]) {
      farthest = x;
    }
    for (auto y : tree[x]) {
      if (y == f || y == -1) continue;
      layerDfs(y, x);
    }
  }
  int getFarthest(int root) {
    if (from.size() < n + 1) {
      from.resize(n + 1);
      depth.resize(n + 1);
    }
    farthest = root;
    layerDfs(root, -1);
    return farthest;
  }
  vector<int> getDiameter(int root) {
    int start = getFarthest(root);
    int end = getFarthest(start);
    vector<int> diameter;
    for (int i = end; i != -1; i = from[i]) diameter.push_back(i);
    return diameter;
  }
  vector<int> getCenters(int root) {
    auto diam = getDiameter(root);
    int half = diam.size() / 2;
    if (diam.size() & 1) {
      return {diam[half]};
    } else {
      return {diam[half - 1], diam[half]};
    }
  }
  void subDfs(int x, int f) {
    sub[x] = 1;
    for (auto y : tree[x]) {
      if (y == f || y == -1) continue;
      subDfs(y, x);
      sub[x] += sub[y];
    }
  }
  void centroidDfs(int x, int f, int n) {
    sub[x] = 1;
    maxSub[x] = 0;
    for (auto y : tree[x]) {
      if (y == f || y == -1) continue;
      centroidDfs(y, x, n);
      maxSub[x] = max(maxSub[x], sub[y]);
      sub[x] += sub[y];
    }
    maxSub[x] = max(maxSub[x], n - sub[x]);
    if (sol.empty() || maxSub[sol[0]] > maxSub[x]) {
      sol = {x};
    } else if (maxSub[sol[0]] == maxSub[x]) {
      sol.push_back(x);
    }
  }
  vector<int> getCentroids(int root, int n) {
    if (sub.size() < this->n + 1) {
      sub.resize(this->n + 1);
      maxSub.resize(this->n + 1);
    }
    sol = {};
    centroidDfs(root, 0, n);
    return sol;
  }
  void centroidDecomposition(int root, int father, int n) {
    int rememberPos = -1;
    for (int i = 0; i < tree[root].size(); ++i) {
      if (tree[root][i] == father) {
        tree[root][i] = -1;
        rememberPos = i;
      }
    }
    auto centroid = getCentroids(root, n)[0];
    for (auto son : tree[centroid]) {
      if (son != -1) {
        subDfs(son, centroid);
        centroidDecomposition(son, centroid, sub[son]);
      }
    }
    if (rememberPos != -1) tree[root][rememberPos] = father;
  }
  CentroidOperations(const vector<vector<int>>& tree) : tree(tree) {
    n = tree.size() - 1;
  }
};
void dfs(int x, vector<int>& comp, int c, vector<bool>& vis, vector<int>& which,
         vector<vector<int>>& T) {
  vis[x] = true;
  which[x] = c;
  comp.push_back(x);
  for (auto y : T[x]) {
    if (!vis[y]) dfs(y, comp, c, vis, which, T);
  }
}
void depth_dfs(int x, int f, vector<int>& depth, vector<vector<int>>& T,
               int d) {
  depth[x] = max(depth[x], d);
  for (auto y : T[x]) {
    if (y == f) continue;
    depth_dfs(y, x, depth, T, d + 1);
  }
}
double Solve(int a, int b, vector<int>& big_diam,
             vector<vector<long long>>& diams) {
  if (diams[a].size() > diams[b].size()) swap(a, b);
  int threshold = max(big_diam[a], big_diam[b]);
  long long all_pairs = 1LL * diams[a].size() * diams[b].size();
  long long good_pairs = 0;
  double good_sum = 0;
  for (int i = 0; i < diams[a].size(); ++i) {
    long long now =
        diams[a][i] - (i == diams[a].size() - 1 ? 0 : diams[a][i + 1]);
    int lo = -1, hi = diams[b].size();
    while (hi - lo > 1) {
      int mid = (lo + hi) >> 1;
      long long here =
          diams[b][mid] - (mid == diams[b].size() - 1 ? 0 : diams[b][mid + 1]);
      if (now + here + 1 < threshold) {
        lo = mid;
      } else {
        hi = mid;
      }
    }
    int cnt = diams[b].size() - hi;
    long long sum = (hi == diams[b].size() ? 0 : diams[b][hi]);
    good_sum += 1.0 * (sum + cnt * now + cnt) / all_pairs;
    good_pairs += cnt;
  }
  return good_sum + (1 - 1.0 * good_pairs / all_pairs) * threshold;
}
void solve() {
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  vector<vector<int>> T(n + 1);
  for (int i = 1; i <= m; ++i) {
    int a, b;
    scanf("%d %d", &a, &b);
    T[a].push_back(b);
    T[b].push_back(a);
  }
  vector<vector<int>> comps;
  vector<bool> vis(n + 1);
  vector<int> depth(n + 1), which(n + 1);
  for (int i = 1; i <= n; ++i) {
    if (!vis[i]) {
      vector<int> comp;
      dfs(i, comp, comps.size(), vis, which, T);
      comps.push_back(comp);
    }
  }
  vector<int> big_diam;
  vector<vector<long long>> diams;
  CentroidOperations ops(T);
  for (auto& comp : comps) {
    auto diameter = ops.getDiameter(comp[0]);
    big_diam.push_back(diameter.size() - 1);
    depth_dfs(diameter.front(), 0, depth, T, 0);
    depth_dfs(diameter.back(), 0, depth, T, 0);
    vector<long long> diam;
    diam.reserve(comp.size());
    for (auto& el : comp) {
      diam.push_back(depth[el]);
    }
    sort(diam.begin(), diam.end());
    for (int i = diam.size() - 2; i >= 0; --i) {
      diam[i] += diam[i + 1];
    }
    diams.push_back(diam);
  }
  map<pair<int, int>, double> M;
  for (int i = 1; i <= q; ++i) {
    int a, b;
    scanf("%d %d", &a, &b);
    a = which[a];
    b = which[b];
    if (a > b) swap(a, b);
    if (a == b) {
      cout << -1 << "\n";
      continue;
    }
    if (M.find(make_pair(a, b)) == M.end()) {
      M[make_pair(a, b)] = Solve(a, b, big_diam, diams);
    }
    cout << fixed << setprecision(8) << M[make_pair(a, b)] << "\n";
  }
}
void reset() {}
int main() {
  int tests = 1;
  for (; tests; --tests) {
    solve();
    reset();
  }
}
