#include <bits/stdc++.h>   #pragma comment(linker,  /stack:200000000 )   #pragma GCC optimize( unroll-loops )   using namespace std;   template <class T>   inline T bigmod(T p, T e, T M) {     long long ret = 1;     for (; e > 0; e >>= 1) {       if (e & 1) ret = (ret * p) % M;       p = (p * p) % M;     }     return (T)ret;   }   template <class T>   inline T gcd(T a, T b) {     if (b == 0) return a;     return gcd(b, a % b);   }   template <class T>   inline T modinverse(T a, T M) {     return bigmod(a, M - 2, M);   }   template <class T>   inline T lcm(T a, T b) {     a = abs(a);     b = abs(b);     return (a / gcd(a, b)) * b;   }   template <class T, class X>   inline bool getbit(T a, X i) {     T t = 1;     return ((a & (t << i)) > 0);   }   template <class T, class X>   inline T setbit(T a, X i) {     T t = 1;     return (a | (t << i));   }   template <class T, class X>   inline T resetbit(T a, X i) {     T t = 1;     return (a & (~(t << i)));   }   inline long long getnum() {     char c = getchar();     long long num, sign = 1;     for (; c <  0  || c >  9 ; c = getchar())       if (c ==  - ) sign = -1;     for (num = 0; c >=  0  && c <=  9 ;) {       c -=  0 ;       num = num * 10 + c;       c = getchar();     }     return num * sign;   }   inline long long power(long long a, long long b) {     long long multiply = 1;     for (int i = (0); i < (b); i++) {       multiply *= a;     }     return multiply;   }   struct MagicComponents {     struct edge {       long long u, v, id;     };     long long num, n, edges;     vector<long long> dfs_num, low, vis;     vector<long long> cuts;     vector<edge> bridges;     vector<vector<edge>> adj;     vector<vector<edge>> bccs;     deque<edge> e_stack;     MagicComponents(const long long& _n) : n(_n) {       adj.assign(n, vector<edge>());       edges = 0;     }     void add_edge(const long long& u, const long long& v) {       adj[u].push_back({u, v, edges});       adj[v].push_back({v, u, edges++});     }     void run(void) {       vis.assign(n, 0);       dfs_num.assign(n, 0);       low.assign(n, 0);       bridges.clear();       cuts.clear();       bccs.clear();       e_stack = deque<edge>();       num = 0;       for (long long i = 0; i < n; ++i) {         if (vis[i]) continue;         dfs(i, -1);       }     }     void dfs(const long long& node, const long long& par) {       dfs_num[node] = low[node] = num++;       vis[node] = 1;       long long n_child = 0;       for (edge& e : adj[node]) {         if (e.v == par) continue;         if (vis[e.v] == 0) {           ++n_child;           e_stack.push_back(e);           dfs(e.v, node);           low[node] = min(low[node], low[e.v]);           if (low[e.v] >= dfs_num[node]) {             if (dfs_num[node] > 0 || n_child > 1) cuts.push_back(node);             if (low[e.v] > dfs_num[node]) {               bridges.push_back(e);               pop(node);             } else               pop(node);           }         } else if (vis[e.v] == 1) {           low[node] = min(low[node], dfs_num[e.v]);           e_stack.push_back(e);         }       }       vis[node] = 2;     }     void pop(const long long& u) {       vector<edge> list;       for (;;) {         edge e = e_stack.back();         e_stack.pop_back();         list.push_back(e);         if (e.u == u) break;       }       bccs.push_back(list);     }   };   int n, m, q;   vector<int> bcc_nodes[100005], tree[100005 * 2];   int L[2 * 100005], table[2 * 100005][19];   void buildTree(int sz, int& _n) {     for (int i = (0); i < (sz); i++) {       _n++;       for (auto it : bcc_nodes[i]) {         tree[_n].push_back(it);         tree[it].push_back(_n);       }     }   }   int query(int p, int q) {     if (L[p] < L[q]) swap(p, q);     int x = 1;     while (true) {       if ((1 << (x + 1)) > L[p]) break;       x++;     }     for (int i = (x); i >= (0); i--) {       if (L[p] - (1 << i) >= L[q]) p = table[p][i];     }     if (p == q) return p;     for (int i = (x); i >= (0); i--) {       if (table[p][i] != -1 && table[p][i] != table[q][i]) {         p = table[p][i];         q = table[q][i];       }     }     return table[p][0];   }   void dfs2(int u, int p = -1, int d = 0) {     L[u] = d;     table[u][0] = p;     for (auto v : tree[u]) {       if (v == p) continue;       dfs2(v, u, d + 1);     }   }   void build(int _n) {     memset(table, -1, sizeof(table));     dfs2(1);     for (int j = 1; 1 << j < _n; j++) {       for (int i = 1; i <= _n; i++) {         if (table[i][j - 1] != -1) table[i][j] = table[table[i][j - 1]][j - 1];       }     }   }   int getdist(int u, int v) {     int lca = query(u, v);     int ret = L[u] + L[v] - 2 * L[lca];     return ret;   }   int main() {     int test, cases = 1;     scanf( %d%d%d , &n, &m, &q);     MagicComponents magic(n + 2);     int u, v;     for (int i = (0); i < (m); i++) {       scanf( %d%d , &u, &v);       magic.add_edge(u, v);     }     magic.run();     int sz = magic.bccs.size();     for (int i = (0); i < (sz); i++) {       for (auto it : magic.bccs[i]) {         bcc_nodes[i].push_back(it.u);         bcc_nodes[i].push_back(it.v);       }       sort(bcc_nodes[i].begin(), bcc_nodes[i].end());       bcc_nodes[i].erase(unique(bcc_nodes[i].begin(), bcc_nodes[i].end()),                          bcc_nodes[i].end());     }     int _n = n;     buildTree(sz, _n);     build(_n);     while (q--) {       scanf( %d%d , &u, &v);       int out = getdist(u, v);       printf( %d n , out / 2);     }     return 0;   }