给定n个点m条的无向连通图和q个询问:
给定l,r,对于任意两点 l<=a,b<=r连通至少需要1~k条边的最小k值
/*input
3
2 1 2
1 2
1 1
1 2
5 5 5
1 2
1 3
2 4
3 4
3 5
1 4
3 4
2 2
2 5
3 5
3 2 1
1 3
2 3
1 3
*/
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int fa[N],dp[N][20],id[N][20],len[N];
int ans[N][20],lg[N];
typedef pair<int,int> pii;
vector<pii> v[N];
int get(int x){
if(x!=fa[x]) return fa[x]=get(fa[x]);
return x;
}
void link(int x,int y){
fa[get(x)]=y;
}
void dfs(int root,int fa,int dep){
len[root]=dep;
for(auto node:v[root]){
if(node.first==fa) continue;
dp[node.first][0]=root;
id[node.first][0]=node.second;
dfs(node.first,root,dep+1);
}
}
int lca(int x,int y){
if(len[x]>len[y]) swap(x,y);
int ans=0;
for(int i=19;i>=0;i--){
if(len[dp[y][i]]>=len[x]){
ans=max(ans,id[y][i]);
y=dp[y][i];
}
}
for(int i=19;i>=0;i--){
if(dp[x][i]!=dp[y][i]){
ans=max({ans,id[x][i],id[y][i]});
x=dp[x][i];
y=dp[y][i];
}
}
if(x!=y) ans=max({ans,id[x][0],id[y][0]});
return ans;
}
void solve(){
int n,m,q;
cin>>n>>m>>q;
for(int i=1;i<=n;i++){
fa[i]=i;
v[i].clear();
}
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
if(get(x)!=get(y)){
v[x].push_back({y,i});
v[y].push_back({x,i});
link(x,y);
}
}
dfs(1,0,1);
for(int i=1;i<20;i++){
for(int j=1;j<=n;j++){
dp[j][i]=dp[dp[j][i-1]][i-1];
id[j][i]=max(id[j][i-1],id[dp[j][i-1]][i-1]);
}
}
for(int i=1;i<n;i++)
ans[i][0]=lca(i,i+1);
for(int i=0;1<<i<=n;i++){
for(int j=1<<i;j<(1<<(i+1))&&j<=n;j++){
lg[j]=i;
}
}
for(int i=1;i<20;i++){
for(int j=1;j+(1<<i)-1<n;j++){
ans[j][i]=max(ans[j][i-1],ans[j+(1<<(i-1))][i-1]);
}
}
while(q--){
int l,r;
cin>>l>>r;
if(l==r) cout<<0<<' ';
else{
int length=r-l;
cout<<max(ans[l][lg[length]],ans[r-(1<<lg[length])][lg[length]])<<' ';
}
}
puts("");
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--) solve();
}