#include <bits/stdc++.h>   using namespace std;   const int N = 100100;   const int LOGN = 15;   struct TreeGraph {     vector<int> *graph;     vector<int> heights;     vector<int> *d;     vector<int> weights;     vector<int> mapNodes;     int n, nAritculationPoints;     ;     TreeGraph(){};     TreeGraph(int nArtiPoints) : nAritculationPoints(nArtiPoints) {       graph = new vector<int>[N * 2];       d = new vector<int>[LOGN];     }     ~TreeGraph() {       delete[] graph;       heights.clear();       delete[] d;       weights.clear();       mapNodes.clear();     }     void addEdge(int u, int v) {       if (u >= N * 2) cerr << u;       if (v >= N * 2) cerr << v;       graph[u].push_back(v);       graph[v].push_back(u);     }     void print() {       for (int i = 0; i < n; i++) {         printf(  n%d:  , i);         for (auto v : graph[i]) printf( %d  , v);       }       printf(  n______ n );     }     void setN(int n, vector<int> mapNodes) {       this->n = n;       this->mapNodes = mapNodes;       heights = vector<int>(n);       weights = vector<int>(n);       for (int i = 0; i < LOGN; i++) d[i] = vector<int>(n);     }     void preprocess() { dfs(0, -1, 0, 0); }     int lca(int u, int v) {       if (heights[v] > heights[u]) swap(u, v);       int nSteps = heights[u] - heights[v];       while (nSteps > 0) {         int step = log2(nSteps);         u = d[step][u], nSteps -= 1 << step;       }       while (u != v) {         int i = log2(heights[u]);         for (; i >= 0; i--)           if (d[i][u] != d[i][v]) break;         if (i < 0)           u = d[0][u], v = d[0][v];         else           u = d[i][u], v = d[i][v];       }       return u;     }     int sumPath(int u, int v) {       int lcaAndU = lca(u, v);       return weights[u] + weights[v] - 2 * weights[lcaAndU] +              (lcaAndU >= nAritculationPoints);     }     void dfs(int u, int parent, int weight, int height) {       weight += u < nAritculationPoints ? 0 : 1;       weights[u] = weight, heights[u] = height;       d[0][u] = parent;       for (int i = 1; 1 << i <= height; i++) d[i][u] = d[i - 1][d[i - 1][u]];       for (auto v : graph[u]) {         if (v == parent) continue;         dfs(v, u, weight, height + 1);       }     }     int solve(int u, int v) {       u = mapNodes[u], v = mapNodes[v];       if (u == v) return 1;       return sumPath(u, v);     }   };   struct GraphSolver {     vector<int> *graph;     vector<int> low, ids;     vector<bool> isArticulationPoint;     vector<int> stacks;     vector<vector<int>> comps;     int n, id;     GraphSolver();     ~GraphSolver() {       ids.clear();       delete[] graph;       isArticulationPoint.clear();       low.clear();       stacks.clear();     }     GraphSolver(int n)         : low(n), ids(n, -1), isArticulationPoint(n, false), id(0), n(n) {       graph = new vector<int>[n];     };     void addEdge(int u, int v) { graph[u].push_back(v), graph[v].push_back(u); }     void dfs(int u, int parent) {       low[u] = ids[u] = id++;       stacks.push_back(u);       int children = 0;       for (auto v : graph[u]) {         if (v == parent) continue;         if (ids[v] != -1) {           low[u] = min(low[u], ids[v]);         } else {           dfs(v, u);           low[u] = min(low[v], low[u]);           children++;           if ((low[v] >= ids[u] && parent != -1) ||               (parent == -1 && children > 1)) {             isArticulationPoint[u] = true;             vector<int> comp = vector<int>{u};             while (comp.back() != v) {               comp.push_back(stacks.back());               stacks.pop_back();             }             comps.push_back(comp);           }         }       }     }     TreeGraph buildBlockCutTree() {       dfs(0, -1);       if (!stacks.empty()) {         vector<int> comp;         while (!stacks.empty()) {           comp.push_back(stacks.back());           stacks.pop_back();         }         comps.push_back(comp);       }       vector<int> mapNodes = vector<int>(n);       int nNodes = 0;       for (int i = 0; i < n; i++)         if (isArticulationPoint[i]) mapNodes[i] = nNodes++;       auto tree = TreeGraph(nNodes);       for (auto comp : comps) {         for (auto v : comp) {           if (!isArticulationPoint[v])             mapNodes[v] = nNodes;           else             tree.addEdge(mapNodes[v], nNodes);         }         nNodes++;       }       tree.setN(nNodes, mapNodes);       return tree;     }   };   int main() {     int n, m, q;     scanf( %d %d %d n , &n, &m, &q);     int u, v;     GraphSolver *solver = new GraphSolver(n);     for (int i = 0; i < m; i++) {       scanf( %d %d n , &u, &v);       solver->addEdge(u - 1, v - 1);     }     auto tree = solver->buildBlockCutTree();     delete (solver);     tree.preprocess();     for (int i = 0; i < q; i++) {       scanf( %d %d n , &u, &v);       printf( %d n , tree.solve(u - 1, v - 1));     }     return 0;   }