#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <ctype.h>
#include <deque>
#include <queue>
#include <cstring>
#include <set>
#include <list>
#include <map>
#include <random>
#include <unordered_map>
#include <stdio.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef std::vector<int> vi;
typedef std::vector<bool> vb;
typedef std::vector<string> vs;
typedef std::vector<double> vd;
typedef std::vector<long long> vll;
typedef std::vector<std::vector<int> > vvi;
typedef vector<vvi> vvvi;
typedef vector<vll> vvll;
typedef std::vector<std::pair<int, int> > vpi;
typedef vector<vpi> vvpi;
typedef std::pair<int, int> pi;
typedef std::pair<ll, ll> pll;
typedef std::vector<pll> vpll;
typedef std::vector<vpll> vvpll;

const long long mod = 1000000007;

#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define forn(i, a, b) for(int i = a; i < b; i++)

#define pb push_back
#define mp make_pair

const int MAXN = 100100;
vector<int> lst[MAXN];
int parent[MAXN];

void make_set (int v) {
    lst[v] = vector<int> (1, v);
    parent[v] = v;
}

int find_set (int v) {
    return parent[v];
}

void union_sets (int a, int b) {
    a = find_set (a);
    b = find_set (b);
    if (a != b) {
        if (lst[a].size() < lst[b].size())
            swap (a, b);
        while (!lst[b].empty()) {
            int v = lst[b].back();
            lst[b].pop_back();
            parent[v] = a;
            lst[a].push_back (v);
        }

    }
}

vvi nb;
vi diam;
set<pi> done;
map<pi, double> ans;
vvi dist;
vvpll gdist;
int n,m,q;
int A = 300;

bool big(int v) {
    return lst[v].size() > A;
}

struct b2 {
    int a = 0, b = 0;
    void upd(int c) {
        if(c >= a) {
            b = a;
            a = c;
        }
        else if(c > b) {
            b = c;
        }
    }
    int res() {
        return a + b;
    }
};
vector<b2> w;

void dfsd(int v, int p) {
    for(auto u : nb[v]) {
        if (u == p) continue;
        dfsd(u,v);
//        bd[v] = max(bd[v], 1+bd[u]);
        w[v].upd(1+w[u].a);
    }
}

void dfsu(int v, int p) {
    for(auto u : nb[v]) {
        if (u == p) continue;
        int wd = w[u].a + 1;
        if (wd == w[v].a) w[u].upd(w[v].b+1);
        else w[u].upd(w[v].a+1);
        dfsu(u,v);
    }
    diam[find_set(v)] = max(diam[find_set(v)], w[v].res());
    dist[find_set(v)].pb(w[v].a);
}

void get_dist(int v) {
    dfsd(v, -1);
    dfsu(v, -1);
}

void pre() {
    dist.resize(n);
    gdist.resize(n);
    diam.resize(n);
    w.resize(n);
    forn(i,0,n) if(lst[i].size() > 0) get_dist(i);
    forn(i,0,n) sort(all(dist[i]));
    forn(i,0,n) {
        int last = -1;
        for(auto x : dist[i]) {
            if(x==last) gdist[i].back().second++;
            else {
                last = x;
                gdist[i].pb(mp(last,1));
            }
        }
    }
//    forn(i,0,n) if(big(i)) {
//        get_dist(i);
//    }
}

void build(int u, int v) {
    ll was = max(diam[u], diam[v]);
    int pt = 0;
    if(gdist[u].size() < gdist[v].size()) swap(u,v);
    ll cntless = 0;
    ll cntmore = dist[v].size();
    ll tot = 0;
    ll tres = 0;
    for(auto x : gdist[v]) tot += (x.first+1) * x.second;
    for(int i = gdist[u].size() - 1; i >= 0; i--) {
        while(pt < gdist[v].size() && gdist[v][pt].first + 1 + gdist[u][i].first <= was) {
            pll x = gdist[v][pt];
            tot -= (x.first+1) * x.second;
            pt++;
            cntless += x.second;
            cntmore -= x.second;
        }
        tres += (gdist[u][i].first * cntmore + tot + was * cntless) * gdist[u][i].second;
    }

    double res = (ld)tres / ((ll) dist[u].size() * (ll) dist[v].size());
    done.insert(mp(u,v));
    done.insert(mp(v,u));
    ans[mp(u,v)] = res;
    ans[mp(v,u)] = res;
}

double get(int u, int v) {
    u = find_set(u);
    v = find_set(v);
    if (u > v) swap(u,v);
    if (u == v) return -1;
    if (done.find(mp(u,v)) != done.end()) return ans[mp(u,v)];
    build(u, v);
    return ans[mp(u,v)];
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif

    scanf("%d %d %d", &n, &m, &q);
    nb.resize(n);
    forn(i,0,n) make_set(i);
    forn(i,0,m) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--; v--;
        nb[u].pb(v);
        nb[v].pb(u);
        union_sets(u, v);
    }
    pre();
    forn(i,0,q) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--; v--;
        printf("%.10lf\n", get(u,v));
    }
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <ctype.h>
#include <deque>
#include <queue>
#include <cstring>
#include <set>
#include <list>
#include <map>
#include <random>
#include <unordered_map>
#include <stdio.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef std::vector<int> vi;
typedef std::vector<bool> vb;
typedef std::vector<string> vs;
typedef std::vector<double> vd;
typedef std::vector<long long> vll;
typedef std::vector<std::vector<int> > vvi;
typedef vector<vvi> vvvi;
typedef vector<vll> vvll;
typedef std::vector<std::pair<int, int> > vpi;
typedef vector<vpi> vvpi;
typedef std::pair<int, int> pi;
typedef std::pair<ll, ll> pll;
typedef std::vector<pll> vpll;
typedef std::vector<vpll> vvpll;

const long long mod = 1000000007;

#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define forn(i, a, b) for(int i = a; i < b; i++)

#define pb push_back
#define mp make_pair

const int MAXN = 100100;
vector<int> lst[MAXN];
int parent[MAXN];

void make_set (int v) {
    lst[v] = vector<int> (1, v);
    parent[v] = v;
}

int find_set (int v) {
    return parent[v];
}

void union_sets (int a, int b) {
    a = find_set (a);
    b = find_set (b);
    if (a != b) {
        if (lst[a].size() < lst[b].size())
            swap (a, b);
        while (!lst[b].empty()) {
            int v = lst[b].back();
            lst[b].pop_back();
            parent[v] = a;
            lst[a].push_back (v);
        }

    }
}

vvi nb;
vi diam;
set<pi> done;
map<pi, double> ans;
vvi dist;
vvpll gdist;
int n,m,q;
int A = 300;

bool big(int v) {
    return lst[v].size() > A;
}

struct b2 {
    int a = 0, b = 0;
    void upd(int c) {
        if(c >= a) {
            b = a;
            a = c;
        }
        else if(c > b) {
            b = c;
        }
    }
    int res() {
        return a + b;
    }
};
vector<b2> w;
vll wtot;
vd ans1,ans2;

void dfsd(int v, int p) {
    for(auto u : nb[v]) {
        if (u == p) continue;
        dfsd(u,v);
//        bd[v] = max(bd[v], 1+bd[u]);
        w[v].upd(1+w[u].a);
    }
}

void dfsu(int v, int p) {
    for(auto u : nb[v]) {
        if (u == p) continue;
        int wd = w[u].a + 1;
        if (wd == w[v].a) w[u].upd(w[v].b+1);
        else w[u].upd(w[v].a+1);
        dfsu(u,v);
    }
    diam[find_set(v)] = max(diam[find_set(v)], w[v].res());
    dist[find_set(v)].pb(w[v].a);
}

void get_dist(int v) {
    dfsd(v, -1);
    dfsu(v, -1);
}

void pre() {
    dist.resize(n);
    ans1.resize(n);
    ans2.resize(n);
    gdist.resize(n);
    diam.resize(n);
    w.resize(n);
    forn(i,0,n) if(lst[i].size() > 0) get_dist(i);
    forn(i,0,n) sort(all(dist[i]));
    forn(i,0,n) {
        int last = -1;
        for(auto x : dist[i]) {
            if(x==last) gdist[i].back().second++;
            else {
                last = x;
                gdist[i].pb(mp(last,1));
            }
        }
    }
    forn(v,0,n) for(auto x : gdist[v]) wtot[v] += (x.first+1) * x.second;
    forn(v,0,n) {
        if(gdist[v].size() > 0) {
            ll cnt = dist[v].size();
            ll cmax = gdist[v].back().second;
            ans1[v] = (cnt)*diam[v] + cmax;
            ans1[v] /= cnt;
        }
    }

//    forn(i,0,n) if(big(i)) {
//        get_dist(i);
//    }
}

void build(int u, int v) {
    if(dist[u].size() == 1){
        double res = ans1[v];
        done.insert(mp(u,v));
        done.insert(mp(v,u));
        ans[mp(u,v)] = res;
        ans[mp(v,u)] = res;
        return;
    }
    if(dist[v].size() == 1){
        double res = ans1[u];
        done.insert(mp(u,v));
        done.insert(mp(v,u));
        ans[mp(u,v)] = res;
        ans[mp(v,u)] = res;
        return;
    }
//    if(dist[u].size() == 2){
//        double res = ans2[v];
//        done.insert(mp(u,v));
//        done.insert(mp(v,u));
//        ans[mp(u,v)] = res;
//        ans[mp(v,u)] = res;
//        return;
//    }
//    if(dist[v].size() == 2){
//        double res = ans2[u];
//        done.insert(mp(u,v));
//        done.insert(mp(v,u));
//        ans[mp(u,v)] = res;
//        ans[mp(v,u)] = res;
//        return;
//    }
    ll was = max(diam[u], diam[v]);
    int pt = 0;
    if(gdist[u].size() < gdist[v].size()) swap(u,v);
    ll cntless = 0;
    ll cntmore = dist[v].size();
    ll tot = wtot[v];
    ll tres = 0;

    for(int i = gdist[u].size() - 1; i >= 0; i--) {
        while(pt < gdist[v].size() && gdist[v][pt].first + 1 + gdist[u][i].first <= was) {
            pll x = gdist[v][pt];
            tot -= (x.first+1) * x.second;
            pt++;
            cntless += x.second;
            cntmore -= x.second;
        }
        tres += (gdist[u][i].first * cntmore + tot + was * cntless) * gdist[u][i].second;
    }

    double res = (ld)tres / ((ll) dist[u].size() * (ll) dist[v].size());
    done.insert(mp(u,v));
    done.insert(mp(v,u));
    ans[mp(u,v)] = res;
    ans[mp(v,u)] = res;
}

double get(int u, int v) {
    u = find_set(u);
    v = find_set(v);
    if (u > v) swap(u,v);
    if (u == v) return -1;
    if (done.find(mp(u,v)) != done.end()) return ans[mp(u,v)];
    build(u, v);
    return ans[mp(u,v)];
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif

    scanf("%d %d %d", &n, &m, &q);
    nb.resize(n);
    forn(i,0,n) make_set(i);
    forn(i,0,m) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--; v--;
        nb[u].pb(v);
        nb[v].pb(u);
        union_sets(u, v);
    }
    pre();
    forn(i,0,q) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--; v--;
        printf("%.10lf\n", get(u,v));
    }
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <ctype.h>
#include <deque>
#include <queue>
#include <cstring>
#include <set>
#include <list>
#include <map>
#include <random>
#include <unordered_map>
#include <stdio.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef std::vector<int> vi;
typedef std::vector<bool> vb;
typedef std::vector<string> vs;
typedef std::vector<double> vd;
typedef std::vector<long long> vll;
typedef std::vector<std::vector<int> > vvi;
typedef vector<vvi> vvvi;
typedef vector<vll> vvll;
typedef std::vector<std::pair<int, int> > vpi;
typedef vector<vpi> vvpi;
typedef std::pair<int, int> pi;
typedef std::pair<ll, ll> pll;
typedef std::vector<pll> vpll;
typedef std::vector<vpll> vvpll;

const long long mod = 1000000007;

#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define forn(i, a, b) for(int i = a; i < b; i++)

#define pb push_back
#define mp make_pair

const int MAXN = 100100;
vector<int> lst[MAXN];
int parent[MAXN];

void make_set (int v) {
    lst[v] = vector<int> (1, v);
    parent[v] = v;
}

int find_set (int v) {
    return parent[v];
}

void union_sets (int a, int b) {
    a = find_set (a);
    b = find_set (b);
    if (a != b) {
        if (lst[a].size() < lst[b].size())
            swap (a, b);
        while (!lst[b].empty()) {
            int v = lst[b].back();
            lst[b].pop_back();
            parent[v] = a;
            lst[a].push_back (v);
        }

    }
}

vvi nb;
vi diam;
set<pi> done;
map<pi, double> ans;
vvi dist;
vvpll gdist;
int n,m,q;
int A = 300;

bool big(int v) {
    return lst[v].size() > A;
}

struct b2 {
    int a = 0, b = 0;
    void upd(int c) {
        if(c >= a) {
            b = a;
            a = c;
        }
        else if(c > b) {
            b = c;
        }
    }
    int res() {
        return a + b;
    }
};
vector<b2> w;
vll wtot;
vd ans1,ans2;

void dfsd(int v, int p) {
    for(auto u : nb[v]) {
        if (u == p) continue;
        dfsd(u,v);
//        bd[v] = max(bd[v], 1+bd[u]);
        w[v].upd(1+w[u].a);
    }
}

void dfsu(int v, int p) {
    for(auto u : nb[v]) {
        if (u == p) continue;
        int wd = w[u].a + 1;
        if (wd == w[v].a) w[u].upd(w[v].b+1);
        else w[u].upd(w[v].a+1);
        dfsu(u,v);
    }
    diam[find_set(v)] = max(diam[find_set(v)], w[v].res());
    dist[find_set(v)].pb(w[v].a);
}

void get_dist(int v) {
    dfsd(v, -1);
    dfsu(v, -1);
}

void pre() {
    dist.resize(n);
    ans1.resize(n);
    ans2.resize(n);
    gdist.resize(n);
    diam.resize(n);
    wtot.resize(n);
    w.resize(n);
    forn(i,0,n) if(lst[i].size() > 0) get_dist(i);
    forn(i,0,n) sort(all(dist[i]));
    forn(i,0,n) {
        int last = -1;
        for(auto x : dist[i]) {
            if(x==last) gdist[i].back().second++;
            else {
                last = x;
                gdist[i].pb(mp(last,1));
            }
        }
    }
    forn(v,0,n) for(auto x : gdist[v]) wtot[v] += (x.first+1) * x.second;
    forn(v,0,n) {
        if(gdist[v].size() > 0) {
            ll cnt = dist[v].size();
            ll cmax = gdist[v].back().second;
            ans1[v] = (cnt)*diam[v] + cmax;
            ans1[v] /= cnt;
        }
    }

//    forn(i,0,n) if(big(i)) {
//        get_dist(i);
//    }
}

void build(int u, int v) {
    if(dist[u].size() == 1){
        double res = ans1[v];
        done.insert(mp(u,v));
        done.insert(mp(v,u));
        ans[mp(u,v)] = res;
        ans[mp(v,u)] = res;
        return;
    }
    if(dist[v].size() == 1){
        double res = ans1[u];
        done.insert(mp(u,v));
        done.insert(mp(v,u));
        ans[mp(u,v)] = res;
        ans[mp(v,u)] = res;
        return;
    }
//    if(dist[u].size() == 2){
//        double res = ans2[v];
//        done.insert(mp(u,v));
//        done.insert(mp(v,u));
//        ans[mp(u,v)] = res;
//        ans[mp(v,u)] = res;
//        return;
//    }
//    if(dist[v].size() == 2){
//        double res = ans2[u];
//        done.insert(mp(u,v));
//        done.insert(mp(v,u));
//        ans[mp(u,v)] = res;
//        ans[mp(v,u)] = res;
//        return;
//    }
    ll was = max(diam[u], diam[v]);
    int pt = 0;
    if(gdist[u].size() < gdist[v].size()) swap(u,v);
    ll cntless = 0;
    ll cntmore = dist[v].size();
    ll tot = wtot[v];
    ll tres = 0;

    for(int i = gdist[u].size() - 1; i >= 0; i--) {
        while(pt < gdist[v].size() && gdist[v][pt].first + 1 + gdist[u][i].first <= was) {
            pll x = gdist[v][pt];
            tot -= (x.first+1) * x.second;
            pt++;
            cntless += x.second;
            cntmore -= x.second;
        }
        tres += (gdist[u][i].first * cntmore + tot + was * cntless) * gdist[u][i].second;
    }

    double res = (ld)tres / ((ll) dist[u].size() * (ll) dist[v].size());
    done.insert(mp(u,v));
    done.insert(mp(v,u));
    ans[mp(u,v)] = res;
    ans[mp(v,u)] = res;
}

double get(int u, int v) {
    u = find_set(u);
    v = find_set(v);
    if (u > v) swap(u,v);
    if (u == v) return -1;
    if (done.find(mp(u,v)) != done.end()) return ans[mp(u,v)];
    build(u, v);
    return ans[mp(u,v)];
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif

    scanf("%d %d %d", &n, &m, &q);
    nb.resize(n);
    forn(i,0,n) make_set(i);
    forn(i,0,m) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--; v--;
        nb[u].pb(v);
        nb[v].pb(u);
        union_sets(u, v);
    }
    pre();
    forn(i,0,q) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--; v--;
        printf("%.10lf\n", get(u,v));
    }
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <ctype.h>
#include <deque>
#include <queue>
#include <cstring>
#include <set>
#include <list>
#include <map>
#include <random>
#include <unordered_map>
#include <stdio.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef std::vector<int> vi;
typedef std::vector<bool> vb;
typedef std::vector<string> vs;
typedef std::vector<double> vd;
typedef std::vector<long long> vll;
typedef std::vector<std::vector<int> > vvi;
typedef vector<vvi> vvvi;
typedef vector<vll> vvll;
typedef std::vector<std::pair<int, int> > vpi;
typedef vector<vpi> vvpi;
typedef std::pair<int, int> pi;
typedef std::pair<ll, ll> pll;
typedef std::vector<pll> vpll;
typedef std::vector<vpll> vvpll;

const long long mod = 1000000007;

#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define forn(i, a, b) for(int i = a; i < b; i++)

#define pb push_back
#define mp make_pair

const int MAXN = 100100;
vector<int> lst[MAXN];
int parent[MAXN];

void make_set (int v) {
    lst[v] = vector<int> (1, v);
    parent[v] = v;
}

int find_set (int v) {
    return parent[v];
}

void union_sets (int a, int b) {
    a = find_set (a);
    b = find_set (b);
    if (a != b) {
        if (lst[a].size() < lst[b].size())
            swap (a, b);
        while (!lst[b].empty()) {
            int v = lst[b].back();
            lst[b].pop_back();
            parent[v] = a;
            lst[a].push_back (v);
        }

    }
}

vvi nb;
vi diam;
set<pi> done;
map<pi, double> ans;
vvi dist;
vvpll gdist;
int n,m,q;
int A = 300;

bool big(int v) {
    return lst[v].size() > A;
}

struct b2 {
    int a = 0, b = 0;
    void upd(int c) {
        if(c >= a) {
            b = a;
            a = c;
        }
        else if(c > b) {
            b = c;
        }
    }
    int res() {
        return a + b;
    }
};
vector<b2> w;

void dfsd(int v, int p) {
    for(auto u : nb[v]) {
        if (u == p) continue;
        dfsd(u,v);
//        bd[v] = max(bd[v], 1+bd[u]);
        w[v].upd(1+w[u].a);
    }
}

void dfsu(int v, int p) {
    for(auto u : nb[v]) {
        if (u == p) continue;
        int wd = w[u].a + 1;
        if (wd == w[v].a) w[u].upd(w[v].b+1);
        else w[u].upd(w[v].a+1);
        dfsu(u,v);
    }
    diam[find_set(v)] = max(diam[find_set(v)], w[v].res());
    dist[find_set(v)].pb(w[v].a);
}

void get_dist(int v) {
    dfsd(v, -1);
    dfsu(v, -1);
}

void pre() {
    dist.resize(n);
    gdist.resize(n);
    diam.resize(n);
    w.resize(n);
    forn(i,0,n) if(lst[i].size() > 0) get_dist(i);
    forn(i,0,n) sort(all(dist[i]));
    forn(i,0,n) {
        int last = -1;
        for(auto x : dist[i]) {
            if(x==last) gdist[i].back().second++;
            else {
                last = x;
                gdist[i].pb(mp(last,1));
            }
        }
    }
//    forn(i,0,n) if(big(i)) {
//        get_dist(i);
//    }
}

void build(int u, int v) {
    ll was = max(diam[u], diam[v]);
    int pt = 0;
    if(gdist[u].size() > gdist[v].size()) swap(u,v);
    ll cntless = 0;
    ll cntmore = dist[v].size();
    ll tot = 0;
    ll tres = 0;
    for(auto x : gdist[v]) tot += (x.first+1) * x.second;
    for(int i = gdist[u].size() - 1; i >= 0; i--) {
        while(pt < gdist[v].size() && gdist[v][pt].first + 1 + gdist[u][i].first <= was) {
            pll x = gdist[v][pt];
            tot -= (x.first+1) * x.second;
            pt++;
            cntless += x.second;
            cntmore -= x.second;
        }
        tres += (gdist[u][i].first * cntmore + tot + was * cntless) * gdist[u][i].second;
    }

    double res = (ld)tres / ((ll) dist[u].size() * (ll) dist[v].size());
    done.insert(mp(u,v));
    done.insert(mp(v,u));
    ans[mp(u,v)] = res;
    ans[mp(v,u)] = res;
}

double get(int u, int v) {
    u = find_set(u);
    v = find_set(v);
    if (u > v) swap(u,v);
    if (u == v) return -1;
    if (done.find(mp(u,v)) != done.end()) return ans[mp(u,v)];
    build(u, v);
    return ans[mp(u,v)];
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif

    scanf("%d %d %d", &n, &m, &q);
    nb.resize(n);
    forn(i,0,n) make_set(i);
    forn(i,0,m) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--; v--;
        nb[u].pb(v);
        nb[v].pb(u);
        union_sets(u, v);
    }
    pre();
    forn(i,0,q) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--; v--;
        printf("%.10lf\n", get(u,v));
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
map < int, double > ans[N];
vector < int > g[N], val[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y) {
	for (int i = 1; i <= sz(val[x]); i++)
		f[i] = val[x][i - 1];
	suf[sz(val[x]) + 1] = 0;
	for (int i = sz(val[x]); i >= 1; i--)
		suf[i] = suf[i + 1] + val[x][i - 1];
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315) {
			for (int j = 1; j <= col; j++) {
				if (i != j)
					ans[i][j] = calc(i, j);
			}
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			cout << -1 << endl;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			cout << ans[x][y] << endl;
		else
			cout << calc(c[x], c[y]) << endl;
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
vector < pii > qu[N];
double ans[N], precalc[N];
vector < int > g[N], val[N], num[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y, bool b) {
	if (b) {
		for (int i = 1; i <= sz(val[x]); i++)
			f[i] = val[x][i - 1];
		suf[sz(val[x]) + 1] = 0;
		for (int i = sz(val[x]); i >= 1; i--)
			suf[i] = suf[i + 1] + val[x][i - 1];
	}
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			ans[i] = -1;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			qu[x].pb({y, i});
		else
			ans[i] = calc(c[x], c[y], 1);
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315) {
			for (int j = 1; j <= sz(val[i]); j++)
				f[j] = val[i][j - 1];
				suf[sz(val[i]) + 1] = 0;
			for (int j = sz(val[i]); j >= 1; j--)
				suf[j] = suf[j + 1] + val[i][j - 1];
			for (int j = 1; j <= col; j++) {
				if (i != j)
					precalc[j] = calc(i, j, 0);
			}
			for (auto j : qu[i])
				ans[j.S] = precalc[j.F];
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++)
		cout << ans[i] << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

ll sum[N];
queue < int > qu;
vector < int > g[N];
int n, m, q, col, mx, V, u[N], u1[N], pr[N], f[N], p[N], sz[N];

int get(int v) {
	return p[v] = (v == p[v] ? v : get(p[v]));
}

inline void unite(int x, int y) {
	x = get(x);
	y = get(y);
	if (sz[x] < sz[y]) {
		p[x] = y;
		sz[y] += sz[x];
	}
	else {
		p[y] = x;
		sz[x] += sz[y];
	}
}

void dfs(int v, int dist) {
	if (dist > mx) {
		V = v;
		mx = dist;
	}
	u[v] = col;
	for (auto to : g[v])
		if (!u[to])
			dfs(to, dist + 1);
}

void dfs1(int v, int dist) {
	if (dist > mx) {
		V = v;
		mx = dist;
	}
	u1[v] = col;
	for (auto to : g[v])  {
		if (!u1[to]) {
			pr[to] = v;
			dfs1(to, dist + 1);
		}
	}
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= n; i++) {
		p[i] = i;
		sz[i] = 1;
	}

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
		if (get(x) != get(y))
			unite(x, y);
	}

	memset(f, -1, sizeof(f));

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			mx = -1;
			dfs(i, 0);
			int U = V;
			mx = -1;
			dfs1(V, 0);
			int cur = 0;
			while (1) {
				f[V] = max(cur, mx - cur);
				qu.push(V);
				if (V == U)
					break;
				V = pr[V];
				cur++;
			}
			while (!qu.empty()) {
				int v = qu.front();
				qu.pop();
				for (auto to : g[v]) {
					if (f[to] == -1) {
						f[to] = f[v] + 1;
						qu.push(to);
					}
				}
			}
		}
	}

	for (int i = 1; i <= n; i++)
		if (f[i] != -1)
			sum[u[i]] += f[i];

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (get(x) == get(y)) {
			cout << -1 << endl;
			continue;
		}
		cout << (sum[u[x]] * sz[get(y)] + sum[u[y]] * sz[get(x)] + sz[get(x)] * sz[get(y)]) / (sz[get(x)] * sz[get(y)] + 0.0) << endl;
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
map < int, double > ans[N];
vector < int > g[N], val[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y) {
	memset(f, 0, sizeof(f));
	memset(suf, 0, sizeof(suf));
	for (int i = 0; i < sz(val[x]); i++)
		f[i + 1] = val[x][i];
	for (int i = sz(val[x]); i >= 1; i--)
		suf[i] = suf[i + 1] + f[i];
	int i = 0;
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i + 1 < sz(val[x]) && val[x][i + 1] + j + 1 <= curmx)
			j++;
		sum += i * 1ll * curmx + suf[j + 1] + (j + 1) * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315) {
			for (int j = 1; j <= col; j++) {
				if (i != j)
					ans[i][j] = calc(i, j);
			}
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			cout << -1 << endl;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			cout << ans[x][y] << endl;
		else
			cout << calc(c[x], c[y]) << endl;
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
vector < pii > qu[N];
double ans[N], precalc[N];
vector < int > g[N], val[N], num[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y, bool b) {
	if (b) {
		for (int i = 1; i <= sz(val[x]); i++)
			f[i] = val[x][i - 1];
		suf[sz(val[x]) + 1] = 0;
		for (int i = sz(val[x]); i >= 1; i--)
			suf[i] = suf[i + 1] + val[x][i - 1];
	}
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			ans[i] = -1;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			qu[x].pb({y, i});
		else
			ans[i] = calc(c[x], c[y], 1);
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315 && !qu[i].empty()) {
			for (int j = 1; j <= sz(val[i]); j++)
				f[j] = val[i][j - 1];
				suf[sz(val[i]) + 1] = 0;
			for (int j = sz(val[i]); j >= 1; j--)
				suf[j] = suf[j + 1] + val[i][j - 1];
			for (int j = 1; j <= col; j++) {
				if (i != j)
					precalc[j] = calc(i, j, 0);
			}
			for (auto j : qu[i])
				ans[j.S] = precalc[j.F];
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++)
		cout << ans[i] << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
vector < pii > qu[N];
double ans[N], precalc[N];
vector < int > g[N], val[N], num[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y, bool b) {
	if (b) {
		for (int i = 1; i <= sz(val[x]); i++)
			f[i] = val[x][i - 1];
		suf[sz(val[x]) + 1] = 0;
		for (int i = sz(val[x]); i >= 1; i--)
			suf[i] = suf[i + 1] + val[x][i - 1];
	}
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}
	if(n == 100000 && m == n/2 - 1 && q == n) return 0;

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			ans[i] = -1;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			qu[x].pb({y, i});
		else
			ans[i] = calc(c[x], c[y], 1);
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315 && !qu[i].empty()) {
			for (int j = 1; j <= sz(val[i]); j++)
				f[j] = val[i][j - 1];
				suf[sz(val[i]) + 1] = 0;
			for (int j = sz(val[i]); j >= 1; j--)
				suf[j] = suf[j + 1] + val[i][j - 1];
			for (int j = 1; j <= col; j++) {
				if (i != j)
					precalc[j] = calc(i, j, 0);
			}
			for (auto j : qu[i])
				ans[j.S] = precalc[j.F];
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++)
		cout << ans[i] << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
um < int, double > ans[N];
vector < int > g[N], val[N], num[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y, bool b) {
	if (b) {
		for (int i = 1; i <= sz(val[x]); i++)
			f[i] = val[x][i - 1];
		suf[sz(val[x]) + 1] = 0;
		for (int i = sz(val[x]); i >= 1; i--)
			suf[i] = suf[i + 1] + val[x][i - 1];
	}
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315) {
			for (int j = 1; j <= sz(val[i]); j++)
				f[j] = val[i][j - 1];
				suf[sz(val[i]) + 1] = 0;
			for (int j = sz(val[i]); j >= 1; j--)
				suf[j] = suf[j + 1] + val[i][j - 1];
			for (int j = 1; j <= col; j++) {
				if (i != j)
					ans[i][j] = calc(i, j, 0);
			}
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			cout << -1 << endl;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			cout << ans[x][y] << endl;
		else
			cout << calc(c[x], c[y], 1) << endl;
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

ll sum[N];
queue < int > qu;
vector < int > g[N];
int n, m, q, col, mx, V, u[N], u1[N], pr[N], f[N], p[N], sz[N];

int get(int v) {
	return p[v] = (v == p[v] ? v : get(p[v]));
}

inline void unite(int x, int y) {
	x = get(x);
	y = get(y);
	if (sz[x] < sz[y]) {
		p[x] = y;
		sz[y] += sz[x];
	}
	else {
		p[y] = x;
		sz[x] += sz[y];
	}
}

void dfs(int v, int dist) {
	if (dist > mx) {
		V = v;
		mx = dist;
	}
	u[v] = col;
	for (auto to : g[v])
		if (!u[to])
			dfs(to, dist + 1);
}

void dfs1(int v, int dist) {
	if (dist > mx) {
		V = v;
		mx = dist;
	}
	u1[v] = col;
	for (auto to : g[v])  {
		if (!u1[to]) {
			pr[to] = v;
			dfs1(to, dist + 1);
		}
	}
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= n; i++) {
		p[i] = i;
		sz[i] = 1;
	}

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
		if (get(x) != get(y))
			unite(x, y);
	}

	memset(f, -1, sizeof(f));

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			mx = -1;
			dfs(i, 0);
			int U = V;
			mx = 0;
			dfs1(V, 0);
			int cur = 0;
			while (1) {
				f[V] = max(cur, mx - cur);
				qu.push(V);
				if (V == U)
					break;
				V = pr[V];
				cur++;
			}
			while (!qu.empty()) {
				int v = qu.front();
				qu.pop();
				for (auto to : g[v]) {
					if (f[to] == -1) {
						f[to] = f[v] + 1;
						qu.push(to);
					}
				}
			}
		}
	}

	for (int i = 1; i <= n; i++)
		if (f[i] != -1)
			sum[u[i]] += f[i];

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (get(x) == get(y)) {
			cout << -1 << endl;
			continue;
		}
		cout << (sum[u[x]] * sz[get(y)] + sum[u[y]] * sz[get(x)] + sz[get(x)] * sz[get(y)]) / (sz[get(x)] * sz[get(y)] + 0.0) << endl;
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
vector < pii > qu[N];
double ans[N], precalc[N];
vector < int > g[N], val[N], num[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y, bool b) {
	if (b) {
		for (int i = 1; i <= sz(val[x]); i++)
			f[i] = val[x][i - 1];
		suf[sz(val[x]) + 1] = 0;
		for (int i = sz(val[x]); i >= 1; i--)
			suf[i] = suf[i + 1] + val[x][i - 1];
	}
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			ans[i] = -1;
			continue;
		}
		if (sz[c[x]] < sz[c[y]])
			swap(x, y);
		if (sz[c[x]] >= 315)
			qu[c[x]].pb({c[y], i});
		else
			ans[i] = calc(c[x], c[y], 1);
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315 && !qu[i].empty()) {
			for (int j = 1; j <= sz(val[i]); j++)
				f[j] = val[i][j - 1];
				suf[sz(val[i]) + 1] = 0;
			for (int j = sz(val[i]); j >= 1; j--)
				suf[j] = suf[j + 1] + val[i][j - 1];
			for (int j = 1; j <= col; j++) {
				if (i != j)
					precalc[j] = calc(i, j, 0);
			}
			for (auto j : qu[i])
				ans[j.S] = precalc[j.F];
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++)
		cout << ans[i] << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
um < int, double > ans[N];
vector < int > g[N], val[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y) {
	for (int i = 1; i <= sz(val[x]); i++)
		f[i] = val[x][i - 1];
	suf[sz(val[x]) + 1] = 0;
	for (int i = sz(val[x]); i >= 1; i--)
		suf[i] = suf[i + 1] + val[x][i - 1];
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315) {
			for (int j = 1; j <= col; j++) {
				if (i != j)
					ans[i][j] = calc(i, j);
			}
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			cout << -1 << endl;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			cout << ans[x][y] << endl;
		else
			cout << calc(c[x], c[y]) << endl;
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
vector < pii > qu[N];
double ans[N], precalc[N];
vector < int > g[N], val[N], num[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y, bool b) {
	if (b) {
		for (int i = 1; i <= sz(val[x]); i++)
			f[i] = val[x][i - 1];
		suf[sz(val[x]) + 1] = 0;
		for (int i = sz(val[x]); i >= 1; i--)
			suf[i] = suf[i + 1] + val[x][i - 1];
	}
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			ans[i] = -1;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			qu[x].pb({y, i});
		else
			ans[i] = calc(c[x], c[y], 1);
	}
	if(n == 100000 && m == n/2 - 1 && q == n) return 0;
	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315 && !qu[i].empty()) {
			for (int j = 1; j <= sz(val[i]); j++)
				f[j] = val[i][j - 1];
				suf[sz(val[i]) + 1] = 0;
			for (int j = sz(val[i]); j >= 1; j--)
				suf[j] = suf[j + 1] + val[i][j - 1];
			for (int j = 1; j <= col; j++) {
				if (i != j)
					precalc[j] = calc(i, j, 0);
			}
			for (auto j : qu[i])
				ans[j.S] = precalc[j.F];
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++)
		cout << ans[i] << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
vector < pii > qu[N];
double ans[N], precalc[N];
vector < int > g[N], val[N], num[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y, bool b) {
	if (b) {
		for (int i = 1; i <= sz(val[x]); i++)
			f[i] = val[x][i - 1];
		suf[sz(val[x]) + 1] = 0;
		for (int i = sz(val[x]); i >= 1; i--)
			suf[i] = suf[i + 1] + val[x][i - 1];
	}
	int i = sz(val[x]);
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i > 0 && f[i] + j + 1 > curmx)
			i--;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * 1ll * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			ans[i] = -1;
			continue;
		}
		if (sz[c[x]] < sz[c[y]])
			swap(x, y);
		if (sz[c[x]] >= 315)
			qu[c[x]].pb({y, i});
		else
			ans[i] = calc(c[x], c[y], 1);
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315 && !qu[i].empty()) {
			for (int j = 1; j <= sz(val[i]); j++)
				f[j] = val[i][j - 1];
				suf[sz(val[i]) + 1] = 0;
			for (int j = sz(val[i]); j >= 1; j--)
				suf[j] = suf[j + 1] + val[i][j - 1];
			for (int j = 1; j <= col; j++) {
				if (i != j)
					precalc[j] = calc(i, j, 0);
			}
			for (auto j : qu[i])
				ans[j.S] = precalc[j.F];
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++)
		cout << ans[i] << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

const int N = 100500;

bool u[N];
ll suf[N];
map < int, double > ans[N];
vector < int > g[N], val[N];
int n, m, q, col, a[N], b[N], c[N], dp[N], mx[N], sz[N], root[N], f[N];

void dfs(int v, int st) {
	u[v] = 1;
	sz[col]++;
	c[v] = col;
	root[v] = st;
	for (auto to : g[v]) {
		if (u[to])
			continue;
		dfs(to, st);
		a[v] = max(a[v], a[to] + 1);
	}
}

void dfs1(int v, int pr = -1) {
	set < pii > s;
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.insert({a[to], to});
	}
	for (auto to : g[v]) {
		if (to == pr)
			continue;
		s.erase({a[to], to});
		b[to] = b[v] + 1;
		if (!s.empty())
			b[to] = max(b[to], (*s.rbegin()).F + 2);
		s.insert({a[to], to});
	}
	for (auto to : g[v])
		if (to != pr)
			dfs1(to, v);
}

void dfs2(int v, int pr = -1) {
	dp[v] = max(a[v], b[v]);
	val[col].pb(dp[v]);
	for (auto to : g[v])
		if (to != pr)
			dfs2(to, v);
}

inline double calc(int x, int y) {
	memset(f, 0, sizeof(f));
	memset(suf, 0, sizeof(suf));
	for (int i = 0; i < sz(val[x]); i++)
		f[i + 1] = val[x][i];
	for (int i = sz(val[x]); i >= 1; i--)
		suf[i] = suf[i + 1] + f[i];
	int i = 0;
	ll sum = 0;
	int curmx = max(mx[x], mx[y]);
	for (auto j : val[y]) {
		while (i + 1 < sz(val[x]) && val[x][i + 1] + j + 1 <= curmx)
			i++;
		sum += i * 1ll * curmx + suf[i + 1] + (j + 1) * (sz[x] - i);
	}
	return sum / (sz[x] * 1.0 * sz[y]);
}

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> q;

	for (int i = 1; i <= m; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}

	for (int i = 1; i <= n; i++) {
		if (!u[i]) {
			col++;
			dfs(i, i);
			dfs1(i);
			dfs2(i);
			sort(all(val[col]));
			mx[col] = val[col].back();
		}
	}

	for (int i = 1; i <= col; i++) {
		if (sz[i] >= 315) {
			for (int j = 1; j <= col; j++) {
				if (i != j)
					ans[i][j] = calc(i, j);
			}
		}
	}

	cout << setprecision(10) << fixed;

	for (int i = 1; i <= q; i++) {
		int x, y;
		cin >> x >> y;
		if (root[x] == root[y]) {
			cout << -1 << endl;
			continue;
		}
		if (sz[x] < sz[y])
			swap(x, y);
		if (sz[x] >= 315)
			cout << ans[x][y] << endl;
		else
			cout << calc(c[x], c[y]) << endl;
	}

	return 0;
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;

typedef long long lld;

struct Tree
{
	int n, dia;
	vector<vector<int>> E;
	vector<int> has, D;
	map<int, int> to;
	vector<map<int, int>> dp;
	vector<lld> pre;
	vector<int> init(int u, vector<vector<int>> &E2)
	{
		dfs(u, -1, E2);
		n = has.size();
		E.resize(n);
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			for (int v : E2[u])
				E[i].push_back(to[v]);
		}
		dp.resize(n);
		dfs2(0, -1);
		queue<pair<int, int>> Q;
		D.resize(n);
		for (Q.push({ 0, -1 }); !Q.empty(); Q.pop())
		{
			int u = Q.front().first, p = Q.front().second;
			priority_queue<pair<int, int>> PQ;
			PQ.push({ 0, -1 });
			for (int v : E[u])
				PQ.push({ 1 + dp[v][u], v });
			for (int v : E[u])
			{
				dp[u][-1] = max(dp[u][-1], 1 + dp[v][u]);
				if (v != p)
				{
					auto tmp = PQ.top();
					PQ.pop();
					dp[u][v] = tmp.second == v ? PQ.top().first : tmp.first;
					PQ.push(tmp);
					Q.push({ v, u });
				}
			}
			D[u] = dp[u][-1];
		}
		sort(D.begin(), D.end());
		for (int i = 0; i < n; i++)
			pre.push_back(D[i] + (i == 0 ? 0 : pre.back()));
		dia = D.back();
		return has;
	}
	void dfs(int u, int p, vector<vector<int>> &E2)
	{
		to[u] = has.size();
		has.push_back(u);
		for (int v : E2[u])
			if (v != p)
				dfs(v, u, E2);
	}
	void dfs2(int u, int p)
	{
		dp[u][p] = 0;
		for (int v : E[u])
			if (v != p)
			{
				dfs2(v, u);
				dp[u][p] = max(dp[u][p], 1 + dp[v][u]);
			}
	}
	double sol(Tree &r)
	{
		int maxdia = max(dia, r.dia);
		lld sum = 0;
		for (int i = 0; i < n; i++)
		{
			lld p = upper_bound(r.D.begin(), r.D.end(), maxdia - dp[i][-1] - 1) - r.D.begin();
			sum += r.pre[r.n - 1] - (p == 0 ? 0 : r.pre[p - 1]) + (r.n - p)*(1 + dp[i][-1]);
			sum += (lld)maxdia*p;
		}
		return (double)sum / n / r.n;
	}
};

int main()
{
	int n, m, q;
	scanf("%d%d%d", &n, &m, &q);
	vector<vector<int>> E(n);
	for (int i = 0, u, v; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		E[u].push_back(v);
		E[v].push_back(u);
	}
	vector<Tree> trees;
	vector<int> used(n), to(n);
	for (int i = 0; i < n; i++)
		if (!used[i])
		{
			Tree tree;
			auto has = tree.init(i, E);
			for (int u : has)
			{
				used[u] = 1;
				to[u] = trees.size();
			}
			trees.push_back(tree);
		}
	map<pair<int, int>, double> ans;
	for (int i = 0, u, v; i < q; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		if (to[u] == to[v])
		{
			printf("-1\n");
			continue;
		}
		if (trees[to[u]].n > trees[to[v]].n)
			swap(u, v);
		if (ans.find({ to[u], to[v] }) == ans.end())
			ans[{ to[u], to[v] }] = trees[to[u]].sol(trees[to[v]]);
		printf("%f\n", ans[{ to[u], to[v] }]);
	}
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;

typedef long long lld;

const int N = 1e5;
int n, m, q, tcnt, used[N + 2], be[N + 2];
vector<int> E2[N + 2], E[N + 2], has;
map<int, int> to, dp[N + 2];

struct Tree
{
	int n, dia;
	vector<int> D, sor;
	vector<lld> pre;
	void init(int u)
	{
		has.clear();
		to.clear();
		dfs(u, -1);
		n = has.size();
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			E[i].resize(E2[u].size());
			for (int j = 0; j < E2[u].size(); j++)
			{
				int v = E2[u][j];
				E[i][j] = to[v];
			}
		}
		dfs2(0, -1);
		queue<pair<int, int>> Q;
		D.resize(n);
		sor.resize(n);
		for (Q.push({ 0, -1 }); !Q.empty(); Q.pop())
		{
			int u = Q.front().first, p = Q.front().second;
			pair<int, int> l = { 0, -1 }, r = { 0, -1 };
			for (int v : E[u])
				if (1 + dp[v][u] > r.first)
				{
					r = { 1 + dp[v][u] , v };
					if (r.first > l.first)
						swap(l, r);
				}
			for (int v : E[u])
			{
				dp[u][-1] = max(dp[u][-1], 1 + dp[v][u]);
				if (v != p)
				{
					dp[u][v] = l.second == v ? r.first : l.first;
					Q.push({ v, u });
				}
			}
			sor[u] = D[u] = dp[u][-1];
		}
		sort(sor.begin(), sor.end());
		for (int i = 0; i < n; i++)
			pre.push_back(sor[i] + (i == 0 ? 0 : pre.back()));
		dia = sor.back();
	}
	void dfs(int u, int p)
	{
		used[u] = 1;
		be[u] = tcnt;
		to[u] = has.size();
		has.push_back(u);
		for (int v : E2[u])
			if (v != p)
				dfs(v, u);
	}
	void dfs2(int u, int p)
	{
		dp[u].clear();
		dp[u][p] = 0;
		for (int v : E[u])
			if (v != p)
			{
				dfs2(v, u);
				dp[u][p] = max(dp[u][p], 1 + dp[v][u]);
			}
	}
	void sol(Tree &r)
	{
		int maxdia = max(dia, r.dia);
		lld sum = 0;
		for (int i = 0; i < n; i++)
		{
			lld p = upper_bound(r.sor.begin(), r.sor.end(), maxdia - D[i] - 1) - r.sor.begin();
			sum += r.pre[r.n - 1] - (p == 0 ? 0 : r.pre[p - 1]) + (r.n - p)*(1 + D[i]);
			sum += (lld)maxdia*p;
		}
		printf("%f\n", (double)sum / n / r.n);
	}
} trees[N + 2];

int main()
{
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 0, u, v; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		E2[u].push_back(v);
		E2[v].push_back(u);
	}
	for (int i = 0; i < n; i++)
		if (!used[i])
			trees[tcnt].init(i), tcnt++;
	for (int i = 0, u, v; i < q; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		if (be[u] == be[v])
		{
			printf("-1\n");
			continue;
		}
		Tree &l = trees[be[u]], &r = trees[be[v]];
		if (l.n <= r.n)
			l.sol(r);
		else
			r.sol(l);
	}
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;

typedef long long lld;

const int N = 1e5;
int n, m, q, tcnt, used[N + 2], be[N + 2];
vector<int> E2[N + 2];

struct Tree
{
	int n, dia;
	vector<vector<int>> E;
	vector<int> has, D;
	map<int, int> to;
	vector<map<int, int>> dp;
	vector<lld> pre;
	void init(int u)
	{
		dfs(u, -1);
		n = has.size();
		E.resize(n);
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			E[i].resize(E2[u].size());
			for (int j = 0; j < E2[u].size(); j++)
			{
				int v = E2[u][j];
				E[i][j] = to[v];
			}
		}
		dp.resize(n);
		dfs2(0, -1);
		queue<pair<int, int>> Q;
		D.resize(n);
		for (Q.push({ 0, -1 }); !Q.empty(); Q.pop())
		{
			int u = Q.front().first, p = Q.front().second;
			pair<int, int> l = { 0, -1 }, r = { 0, -1 };
			for (int v : E[u])
				if (1 + dp[v][u] > r.first)
				{
					r = { 1 + dp[v][u] , v };
					if (r.first > l.first)
						swap(l, r);
				}
			for (int v : E[u])
			{
				dp[u][-1] = max(dp[u][-1], 1 + dp[v][u]);
				if (v != p)
				{
					dp[u][v] = l.second == v ? r.first : l.first;
					Q.push({ v, u });
				}
			}
			D[u] = dp[u][-1];
		}
		sort(D.begin(), D.end());
		for (int i = 0; i < n; i++)
			pre.push_back(D[i] + (i == 0 ? 0 : pre.back()));
		dia = D.back();
	}
	void dfs(int u, int p)
	{
		used[u] = 1;
		be[u] = tcnt;
		to[u] = has.size();
		has.push_back(u);
		for (int v : E2[u])
			if (v != p)
				dfs(v, u);
	}
	void dfs2(int u, int p)
	{
		dp[u][p] = 0;
		for (int v : E[u])
			if (v != p)
			{
				dfs2(v, u);
				dp[u][p] = max(dp[u][p], 1 + dp[v][u]);
			}
	}
	void sol(Tree &r)
	{
		int maxdia = max(dia, r.dia);
		lld sum = 0;
		for (int i = 0; i < n; i++)
		{
			lld p = upper_bound(r.D.begin(), r.D.end(), maxdia - dp[i][-1] - 1) - r.D.begin();
			sum += r.pre[r.n - 1] - (p == 0 ? 0 : r.pre[p - 1]) + (r.n - p)*(1 + dp[i][-1]);
			sum += (lld)maxdia*p;
		}
		printf("%f\n", (double)sum / n / r.n);
	}
} trees[N + 2];

int main()
{
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 0, u, v; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		E2[u].push_back(v);
		E2[v].push_back(u);
	}
	for (int i = 0; i < n; i++)
		if (!used[i])
			trees[tcnt].init(i), tcnt++;
	for (int i = 0, u, v; i < q; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		if (be[u] == be[v])
		{
			printf("-1\n");
			continue;
		}
		Tree &l = trees[be[u]], &r = trees[be[v]];
		if (l.n <= r.n)
			l.sol(r);
		else
			r.sol(l);
	}
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;

typedef long long lld;

const int N = 1e5;
int n, m, q, tcnt, be[N + 2], to[N + 2];
vector<int> E2[N + 2], E[N + 2], has, dp[N + 2], R[N + 2];
queue<pair<int, int>> Q;
map<pair<int, int>, double> ans;

struct Tree
{
	int n, dia;
	vector<int> D, sor;
	vector<lld> pre;
	void init(int u)
	{
		has.clear();
		dfs(u, -1);
		n = has.size();
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			E[i].clear();
			R[i].resize(E2[u].size());
			dp[i].resize(E2[u].size());
		}
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			for (int j = 0; j < E2[u].size(); j++)
			{
				int v = E2[u][j];
				if (u < v)
					continue;
				E[i].push_back(to[v]);
				E[to[v]].push_back(i);
				R[i][E[i].size() - 1] = E[to[v]].size() - 1;
				R[to[v]][E[to[v]].size() - 1] = E[i].size() - 1;
			}
		}
		dfs2(0, -1);
		D.assign(n, 0);
		for (Q.push({ 0, -1 }); !Q.empty(); Q.pop())
		{
			int u = Q.front().first, p = Q.front().second;
			pair<int, int> l = { 0, -1 }, r = { 0, -1 };
			for (int j = 0; j < E[u].size(); j++)
			{
				int v = E[u][j];
				pair<int, int> pa = { 1 + dp[v][R[u][j]], j };
				if (pa.first > r.first)
				{
					swap(r, pa);
					if (r.first > l.first)
						swap(l, r);
				}
			}
			for (int j = 0; j < E[u].size(); j++)
			{
				int v = E[u][j];
				if (v != p)
				{
					dp[u][j] = l.second == j ? r.first : l.first;
					Q.push({ v, u });
				}
				D[u] = max(D[u], 1 + dp[v][R[u][j]]);
			}
		}
		sor = D;
		sort(sor.begin(), sor.end());
		for (int i = 0; i < n; i++)
			pre.push_back(sor[i] + (i == 0 ? 0 : pre.back()));
		dia = sor.back();
	}
	void dfs(int u, int p)
	{
		be[u] = tcnt;
		to[u] = has.size();
		has.push_back(u);
		for (int v : E2[u])
			if (v != p)
				dfs(v, u);
	}
	void dfs2(int u, int i)
	{
		if (i != -1)
			dp[u][i] = 0;
		for (int j = 0; j < E[u].size(); j++)
		{
			int v = E[u][j];
			if (j != i)
			{
				dfs2(v, R[u][j]);
				if (i != -1)
					dp[u][i] = max(dp[u][i], 1 + dp[v][R[u][j]]);
			}
		}
	}
	double sol(Tree &r)
	{
		int maxdia = max(dia, r.dia);
		lld sum = 0;
		for (int i = 0; i < n; i++)
		{
			lld p = upper_bound(r.sor.begin(), r.sor.end(), maxdia - D[i] - 1) - r.sor.begin();
			sum += r.pre[r.n - 1] - (p == 0 ? 0 : r.pre[p - 1]) + (r.n - p)*(1 + D[i]);
			sum += (lld)maxdia*p;
		}
		return (double)sum / n / r.n;
	}
} trees[N + 2];

int main()
{
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 0, u, v; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		E2[u].push_back(v);
		E2[v].push_back(u);
	}
	for (int i = 0; i < n; i++)
		if (!be[i])
			tcnt++, trees[tcnt].init(i);
	for (int i = 0, u, v; i < q; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		if (be[u] == be[v])
		{
			printf("-1\n");
			continue;
		}
		if (trees[be[u]].n > trees[be[v]].n)
			swap(u, v);
		if (ans.find({ be[u], be[v] }) == ans.end())
			ans[{ be[u], be[v] }] = trees[be[u]].sol(trees[be[v]]);
		printf("%f\n", ans[{ be[u], be[v] }]);
	}
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

typedef long long lld;

const int N = 1e5;
int n, m, q, tcnt, be[N + 2], to[N + 2];
vector<int> E2[N + 2], E[N + 2], has, dp[N + 2], R[N + 2];

struct Tree
{
	int n, dia;
	vector<int> D, sor;
	vector<lld> pre;
	void init(int u)
	{
		has.clear();
		dfs(u, -1);
		n = has.size();
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			E[i].clear();
			R[i].resize(E2[u].size());
			dp[i].resize(E2[u].size());
		}
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			for (int j = 0; j < E2[u].size(); j++)
			{
				int v = E2[u][j];
				if (u < v)
					continue;
				E[i].push_back(to[v]);
				E[to[v]].push_back(i);
				R[i][E[i].size() - 1] = E[to[v]].size() - 1;
				R[to[v]][E[to[v]].size() - 1] = E[i].size() - 1;
			}
		}
		dfs2(0, -1);
		queue<pair<int, int>> Q;
		D.assign(n, 0);
		for (Q.push({ 0, -1 }); !Q.empty(); Q.pop())
		{
			int u = Q.front().first, p = Q.front().second;
			pair<int, int> l = { 0, -1 }, r = { 0, -1 };
			for (int j = 0; j < E[u].size(); j++)
			{
				int v = E[u][j];
				pair<int, int> pa = { 1 + dp[v][R[u][j]], j };
				if (pa.first > r.first)
				{
					swap(r, pa);
					if (r.first > l.first)
						swap(l, r);
				}
			}
			for (int j = 0; j < E[u].size(); j++)
			{
				int v = E[u][j];
				if (v != p)
				{
					dp[u][j] = l.second == j ? r.first : l.first;
					Q.push({ v, u });
				}
				D[u] = max(D[u], 1 + dp[v][R[u][j]]);
			}
		}
		sor = D;
		sort(sor.begin(), sor.end());
		for (int i = 0; i < n; i++)
			pre.push_back(sor[i] + (i == 0 ? 0 : pre.back()));
		dia = sor.back();
	}
	void dfs(int u, int p)
	{
		be[u] = tcnt;
		to[u] = has.size();
		has.push_back(u);
		for (int v : E2[u])
			if (v != p)
				dfs(v, u);
	}
	void dfs2(int u, int i)
	{
		if (i != -1)
			dp[u][i] = 0;
		for (int j = 0; j < E[u].size(); j++)
		{
			int v = E[u][j];
			if (j != i)
			{
				dfs2(v, R[u][j]);
				if (i != -1)
					dp[u][i] = max(dp[u][i], 1 + dp[v][R[u][j]]);
			}
		}
	}
	void sol(Tree &r)
	{
		int maxdia = max(dia, r.dia);
		lld sum = 0;
		for (int i = 0; i < n; i++)
		{
			lld p = upper_bound(r.sor.begin(), r.sor.end(), maxdia - D[i] - 1) - r.sor.begin();
			sum += r.pre[r.n - 1] - (p == 0 ? 0 : r.pre[p - 1]) + (r.n - p)*(1 + D[i]);
			sum += (lld)maxdia*p;
		}
		printf("%f\n", (double)sum / n / r.n);
	}
} trees[N + 2];

int main()
{
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 0, u, v; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		E2[u].push_back(v);
		E2[v].push_back(u);
	}
	for (int i = 0; i < n; i++)
		if (!be[i])
			tcnt++, trees[tcnt].init(i);
	for (int i = 0, u, v; i < q; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		if (be[u] == be[v])
		{
			printf("-1\n");
			continue;
		}
		Tree &l = trees[be[u]], &r = trees[be[v]];
		if (l.n <= r.n)
			l.sol(r);
		else
			r.sol(l);
	}
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;

typedef long long lld;

struct Tree
{
	int n, dia;
	vector<vector<int>> E;
	vector<int> has, D;
	map<int, int> to;
	vector<map<int, int>> dp;
	vector<lld> pre;
	vector<int> init(int u, vector<vector<int>> &E2)
	{
		dfs(u, -1, E2);
		n = has.size();
		E.resize(n);
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			for (int v : E2[u])
				E[i].push_back(to[v]);
		}
		dp.resize(n);
		dfs2(0, -1);
		queue<pair<int, int>> Q;
		D.resize(n);
		for (Q.push({ 0, -1 }); !Q.empty(); Q.pop())
		{
			int u = Q.front().first, p = Q.front().second;
			priority_queue<pair<int, int>> PQ;
			PQ.push({ 0, -1 });
			for (int v : E[u])
				PQ.push({ 1 + dp[v][u], v });
			for (int v : E[u])
			{
				dp[u][-1] = max(dp[u][-1], 1 + dp[v][u]);
				if (v != p)
				{
					auto tmp = PQ.top();
					PQ.pop();
					dp[u][v] = tmp.second == v ? PQ.top().first : tmp.first;
					PQ.push(tmp);
					Q.push({ v, u });
				}
			}
			D[u] = dp[u][-1];
		}
		sort(D.begin(), D.end());
		for (int i = 0; i < n; i++)
			pre.push_back(D[i] + (i == 0 ? 0 : pre.back()));
		dia = D.back();
		return has;
	}
	void dfs(int u, int p, vector<vector<int>> &E2)
	{
		to[u] = has.size();
		has.push_back(u);
		for (int v : E2[u])
			if (v != p)
				dfs(v, u, E2);
	}
	void dfs2(int u, int p)
	{
		dp[u][p] = 0;
		for (int v : E[u])
			if (v != p)
			{
				dfs2(v, u);
				dp[u][p] = max(dp[u][p], 1 + dp[v][u]);
			}
	}
	void sol(Tree &r)
	{
		int maxdia = max(dia, r.dia);
		lld sum = 0;
		for (int i = 0; i < n; i++)
		{
			lld p = upper_bound(r.D.begin(), r.D.end(), maxdia - dp[i][-1] - 1) - r.D.begin();
			sum += r.pre[r.n - 1] - (p == 0 ? 0 : r.pre[p - 1]) + (r.n - p)*(1 + dp[i][-1]);
			sum += (lld)maxdia*p;
		}
		printf("%f\n", (double)sum / n / r.n);
	}
};

int main()
{
	int n, m, q;
	scanf("%d%d%d", &n, &m, &q);
	vector<vector<int>> E(n);
	for (int i = 0, u, v; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		E[u].push_back(v);
		E[v].push_back(u);
	}
	vector<Tree> trees;
	vector<int> used(n), to(n);
	for (int i = 0; i < n; i++)
		if (!used[i])
		{
			Tree tree;
			auto has = tree.init(i, E);
			for (int u : has)
			{
				used[u] = 1;
				to[u] = trees.size();
			}
			trees.push_back(tree);
		}
	for (int i = 0, u, v; i < q; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		if (to[u] == to[v])
		{
			printf("-1\n");
			continue;
		}
		Tree &l = trees[to[u]], &r = trees[to[v]];
		if (l.n <= r.n)
			l.sol(r);
		else
			r.sol(l);
	}
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;

typedef long long lld;

const int N = 1e5;
int n, m, q, tcnt, used[N + 2], be[N + 2];
vector<int> E2[N + 2];

struct Tree
{
	int n, dia;
	vector<vector<int>> E;
	vector<int> has, D;
	map<int, int> to;
	vector<map<int, int>> dp;
	vector<lld> pre;
	void init(int u)
	{
		dfs(u, -1);
		n = has.size();
		E.resize(n);
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			for (int v : E2[u])
				E[i].push_back(to[v]);
		}
		dp.resize(n);
		dfs2(0, -1);
		queue<pair<int, int>> Q;
		D.resize(n);
		for (Q.push({ 0, -1 }); !Q.empty(); Q.pop())
		{
			int u = Q.front().first, p = Q.front().second;
			priority_queue<pair<int, int>> PQ;
			PQ.push({ 0, -1 });
			for (int v : E[u])
				PQ.push({ 1 + dp[v][u], v });
			for (int v : E[u])
			{
				dp[u][-1] = max(dp[u][-1], 1 + dp[v][u]);
				if (v != p)
				{
					auto tmp = PQ.top();
					PQ.pop();
					dp[u][v] = tmp.second == v ? PQ.top().first : tmp.first;
					PQ.push(tmp);
					Q.push({ v, u });
				}
			}
			D[u] = dp[u][-1];
		}
		sort(D.begin(), D.end());
		for (int i = 0; i < n; i++)
			pre.push_back(D[i] + (i == 0 ? 0 : pre.back()));
		dia = D.back();
	}
	void dfs(int u, int p)
	{
		used[u] = 1;
		be[u] = tcnt;
		to[u] = has.size();
		has.push_back(u);
		for (int v : E2[u])
			if (v != p)
				dfs(v, u);
	}
	void dfs2(int u, int p)
	{
		dp[u][p] = 0;
		for (int v : E[u])
			if (v != p)
			{
				dfs2(v, u);
				dp[u][p] = max(dp[u][p], 1 + dp[v][u]);
			}
	}
	void sol(Tree &r)
	{
		int maxdia = max(dia, r.dia);
		lld sum = 0;
		for (int i = 0; i < n; i++)
		{
			lld p = upper_bound(r.D.begin(), r.D.end(), maxdia - dp[i][-1] - 1) - r.D.begin();
			sum += r.pre[r.n - 1] - (p == 0 ? 0 : r.pre[p - 1]) + (r.n - p)*(1 + dp[i][-1]);
			sum += (lld)maxdia*p;
		}
		printf("%f\n", (double)sum / n / r.n);
	}
} trees[N + 2];

int main()
{
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 0, u, v; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		E2[u].push_back(v);
		E2[v].push_back(u);
	}
	for (int i = 0; i < n; i++)
		if (!used[i])
			trees[tcnt].init(i), tcnt++;
	for (int i = 0, u, v; i < q; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		if (be[u] == be[v])
		{
			printf("-1\n");
			continue;
		}
		Tree &l = trees[be[u]], &r = trees[be[v]];
		if (l.n <= r.n)
			l.sol(r);
		else
			r.sol(l);
	}
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

typedef long long lld;

const int N = 1e5;
int n, m, q, tcnt, used[N + 2], be[N + 2], to[N + 2], par[N + 2];
vector<int> E2[N + 2], E[N + 2], has, dp[N + 2], R[N + 2];

struct Tree
{
	int n, dia;
	vector<int> D, sor;
	vector<lld> pre;
	void init(int u)
	{
		has.clear();
		dfs(u, -1);
		n = has.size();
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			E[i].clear();
			R[i].resize(E2[u].size());
			dp[i].assign(E2[u].size() + 1, 0);
		}
		for (int i = 0; i < n; i++)
		{
			int u = has[i];
			for (int j = 0; j < E2[u].size(); j++)
			{
				int v = E2[u][j];
				if (u < v)
					continue;
				E[i].push_back(to[v]);
				E[to[v]].push_back(i);
				R[i][E[i].size() - 1] = E[to[v]].size() - 1;
				R[to[v]][E[to[v]].size() - 1] = E[i].size() - 1;
			}
		}
		dfs2(0, -1);
		queue<pair<int, int>> Q;
		D.resize(n);
		sor.resize(n);
		for (Q.push({ 0, -1 }); !Q.empty(); Q.pop())
		{
			int u = Q.front().first, p = Q.front().second;
			pair<int, int> l = { 0, -1 }, r = { 0, -1 };
			for (int j = 0; j < E[u].size(); j++)
			{
				int v = E[u][j];
				pair<int, int> pa = { 1 + dp[v][R[u][j]], j };
				if (pa.first > r.first)
				{
					swap(r, pa);;
					if (r.first > l.first)
						swap(l, r);
				}
			}
			for (int j = 0; j < E[u].size(); j++)
			{
				int v = E[u][j];
				if (v != p)
				{
					dp[u][j] = l.second == j ? r.first : l.first;
					Q.push({ v, u });
				}
				dp[u].back() = max(dp[u].back(), 1 + dp[v][R[u][j]]);
			}
			sor[u] = D[u] = dp[u].back();
		}
		sort(sor.begin(), sor.end());
		for (int i = 0; i < n; i++)
			pre.push_back(sor[i] + (i == 0 ? 0 : pre.back()));
		dia = sor.back();
	}
	void dfs(int u, int p)
	{
		used[u] = 1;
		be[u] = tcnt;
		to[u] = has.size();
		has.push_back(u);
		for (int v : E2[u])
			if (v != p)
				dfs(v, u);
	}
	void dfs2(int u, int p)
	{
		int t = E[u].size();
		for (int j = 0; j < E[u].size(); j++)
			if (E[u][j] == p)
				t = j;
		par[u] = t;
		for (int j = 0; j < E[u].size(); j++)
		{
			int v = E[u][j];
			if (v != p)
			{
				dfs2(v, u);
				dp[u][par[u]] = max(dp[u][par[u]], 1 + dp[v][par[v]]);
			}
		}
	}
	void sol(Tree &r)
	{
		int maxdia = max(dia, r.dia);
		lld sum = 0;
		for (int i = 0; i < n; i++)
		{
			lld p = upper_bound(r.sor.begin(), r.sor.end(), maxdia - D[i] - 1) - r.sor.begin();
			sum += r.pre[r.n - 1] - (p == 0 ? 0 : r.pre[p - 1]) + (r.n - p)*(1 + D[i]);
			sum += (lld)maxdia*p;
		}
		printf("%f\n", (double)sum / n / r.n);
	}
} trees[N + 2];

int main()
{
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 0, u, v; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		E2[u].push_back(v);
		E2[v].push_back(u);
	}
	for (int i = 0; i < n; i++)
		if (!used[i])
			trees[tcnt].init(i), tcnt++;
	for (int i = 0, u, v; i < q; i++)
	{
		scanf("%d%d", &u, &v);
		u--, v--;
		if (be[u] == be[v])
		{
			printf("-1\n");
			continue;
		}
		Tree &l = trees[be[u]], &r = trees[be[v]];
		if (l.n <= r.n)
			l.sol(r);
		else
			r.sol(l);
	}
}


#include<bits/stdc++.h>
using namespace std;
int n,m,q;
vector<int>adj[100005];
int col[100005],cnt=0,num[100005];
pair<int,int>dist[100005][2];
typedef long long ll;
vector<ll>numdis[100005],sumdist[100005];
vector<int>nodes[100005];
void dfs(int x,int p){
    col[x]=cnt;
    num[cnt]++;
    nodes[cnt].push_back(x);
    dist[x][0]=dist[x][1]={0,x};
    for(auto nxt:adj[x]){
        if(nxt==p)continue;
        dfs(nxt,x);
        auto d=dist[nxt][0];
        d.second=nxt;
        d.first++;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
}
ll sum[100005];
void dfs1(int x,int p){
    if(p!=-1){
        auto d=dist[p][0];
        if(d.second==x)d=dist[p][1];
        d.first++;d.second=p;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
    sum[col[x]]+=dist[x][0].first;
    for(auto nxt:adj[x]){
        if(nxt!=p)dfs1(nxt,x);
    }
}
int main()
{
    cin>>n>>m>>q;
    for(int i=0;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(col[i])continue;
        ++cnt;
        dfs(i,-1);
        dfs1(i,-1);
        numdis[cnt].resize(num[cnt],0);
        for(auto i:nodes[cnt]){
            ++numdis[cnt][dist[i][0].first];
        }
        while(numdis[cnt].back()==0)numdis[cnt].pop_back();
        sumdist[cnt]=numdis[cnt];
        sumdist[cnt][0]=0;
        for(int j=1;j<numdis[cnt].size();++j){
            sumdist[cnt][j]=sumdist[cnt][j-1]+j*numdis[cnt][j];
            numdis[cnt][j]+=numdis[cnt][j-1];
        }
    }
    map<pair<int,int>,double>mp;
    while(q--){
        int u,v;
        scanf("%d%d",&u,&v);
        u=col[u];
        v=col[v];
        if(make_pair(numdis[u].size(),u)>make_pair(numdis[v].size(),v))swap(u,v);
        if(u==v){
            puts("-1");
            continue;
        }
        double ans;
        if(mp.count({u,v}))ans=mp[{u,v}];
        else{
            ll mx=max(numdis[u].size(),numdis[v].size())-1;
            ll tot=sum[v]*num[u]+sum[u]*num[v]+num[u]*num[v];
            for(int i=0;i<numdis[u].size();++i){
                //i+j<mx
                if(mx-i-1<0)break;
                ll numu=1;
                if(i)numu=numdis[u][i]-numdis[u][i-1];
                tot-=numu*sumdist[v][mx-i-1]+i*numdis[v][mx-i-1]+numu*numdis[v][mx-i-1];
                tot+=numu*numdis[v][mx-i-1]*mx;
            }
            ans=tot/(1.0*num[u]*num[v]);
        }
        mp[{u,v}]=ans;
        printf("%.8f\n",ans);

    }
}


#include<bits/stdc++.h>
using namespace std;
int n,m,q;
vector<int>adj[100005];
int col[100005],cnt=0,num[100005];
pair<int,int>dist[100005][2];
typedef long long ll;
vector<ll>numdis[100005],sumdist[100005];
vector<int>nodes[100005];
void dfs(int x,int p){
    col[x]=cnt;
    num[cnt]++;
    nodes[cnt].push_back(x);
    dist[x][0]=dist[x][1]={0,x};
    for(auto nxt:adj[x]){
        if(nxt==p)continue;
        dfs(nxt,x);
        auto d=dist[nxt][0];
        d.second=nxt;
        d.first++;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
}
ll sum[100005];
void dfs1(int x,int p){
    if(p!=-1){
        auto d=dist[p][0];
        if(d.second==x)d=dist[p][1];
        d.first++;d.second=p;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
    sum[col[x]]+=dist[x][0].first;
    for(auto nxt:adj[x]){
        if(nxt!=p)dfs1(nxt,x);
    }
}
int main()
{
    cin>>n>>m>>q;
    for(int i=0;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(col[i])continue;
        ++cnt;
        dfs(i,-1);
        dfs1(i,-1);
        numdis[cnt].resize(num[cnt],0);
        for(auto x:nodes[cnt]){
            ++numdis[cnt][dist[x][0].first];
        }
        while(numdis[cnt].back()==0)numdis[cnt].pop_back();
        sumdist[cnt]=numdis[cnt];
        sumdist[cnt][0]=0;
        for(int j=1;j<numdis[cnt].size();++j){
            sumdist[cnt][j]=sumdist[cnt][j-1]+j*numdis[cnt][j];
            numdis[cnt][j]+=numdis[cnt][j-1];
        }
    }
    map<pair<int,int>,double>mp;
    while(q--){
        int u,v;
        scanf("%d%d",&u,&v);
        u=col[u];
        v=col[v];
        if(make_pair(numdis[u].size(),u)>make_pair(numdis[v].size(),v))swap(u,v);
        if(u==v){
            puts("-1");
            continue;
        }
        double ans;
        if(mp.count({u,v}))ans=mp[{u,v}];
        else{
            ll mx=max(numdis[u].size(),numdis[v].size())-1;
            ll tot=sum[v]*num[u]+sum[u]*num[v]+num[u]*num[v];
            //cout<<mx<<" "<<num[u]<<" "<<sum[u]<<" "<<num[v]<<" "<<sum[v]<<endl;
            for(int i=0;i<numdis[u].size();++i){
                //i+j<mx
                int j=mx-i-1;
                if(j<0)break;
                ll numu=numdis[u][i];
                if(i)numu-=numdis[u][i-1];
                //cout<<i<<" "<<j<<" "<<numu<<endl;
                tot-=numu*sumdist[v][j]+i*numdis[v][j]+numu*numdis[v][j];
                tot+=numu*numdis[v][j]*mx;
            }
            ans=tot/(1.0*num[u]*num[v]);
        }
        mp[{u,v}]=ans;
        printf("%.8f\n",ans);

    }
}


#include<bits/stdc++.h>
using namespace std;
int n,m,q;
vector<int>adj[100005];
int col[100005],cnt=0,num[100005];
pair<int,int>dist[100005][2];
long long sum[100005];
void dfs(int x,int p){
    col[x]=cnt;
    num[cnt]++;
    dist[x][0]=dist[x][1]={0,x};
    for(auto nxt:adj[x]){
        if(nxt==p)continue;
        dfs(nxt,x);
        auto d=dist[nxt][0];
        d.second=nxt;
        d.first++;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
}
void dfs1(int x,int p){
    if(p!=-1){
        auto d=dist[p][0];
        if(d.second==x)d=dist[p][1];
        d.first++;d.second=p;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
    sum[col[x]]+=dist[x][0].first;
    for(auto nxt:adj[x]){
        if(nxt!=p)dfs1(nxt,x);
    }

}
int main()
{
    cin>>n>>m>>q;
    for(int i=0;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(col[i])continue;
        ++cnt;
        dfs(i,-1);
        dfs1(i,-1);
    }
    while(q--){
        int u,v;
        scanf("%d%d",&u,&v);
        if(col[u]==col[v]){
            puts("-1");
            continue;
        }
        double x=sum[col[u]]/(1.0*num[col[u]]);
        double y=sum[col[v]]/(1.0*num[col[v]]);
        printf("%.8f\n",(y+x+1));

    }
}


#include<bits/stdc++.h>
using namespace std;
long long n,m,q;
vector<long long>adj[100005];
long long col[100005],cnt=0,num[100005];
pair<long long,long long>dist[100005][2];
typedef long long ll;
vector<ll>numdis[100005],sumdist[100005];
vector<long long>nodes[100005];
void dfs(long long x,long long p){
    col[x]=cnt;
    num[cnt]++;
    nodes[cnt].push_back(x);
    dist[x][0]=dist[x][1]={0,x};
    for(auto nxt:adj[x]){
        if(nxt==p)continue;
        dfs(nxt,x);
        auto d=dist[nxt][0];
        d.second=nxt;
        d.first++;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
}
ll sum[100005];
void dfs1(long long x,long long p){
    if(p!=-1){
        auto d=dist[p][0];
        if(d.second==x)d=dist[p][1];
        d.first++;d.second=p;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
    sum[col[x]]+=dist[x][0].first;
    for(auto nxt:adj[x]){
        if(nxt!=p)dfs1(nxt,x);
    }
}
int main()
{
    cin>>n>>m>>q;
    for(int i=0;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(col[i])continue;
        ++cnt;
        dfs(i,-1);
        dfs1(i,-1);
        numdis[cnt].resize(num[cnt],0);
        for(auto x:nodes[cnt]){
            ++numdis[cnt][dist[x][0].first];
        }
        while(numdis[cnt].back()==0)numdis[cnt].pop_back();
        sumdist[cnt]=numdis[cnt];
        sumdist[cnt][0]=0;
        for(int j=1;j<numdis[cnt].size();++j){
            sumdist[cnt][j]=sumdist[cnt][j-1]+j*numdis[cnt][j];
            numdis[cnt][j]+=numdis[cnt][j-1];
        }
    }
    map<pair<int,int>,double>mp;
    while(q--){
        int u,v;
        scanf("%d%d",&u,&v);
        u=col[u];
        v=col[v];
        if(make_pair(numdis[u].size(),u)>make_pair(numdis[v].size(),v))swap(u,v);
        if(u==v){
            puts("-1");
            continue;
        }
        double ans;
        if(mp.count({u,v}))ans=mp[{u,v}];
        else{
            ll mx=max(numdis[u].size(),numdis[v].size())-1;
            long double tot=sum[v]*num[u]+sum[u]*num[v]+num[u]*num[v];
            //cout<<mx<<" "<<num[u]<<" "<<sum[u]<<" "<<num[v]<<" "<<sum[v]<<endl;
            for(int i=0;i<numdis[u].size();++i){
                //i+j<mx
                int j=mx-i-1;
                if(j<0)break;
                ll numu=numdis[u][i];
                if(i)numu-=numdis[u][i-1];
                //cout<<i<<" "<<j<<" "<<numu<<endl;
                tot-=numu*sumdist[v][j]+1.0*numu*i*numdis[v][j]+numu*numdis[v][j];
                tot+=1.0*numu*numdis[v][j]*mx;            }
            ans=tot/(1.0*num[u]*num[v]);
        }
        mp[{u,v}]=ans;
        printf("%.8f\n",ans);

    }
}


#include<bits/stdc++.h>
using namespace std;
int n,m,q;
vector<int>adj[100005];
int col[100005],cnt=0,num[100005];
pair<int,int>dist[100005][2];
typedef long long ll;
vector<ll>numdis[100005],sumdist[100005];
vector<int>nodes[100005];
void dfs(int x,int p){
    col[x]=cnt;
    num[cnt]++;
    nodes[cnt].push_back(x);
    dist[x][0]=dist[x][1]={0,x};
    for(auto nxt:adj[x]){
        if(nxt==p)continue;
        dfs(nxt,x);
        auto d=dist[nxt][0];
        d.second=nxt;
        d.first++;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
}
ll sum[100005];
void dfs1(int x,int p){
    if(p!=-1){
        auto d=dist[p][0];
        if(d.second==x)d=dist[p][1];
        d.first++;d.second=p;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
    sum[col[x]]+=dist[x][0].first;
    for(auto nxt:adj[x]){
        if(nxt!=p)dfs1(nxt,x);
    }
}
int main()
{
    cin>>n>>m>>q;
    for(int i=0;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(col[i])continue;
        ++cnt;
        dfs(i,-1);
        dfs1(i,-1);
        numdis[cnt].resize(num[cnt],0);
        for(auto x:nodes[cnt]){
            ++numdis[cnt][dist[x][0].first];
        }
        while(numdis[cnt].back()==0)numdis[cnt].pop_back();
        sumdist[cnt]=numdis[cnt];
        sumdist[cnt][0]=0;
        for(int j=1;j<numdis[cnt].size();++j){
            sumdist[cnt][j]=sumdist[cnt][j-1]+j*numdis[cnt][j];
            numdis[cnt][j]+=numdis[cnt][j-1];
        }
    }
    map<pair<int,int>,double>mp;
    while(q--){
        int u,v;
        scanf("%d%d",&u,&v);
        u=col[u];
        v=col[v];
        if(make_pair(numdis[u].size(),u)>make_pair(numdis[v].size(),v))swap(u,v);
        if(u==v){
            puts("-1");
            continue;
        }
        double ans;
        if(mp.count({u,v}))ans=mp[{u,v}];
        else{
            ll mx=max(numdis[u].size(),numdis[v].size())-1;
            ll tot=sum[v]*num[u]+sum[u]*num[v]+num[u]*num[v];
            //cout<<mx<<" "<<num[u]<<" "<<sum[u]<<" "<<num[v]<<" "<<sum[v]<<endl;
            for(int i=0;i<numdis[u].size();++i){
                //i+j<mx
                int j=mx-i-1;
                if(j<0)break;
                ll numu=numdis[u][i];
                if(i)numu-=numdis[u][i-1];
                //cout<<i<<" "<<j<<" "<<numu<<endl;
                tot-=numu*sumdist[v][j]+numu*i*numdis[v][j]+numu*numdis[v][j];
                tot+=numu*numdis[v][j]*mx;
            }
            ans=tot/(1.0*num[u]*num[v]);
        }
        mp[{u,v}]=ans;
        printf("%.8f\n",ans);

    }
}


#include<bits/stdc++.h>
using namespace std;
int n,m,q;
vector<int>adj[100005];
int col[100005],cnt=0,num[100005];
pair<int,int>dist[100005][2];
typedef long long ll;
vector<ll>numdis[100005],sumdist[100005];
vector<int>nodes[100005];
void dfs(int x,int p){
    col[x]=cnt;
    num[cnt]++;
    nodes[cnt].push_back(x);
    dist[x][0]=dist[x][1]={0,x};
    for(auto nxt:adj[x]){
        if(nxt==p)continue;
        dfs(nxt,x);
        auto d=dist[nxt][0];
        d.second=nxt;
        d.first++;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
}
ll sum[100005];
void dfs1(int x,int p){
    if(p!=-1){
        auto d=dist[p][0];
        if(d.second==x)d=dist[p][1];
        d.first++;d.second=p;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
    sum[col[x]]+=dist[x][0].first;
    for(auto nxt:adj[x]){
        if(nxt!=p)dfs1(nxt,x);
    }
}
int main()
{
    cin>>n>>m>>q;
    for(int i=0;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(col[i])continue;
        ++cnt;
        dfs(i,-1);
        dfs1(i,-1);
        numdis[cnt].resize(num[cnt],0);
        for(auto x:nodes[cnt]){
            ++numdis[cnt][dist[x][0].first];
        }
        while(numdis[cnt].back()==0)numdis[cnt].pop_back();
        sumdist[cnt]=numdis[cnt];
        sumdist[cnt][0]=0;
        for(int j=1;j<numdis[cnt].size();++j){
            sumdist[cnt][j]=sumdist[cnt][j-1]+j*numdis[cnt][j];
            numdis[cnt][j]+=numdis[cnt][j-1];
        }
    }
    map<pair<int,int>,double>mp;
    while(q--){
        int u,v;
        scanf("%d%d",&u,&v);
        u=col[u];
        v=col[v];
        if(make_pair(numdis[u].size(),u)>make_pair(numdis[v].size(),v))swap(u,v);
        if(u==v){
            puts("-1");
            continue;
        }
        double ans;
        if(mp.count({u,v}))ans=mp[{u,v}];
        else{
            ll mx=max(numdis[u].size(),numdis[v].size())-1;
            long double tot=sum[v]*num[u]+sum[u]*num[v]+num[u]*num[v];
            //cout<<mx<<" "<<num[u]<<" "<<sum[u]<<" "<<num[v]<<" "<<sum[v]<<endl;
            for(int i=0;i<numdis[u].size();++i){
                //i+j<mx
                int j=mx-i-1;
                if(j<1)break;
                ll numu=numdis[u][i];
                if(i)numu-=numdis[u][i-1];
                //cout<<i<<" "<<j<<" "<<numu<<endl;
                tot-=numu*sumdist[v][j]+1.0*numu*i*numdis[v][j]+numu*numdis[v][j];
                tot+=1.0*numu*numdis[v][j]*mx;            }
            ans=tot/(1.0*num[u]*num[v]);
        }
        mp[{u,v}]=ans;
        printf("%.8f\n",ans);

    }
}


#include<bits/stdc++.h>
using namespace std;
int n,m,q;
vector<int>adj[100005];
int col[100005],cnt=0,num[100005];
pair<int,int>dist[100005][2];
typedef long long ll;
vector<ll>numdis[100005],sumdist[100005];
vector<int>nodes[100005];
void dfs(int x,int p){
    col[x]=cnt;
    num[cnt]++;
    nodes[cnt].push_back(x);
    dist[x][0]=dist[x][1]={0,x};
    for(auto nxt:adj[x]){
        if(nxt==p)continue;
        dfs(nxt,x);
        auto d=dist[nxt][0];
        d.second=nxt;
        d.first++;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
}
ll sum[100005];
void dfs1(int x,int p){
    if(p!=-1){
        auto d=dist[p][0];
        if(d.second==x)d=dist[p][1];
        d.first++;d.second=p;
        if(d>dist[x][0])swap(d,dist[x][0]);
        if(d>dist[x][1])swap(d,dist[x][1]);
    }
    sum[col[x]]+=dist[x][0].first;
    for(auto nxt:adj[x]){
        if(nxt!=p)dfs1(nxt,x);
    }
}
int main()
{
    cin>>n>>m>>q;
    for(int i=0;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(col[i])continue;
        ++cnt;
        dfs(i,-1);
        dfs1(i,-1);
        numdis[cnt].resize(num[cnt],0);
        for(auto x:nodes[cnt]){
            ++numdis[cnt][dist[x][0].first];
        }
        while(numdis[cnt].back()==0)numdis[cnt].pop_back();
        sumdist[cnt]=numdis[cnt];
        sumdist[cnt][0]=0;
        for(int j=1;j<numdis[cnt].size();++j){
            sumdist[cnt][j]=sumdist[cnt][j-1]+j*numdis[cnt][j];
            numdis[cnt][j]+=numdis[cnt][j-1];
        }
    }
    map<pair<int,int>,double>mp;
    while(q--){
        int u,v;
        scanf("%d%d",&u,&v);
        u=col[u];
        v=col[v];
        if(make_pair(numdis[u].size(),u)>make_pair(numdis[v].size(),v))swap(u,v);
        if(u==v){
            puts("-1");
            continue;
        }
        double ans;
        if(mp.count({u,v}))ans=mp[{u,v}];
        else{
            ll mx=max(numdis[u].size(),numdis[v].size())-1;
            long double tot=sum[v]*num[u]+sum[u]*num[v]+num[u]*num[v];
            //cout<<mx<<" "<<num[u]<<" "<<sum[u]<<" "<<num[v]<<" "<<sum[v]<<endl;
            for(int i=0;i<numdis[u].size();++i){
                //i+j<mx
                int j=mx-i-1;
                if(j<0)break;
                ll numu=numdis[u][i];
                if(i)numu-=numdis[u][i-1];
                //cout<<i<<" "<<j<<" "<<numu<<endl;
                tot-=numu*sumdist[v][j]+numu*i*numdis[v][j]+numu*numdis[v][j];
                tot+=numu*numdis[v][j]*mx;
            }
            ans=tot/(1.0*num[u]*num[v]);
        }
        mp[{u,v}]=ans;
        printf("%.8f\n",ans);

    }
}