#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, q, timer = 0, numTree = 0;
int h[N], x[N], y[N], ver[N], pos[N], f[N], g[N];
int sz[2];
bool fre[N];
vector<int> adj[N], subTree[N], V[N], S[N];
map<int, double> Q[N];
namespace RMQ {
int spT[N][20], lg[N];
void Init() {
  for (int i = 1; i <= n; ++i) spT[i][0] = h[ver[i]];
  for (int j = 1; 1 << j <= n; ++j)
    for (int i = 1; i + (1 << j) - 1 <= n; ++i)
      spT[i][j] = max(spT[i][j - 1], spT[i + (1 << (j - 1))][j - 1]);
  for (int i = 0; 1 << i <= n; ++i) lg[1 << i] = i;
  for (int i = 1; i <= n; ++i)
    if (!lg[i]) lg[i] = lg[i - 1];
}
int GetMax(int l, int r) {
  int k = lg[r - l + 1];
  return max(spT[l][k], spT[r - (1 << k) + 1][k]);
}
};  // namespace RMQ
void DFS(int u, int par = -1) {
  pos[u] = numTree;
  subTree[numTree].push_back(u);
  x[u] = ++timer;
  ver[timer] = u;
  for (int k = 0; k < adj[u].size(); ++k) {
    int v = adj[u][k];
    if (v == par) continue;
    h[v] = h[u] + 1;
    DFS(v, u);
  }
  y[u] = timer;
}
void PreCal(int u, int par = 0) {
  fre[u] = true;
  f[u] = 0;
  if (par != 0) {
    g[u] = max(g[u], g[par] + 1);
    if (x[par] <= x[u] - 1)
      g[u] = max(g[u], RMQ::GetMax(x[par], x[u] - 1) - h[par] + 1);
    if (y[u] + 1 <= y[par])
      g[u] = max(g[u], RMQ::GetMax(y[u] + 1, y[par]) - h[par] + 1);
  }
  for (int k = 0; k < adj[u].size(); ++k) {
    int v = adj[u][k];
    if (v == par) continue;
    PreCal(v, u);
    f[u] = max(f[u], f[v] + 1);
  }
}
double Query(int s, int t) {
  int x = pos[s], y = pos[t];
  if (subTree[x].size() > subTree[y].size()) {
    swap(s, t);
    swap(x, y);
  }
  if (Q[x].count(y)) return Q[x][y];
  int MaxD = max(V[x].back(), V[y].back());
  long long ans = 0;
  for (int i = 0; i < V[x].size(); ++i) {
    int val = V[x][i];
    int j =
        upper_bound(V[y].begin(), V[y].end(), MaxD - val - 1) - V[y].begin();
    ans += (long long)j * MaxD;
    ans += (long long)(val + 1) * (V[y].size() - j) +
           (S[y][V[y].size() - 1] - (j == 0 ? 0 : S[y][j - 1]));
  }
  return Q[x][y] = (double)ans / ((double)V[x].size() * V[y].size());
}
bool cmp(int x, int y) { return f[x] < f[y]; }
void Solve() {
  memset(fre, false, sizeof fre);
  RMQ::Init();
  for (int i = 1; i <= n; ++i)
    if (!fre[i]) PreCal(i);
  for (int i = 1; i <= n; ++i) f[i] = max(f[i], g[i]);
  for (int i = 1; i <= numTree; ++i) {
    for (int k = 0; k < subTree[i].size(); ++k) {
      int u = subTree[i][k];
      V[i].push_back(f[u]);
    }
    sort(V[i].begin(), V[i].end());
    S[i].resize(V[i].size());
    for (int k = 0; k < subTree[i].size(); ++k)
      S[i][k] = k == 0 ? V[i][k] : S[i][k - 1] + V[i][k];
  }
  while (q--) {
    int u, v;
    scanf("%d%d", &u, &v);
    if (pos[u] == pos[v])
      puts("-1");
    else
      printf("%7f\n", Query(u, v));
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= m; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (int i = 1; i <= n; ++i)
    if (x[i] == 0) {
      ++numTree;
      DFS(i);
    }
  Solve();
  return 0;
}
