#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <functional>
#include <iterator>
#include <limits>
#include <numeric>
#include <utility>
#include <cmath>
using namespace std; using namespace placeholders;
using LL = long long;
using ULL = unsigned long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VS = vector<string>;
using SS = stringstream;
using PII = pair<int,int>;
using VPII = vector< pair<int,int> >;
template < typename T = int > using VT = vector<T>;
template < typename T = int > using VVT = VT< VT<T> >;
template < typename T = int > using LIM = numeric_limits<T>;
template < typename T > inline T fromString( const string &s ){ T res; istringstream iss( s ); iss >> res; return res; };
template < typename T > inline string toString( const T &a ){ ostringstream oss; oss << a; return oss.str(); };
#define REP( i, m, n ) for ( int i = (int)( m ); i < (int)( n ); ++i )
#define FOR( e, c ) for ( auto &e : c )
#define ALL( c ) (c).begin(), (c).end()
#define AALL( a, t ) (t*)a, (t*)a + sizeof( a ) / sizeof( t )
#define DRANGE( c, p ) (c).begin(), (c).begin() + p, (c).end()
#define PB( n ) push_back( n )
#define MP( a, b ) make_pair( ( a ), ( b ) )
#define EXIST( c, e ) ( (c).find( e ) != (c).end() )
#define fst first
#define snd second
#define DUMP( x ) cerr << #x << " = " << ( x ) << endl
// セグメント木のユーティリティ
inline const int chl( const int k )
{
return k * 2 + 1;
}
inline const int chr( const int k )
{
return k * 2 + 2;
}
inline const int mid( const int l, const int r )
{
return ( l + r ) / 2;
}
// セグメント木による Range Minimum Query
class RangeMinimumQuery
{
private:
const int N;
vector<LL> data;
public:
RangeMinimumQuery( const vector<int> &src ) : N( src.size() ), data( N * 4 )
{
REP( i, 0, N )
{
update( i, src[i] );
}
return;
}
void update( const int p, const LL x )
{
return update( p, x, 0, 0, N );
}
int minimum( const int a, const int b ) const
{
return minimum( a, b, 0, 0, N );
}
private:
void update( const int p, const LL x, const int k, const int l, const int r )
{
if ( p < l || r <= p )
{
return;
}
if ( l + 1 == r && p == l )
{
data[k] = x;
return;
}
update( p, x, chl( k ), l, mid( l, r ) );
update( p, x, chr( k ), mid( l, r ), r );
data[k] = min( data[ chl( k ) ], data[ chr( k ) ] );
return;
}
int minimum( const int a, const int b, const int k, const int l, const int r ) const
{
if ( b <= l || r <= a )
{
return LIM<>::max() / 4;
}
else if ( a <= l && r <= b )
{
return data[k];
}
else
{
return min( minimum( a, b, chl( k ), l, mid( l, r ) ), minimum( a, b, chr( k ), mid( l, r ), r ) );
}
}
};
// RangeMinimumQuery( VI src )
// update( pos, x )
// minimum( [ a, b ) )
void dfs( const VVI &G, const int u, const int prev, const int d, VI &vs, VI &depth )
{
vs.PB( u );
depth.PB( d );
FOR( v, G[u] )
{
if ( v == prev )
{
continue;
}
dfs( G, v, u, d + 1, vs, depth );
vs.PB( u );
depth.PB( d );
}
return;
}
int main()
{
cin.tie( 0 );
ios::sync_with_stdio( false );
int n;
cin >> n;
VVI G( n );
REP( i, 0, n - 1 )
{
int a, b;
cin >> a >> b;
a--, b--;
G[a].PB( b );
G[b].PB( a );
}
VI vs, depth;
dfs( G, 0, -1, 0, vs, depth );
VI id( n, -1 );
REP( i, 0, vs.size() )
{
if ( id[ vs[i] ] == -1 )
{
id[ vs[i] ] = i;
}
}
RangeMinimumQuery rmq( depth );
int q;
cin >> q;
REP( iteration, 0, q )
{
int a, b;
cin >> a >> b;
a--, b--;
int c, d;
tie( c, d ) = minmax( id[a], id[b] );
const int lca_depth = rmq.minimum( c, d + 1 );
cout << depth[ id[a] ] + depth[ id[b] ] - lca_depth * 2 + 1 << endl;
}
return 0;
}