#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> adj;
vector<int> component;
void dfs(int v, int p, int c) {
  component[v] = c;
  for (int u : adj[v])
    if (u != p) dfs(u, v, c);
}
int diameter;
struct S {
  int largest_down1;
  int idx1;
  int largest_down2;
  int idx2;
  int mdist;
};
vector<S> data;
void max_dist(int v, int p) {
  for (int u : adj[v]) {
    if (u != p) {
      max_dist(u, v);
      if (data[u].largest_down1 + 1 > data[v].largest_down1) {
        data[v].largest_down2 = data[v].largest_down1;
        data[v].idx2 = data[v].idx1;
        data[v].largest_down1 = data[u].largest_down1 + 1;
        data[v].idx1 = u;
      } else if (data[u].largest_down1 + 1 > data[v].largest_down2) {
        data[v].largest_down2 = data[u].largest_down1 + 1;
        data[v].idx2 = u;
      }
    }
  }
  diameter = max(diameter, data[v].largest_down1 + data[v].largest_down2);
}
void top_down(int v, int p, int down) {
  data[v].mdist = max(down, data[v].largest_down1);
  for (int u : adj[v]) {
    if (u != p) {
      int l = down + 1;
      if (data[v].idx1 != u) l = max(l, data[v].largest_down1 + 1);
      if (data[v].idx2 != u) l = max(l, data[v].largest_down2 + 1);
      top_down(u, v, l);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, m, q;
  cin >> n >> m >> q;
  adj.resize(n);
  data.assign(n, {0, -1, 0, -1, 0});
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    --u, --v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  vector<pair<int, int>> queries(q);
  for (int idx = 0; idx < q; idx++)
    cin >> queries[idx].first >> queries[idx].second;
  vector<int> diameters(n + 1);
  component.assign(n, -1);
  int c = 0;
  for (int i = 0; i < n; i++) {
    if (component[i] == -1) {
      dfs(i, -1, c);
      diameter = 0;
      max_dist(i, -1);
      diameters[c] = diameter;
      top_down(i, -1, 0);
      c++;
    }
  }
  vector<vector<int>> dists(c), psums(c);
  for (int i = 0; i < n; i++) {
    dists[component[i]].push_back(data[i].mdist);
  }
  for (int i = 0; i < c; i++) sort(dists[i].begin(), dists[i].end());
  for (int i = 0; i < c; i++) {
    psums[i].resize(dists[i].size() + 1);
    psums[i][0] = 0;
    for (int j = 0; j < dists[i].size(); j++)
      psums[i][j + 1] += psums[i][j] + dists[i][j];
  }
  cout.precision(10);
  cout << fixed;
  map<pair<int, int>, double> memo;
  for (auto q : queries) {
    int a = component[q.first - 1];
    int b = component[q.second - 1];
    if (a == b) {
      cout << -1 << '\n';
      continue;
    }
    auto p = make_pair(min(a, b), max(a, b));
    if (memo.count(p)) {
      cout << memo[p] << '\n';
      continue;
    }
    auto& v1 = dists[a];
    auto& v2 = dists[b];
    int x = max(diameters[a], diameters[b]);
    double xxx = 0;
    double psum = 0;
    if (v1.size() < v2.size()) {
      int i2 = v2.size();
      for (int i1 = 0; i1 < v1.size(); i1++) {
        auto it = lower_bound(v2.begin(), v2.begin() + i2, x - v1[i1] - 1);
        i2 = it - v2.begin();
        psum = psums[b].back() - psums[b][i2];
        xxx += (double)i2 * x;
        xxx += psum + (v2.size() - i2) * (double)(v1[i1] + 1);
      }
    } else {
      int i1 = v1.size();
      for (int i2 = 0; i2 < v2.size(); i2++) {
        auto it = lower_bound(v1.begin(), v1.begin() + i1, x - v2[i2] - 1);
        i1 = it - v1.begin();
        psum = psums[a].back() - psums[a][i1];
        xxx += (double)i1 * x;
        xxx += psum + (v1.size() - i1) * (double)(v2[i2] + 1);
      }
    }
    xxx /= v1.size();
    xxx /= v2.size();
    cout << xxx << '\n';
    memo[p] = xxx;
  }
}
