#include <bits/stdc++.h>
int n, m, q;
std::vector<int> g[1 + (2 * 100 * 1000)];
int component[1 + (2 * 100 * 1000)];
int depth[1 + (2 * 100 * 1000)];
int tree_size[1 + (2 * 100 * 1000)];
int tree_diameter[1 + (2 * 100 * 1000)];
double tree_expected_value[1 + (2 * 100 * 1000)];
std::vector<int> tree_depth_count[1 + (2 * 100 * 1000)];
std::vector<int> tree_cumulative_depth_count[1 + (2 * 100 * 1000)];
std::vector<double> tree_depth_probability[1 + (2 * 100 * 1000)];
std::vector<double> tree_cumulative_depth_probability[1 + (2 * 100 * 1000)];
std::vector<double> tree_cumulative_score[1 + (2 * 100 * 1000)];
std::pair<int, int> compute_depth(int d, int v, int p) {
  if (component[v] == 0) {
    component[v] = (p == -1) ? v : component[p];
    tree_size[component[v]]++;
  }
  std::pair<int, int> result = std::make_pair(d, v);
  depth[v] = std::max(depth[v], d);
  for (auto u : g[v]) {
    if (u == p) {
      continue;
    }
    result = std::max(result, compute_depth(d + 1, u, v));
  }
  return result;
}
int main(void) {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int i = 1; i <= n; i++) {
    if (component[i] == 0) {
      auto result = compute_depth(0, i, -1);
      result = compute_depth(0, result.second, -1);
      tree_diameter[i] = compute_depth(0, result.second, -1).first;
      tree_depth_count[i].resize(tree_diameter[i] + 1);
      tree_cumulative_depth_count[i].resize(tree_diameter[i] + 1);
      tree_depth_probability[i].resize(tree_diameter[i] + 1);
      tree_cumulative_depth_probability[i].resize(tree_diameter[i] + 1);
      tree_cumulative_score[i].resize(tree_diameter[i] + 1);
    }
  }
  for (int i = 1; i <= n; i++) {
    const int c = component[i];
    fprintf(stderr, "Node %d is in component %d and has depth %d\n", i, c,
            depth[i]);
    tree_expected_value[c] += (double)depth[i] / tree_size[c];
    tree_depth_count[c][depth[i]]++;
    tree_depth_probability[c][depth[i]] += 1. / tree_size[c];
  }
  for (int i = 1; i <= n; i++) {
    if (i == component[i]) {
      const int c = component[i];
      fprintf(stderr, "Component %d has size %d, diameter %d, overall EV %lf\n",
              i, tree_size[c], tree_diameter[c], tree_expected_value[c]);
      for (int j = 0; j <= tree_diameter[c]; j++) {
        tree_cumulative_depth_count[c][j] =
            tree_depth_count[c][j] +
            ((j == 0) ? 0 : tree_cumulative_depth_count[c][j - 1]);
        tree_cumulative_depth_probability[c][j] =
            tree_depth_probability[c][j] +
            ((j == 0) ? 0 : tree_cumulative_depth_probability[c][j - 1]);
        tree_cumulative_score[c][j] =
            (tree_depth_count[c][j] * j) +
            ((j == 0) ? 0 : tree_cumulative_score[c][j - 1]);
        fprintf(stderr,
                "Probability of picking a node with depth = %d is %lf\n", j,
                tree_depth_probability[c][j]);
        fprintf(stderr, "Among nodes with depth <= %d, EV is %lf\n", j,
                (tree_cumulative_depth_count[c][j] == 0)
                    ? 0
                    : (double)tree_cumulative_score[c][j] /
                          tree_cumulative_depth_count[c][j]);
      }
    }
  }
  while (q--) {
    int u, v;
    scanf("%d %d", &u, &v);
    u = component[u];
    v = component[v];
    if (u != v) {
      if (tree_diameter[u] < tree_diameter[v]) {
        int t = u;
        u = v;
        v = t;
      }
      double result = 1 + tree_expected_value[u] + tree_expected_value[v];
      fprintf(stderr, "Naive solution says %lf for union of %d, %d\n", result,
              u, v);
      double underflow_probability = 0;
      double underflow_score = 0;
      int underflow_count = 0;
      for (int i = 0; i <= std::min(tree_diameter[v], tree_diameter[u] - 1);
           i++) {
        int ub = tree_diameter[u] - 1 - i;
        underflow_probability += tree_depth_probability[v][i] *
                                 tree_cumulative_depth_probability[u][ub];
        underflow_count +=
            tree_depth_count[v][i] * tree_cumulative_depth_count[u][ub];
        if (tree_cumulative_depth_count[u][ub] > 0) {
          underflow_score +=
              (tree_depth_count[v][i] * tree_cumulative_depth_count[u][ub]) *
              ((i + 1) + (double)tree_cumulative_score[u][ub] /
                             tree_cumulative_depth_count[u][ub]);
        }
      }
      fprintf(stderr, "%d\n", underflow_count);
      double underflow_expected_value = underflow_score / underflow_count;
      fprintf(stderr,
              "Taking the union of %d, %d has an underflow probability of %lf, "
              "with expected value %lf\n",
              u, v, underflow_probability, underflow_expected_value);
      if (underflow_count > 0) {
        result += tree_diameter[u] * underflow_probability;
        result -= underflow_expected_value * underflow_probability;
      }
      printf("%lf\n", result);
    } else {
      puts("-1");
    }
  }
  return 0;
}
