#include <bits/stdc++.h>
using namespace std;
int const inf = 1000 * 1000 * 1000;
long long const inf64 = 1ll * inf * inf;
int const N = 1e5 + 5;
int const SQRT = 320;
int n, m, q;
vector<int> g[N];
void readGraph() {
  scanf("%d %d %d", &n, &m, &q);
  for (int u, v, i = 0; i < m; i++) {
    scanf("%d %d", &u, &v);
    g[u].push_back(v);
    g[v].push_back(u);
  }
}
bool isTree[N];
int cid[N];
bool used[N];
int mx[N];
int dn[N];
int cntv[N];
vector<int> arr[N];
vector<long long> pref[N];
int cur = 1;
void go1(int v, int par = -1) {
  dn[v] = 0;
  for (int to : g[v]) {
    if (to == par) continue;
    go1(to, v);
    dn[v] = max(dn[v], dn[to] + 1);
  }
}
void go2(int v, int up = 0, int par = -1) {
  int mx1 = -10;
  int mx2 = -10;
  mx[v] = max(up, dn[v]);
  for (int to : g[v]) {
    if (to == par) continue;
    if (mx1 < dn[to]) {
      mx2 = mx1;
      mx1 = dn[to];
    } else if (mx2 < dn[to]) {
      mx2 = dn[to];
    }
  }
  for (int to : g[v]) {
    if (to == par) continue;
    int tmp = up;
    if (mx1 == dn[to])
      tmp = max(tmp, mx2 + 1);
    else
      tmp = max(tmp, mx1 + 1);
    go2(to, tmp + 1, v);
  }
}
void buildComponents() {
  for (int i = 1; i <= n; i++) {
    used[i] = 0;
  }
  queue<int> que;
  for (int i = 1; i <= n; i++) {
    if (used[i]) continue;
    que.push(i);
    used[i] = 1;
    cid[i] = cur;
    cntv[cur] = 1;
    int cnte = (int)g[i].size();
    vector<int> List;
    List.push_back(i);
    while (!que.empty()) {
      int v = que.front();
      que.pop();
      for (int to : g[v]) {
        if (!used[to]) {
          used[to] = 1;
          cid[to] = cur;
          que.push(to);
          cntv[cur]++;
          cnte += (int)g[to].size();
          List.push_back(to);
        }
      }
    }
    cnte /= 2;
    isTree[cur] = cnte == cntv[cur] - 1;
    if (isTree[cur]) {
      go1(i);
      go2(i);
      long long cur_pref = 0;
      for (int v : List) {
        arr[cur].push_back(mx[v]);
      }
      sort((arr[cur]).begin(), (arr[cur]).end());
      for (int x : arr[cur]) {
        cur_pref += x;
        pref[cur].push_back(cur_pref);
      }
    }
    cur++;
  }
}
bool alreadyAns[N];
double answer[N];
vector<pair<int, int> > query[N];
void readQuestions() {
  for (int v, u, iter = 0; iter < q; iter++) {
    scanf("%d %d", &u, &v);
    if (cid[u] == cid[v]) {
      alreadyAns[iter] = 1;
      answer[iter] = -1.0;
    } else if (!isTree[cid[u]] || !isTree[cid[v]]) {
      alreadyAns[iter] = 1;
      answer[iter] = -1.0;
    } else {
      if (cntv[cid[u]] > cntv[cid[v]]) swap(u, v);
      query[cid[u]].push_back(make_pair(cid[v], iter));
    }
  }
  for (int i = 1; i <= n; i++) {
    sort((query[i]).begin(), (query[i]).end());
  }
}
int main() {
  readGraph();
  buildComponents();
  readQuestions();
  for (int iter = 1; iter < cur; iter++) {
    if (cntv[iter] < SQRT) {
      for (int j = 0; j < (int)query[iter].size(); j++) {
        int t = j;
        while (t < (int)query[iter].size() &&
               query[iter][j].first == query[iter][t].first)
          t++;
        t--;
        vector<int>& arr1 = arr[iter];
        vector<int>& arr2 = arr[query[iter][j].first];
        int D = max(arr1.back(), arr2.back());
        long long tot = 0;
        long long tot_cnt = 0;
        for (int m1 : arr1) {
          int id = upper_bound((arr2).begin(), (arr2).end(), D - 1 - m1) -
                   arr2.begin();
          if (id < (int)arr2.size()) {
            tot += pref[query[iter][j].first].back() -
                   (id > 0 ? pref[query[iter][j].first][id - 1] : 0ll);
            tot += 1ll * (m1 + 1) * ((int)arr2.size() - id);
            tot_cnt += (int)arr2.size() - id;
          }
        }
        tot += 1ll * (1ll * (int)arr1.size() * (int)arr2.size() - tot_cnt) * D;
        double cur_ans =
            1.0 * tot / (1.0 * (int)arr1.size() * (int)arr2.size());
        for (int qid, it = j; it <= t; it++) {
          qid = query[iter][it].second;
          alreadyAns[qid] = 1;
          answer[qid] = cur_ans;
        }
        j = t;
      }
    } else {
      for (int j = 0; j < (int)query[iter].size(); j++) {
        int t = j;
        while (t < (int)query[iter].size() &&
               query[iter][j].first == query[iter][t].first)
          t++;
        t--;
        vector<int>& arr1 = arr[iter];
        vector<int>& arr2 = arr[query[iter][j].first];
        int D = max(arr1.back(), arr2.back());
        long long tot = 0;
        long long tot_cnt = 0;
        for (int m2 : arr2) {
          int id = upper_bound((arr1).begin(), (arr1).end(), D - 1 - m2) -
                   arr1.begin();
          if (id < (int)arr1.size()) {
            tot += pref[iter].back() - (id > 0 ? pref[iter][id - 1] : 0);
            tot += 1ll * (m2 + 1) * ((int)arr1.size() - id);
            tot_cnt += (int)arr1.size() - id;
          }
        }
        tot += 1ll * (1ll * (int)arr1.size() * (int)arr2.size() - tot_cnt) * D;
        double cur_ans =
            1.0 * tot / (1.0 * (int)arr1.size() * (int)arr2.size());
        for (int qid, it = j; it <= t; it++) {
          qid = query[iter][it].second;
          alreadyAns[qid] = 1;
          answer[qid] = cur_ans;
        }
        j = t;
      }
    }
  }
  for (int i = 0; i < q; i++) {
    printf("%.10lf\n", answer[i]);
  }
  return 0;
}
