#include <bits/stdc++.h>
using namespace std;

#define maxn 200005
#define LOG 20

int n,m,q;
vector<pair<int,int>> g[maxn];

int U[maxn], V[maxn];

// Tarjan
int dfn[maxn], low[maxn], timer;
bool isBridge[maxn];
vector<int> st;

// block-cut tree
vector<int> bc[maxn*2];
int id; // total node in bc tree

// mark visited in bcc
int seen[maxn], stamp;

// ---------- Tarjan DFS ----------
void dfs(int u, int pEdge){
    dfn[u] = low[u] = ++timer;

    for(auto [v, idEdge] : g[u]){
        if(idEdge == pEdge) continue;

        if(!dfn[v]){
            st.push_back(idEdge);
            dfs(v, idEdge);
            low[u] = min(low[u], low[v]);

            // bridge
            if(low[v] > dfn[u]) isBridge[idEdge] = 1;

            // build bcc
            if(low[v] >= dfn[u]){
                int node = ++id;

                stamp++;
                while(true){
                    int e = st.back(); st.pop_back();
                    int a = U[e], b = V[e];

                    if(seen[a] != stamp){
                        seen[a] = stamp;
                        bc[a].push_back(node);
                        bc[node].push_back(a);
                    }
                    if(seen[b] != stamp){
                        seen[b] = stamp;
                        bc[b].push_back(node);
                        bc[node].push_back(b);
                    }

                    if(e == idEdge) break;
                }
            }
        }
        else if(dfn[v] < dfn[u]){
            st.push_back(idEdge);
            low[u] = min(low[u], dfn[v]);
        }
    }
}

// ---------- LCA ----------
int up[maxn*2][LOG], depth[maxn*2], val[maxn*2];

void dfs_lca(int u, int p){
    for(int v: bc[u]){
        if(v == p) continue;
        depth[v] = depth[u] + 1;
        up[v][0] = u;
        val[v] += val[u];
        dfs_lca(v,u);
    }
}

int lca(int u, int v){
    if(depth[u] < depth[v]) swap(u,v);

    int k = depth[u] - depth[v];
    for(int i=0;i<LOG;i++)
        if(k>>i&1) u = up[u][i];

    if(u==v) return u;

    for(int i=LOG-1;i>=0;i--){
        if(up[u][i] != up[v][i]){
            u = up[u][i];
            v = up[v][i];
        }
    }
    return up[u][0];
}

// ---------- DSU for bridge tree ----------
int par[maxn];

int find(int u){
    return par[u]==u ? u : par[u]=find(par[u]);
}

void unite(int u,int v){
    u=find(u); v=find(v);
    if(u!=v) par[v]=u;
}

vector<int> tree[maxn];
int dep2[maxn], up2[maxn][LOG];

void dfs2(int u, int p){
    for(int v: tree[u]){
        if(v==p) continue;
        dep2[v] = dep2[u] + 1;
        up2[v][0] = u;
        dfs2(v,u);
    }
}

int lca2(int u,int v){
    if(dep2[u] < dep2[v]) swap(u,v);

    int k = dep2[u]-dep2[v];
    for(int i=0;i<LOG;i++)
        if(k>>i&1) u=up2[u][i];

    if(u==v) return u;

    for(int i=LOG-1;i>=0;i--){
        if(up2[u][i]!=up2[v][i]){
            u=up2[u][i];
            v=up2[v][i];
        }
    }
    return up2[u][0];
}

// ---------- MAIN ----------
int main(){
    ios::sync_with_stdio(0); cin.tie(0);

    cin>>n>>m>>q;

    for(int i=1;i<=m;i++){
        cin>>U[i]>>V[i];
        g[U[i]].push_back({V[i],i});
        g[V[i]].push_back({U[i],i});
    }

    id = n;

    dfs(1,0);

    // ----- prepare block-cut tree -----
    for(int i=1;i<=n;i++) val[i]=1; // chỉ tính node gốc

    dfs_lca(1,0);

    for(int j=1;j<LOG;j++)
        for(int i=1;i<=id;i++)
            up[i][j]=up[ up[i][j-1] ][j-1];

    // ----- build bridge tree -----
    for(int i=1;i<=n;i++) par[i]=i;

    for(int i=1;i<=m;i++){
        if(!isBridge[i])
            unite(U[i],V[i]);
    }

    map<int,int> mp;
    int cnt=0;

    for(int i=1;i<=n;i++){
        int r = find(i);
        if(!mp[r]) mp[r]=++cnt;
    }

    for(int i=1;i<=m;i++){
        if(isBridge[i]){
            int a = mp[find(U[i])];
            int b = mp[find(V[i])];
            tree[a].push_back(b);
            tree[b].push_back(a);
        }
    }

    dfs2(1,0);

    for(int j=1;j<LOG;j++)
        for(int i=1;i<=cnt;i++)
            up2[i][j]=up2[ up2[i][j-1] ][j-1];

    // ----- queries -----
    while(q--){
        int s,t;
        cin>>s>>t;

        // vertex
        int L = lca(s,t);
        int ansV = val[s] + val[t] - 2*val[L] + 1;

        // edge
        int a = mp[find(s)];
        int b = mp[find(t)];
        int L2 = lca2(a,b);
        int ansE = dep2[a] + dep2[b] - 2*dep2[L2];

        cout<<ansV<<" "<<ansE<<"\n";
    }
}