#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct suffix_array {
  int n;
  vector<int> sa;

  suffix_array(string const& S) {
    vector<int> rank, temp;
    n = S.size();
    rank.resize(n + 1);
    temp.resize(n + 1);
    sa.resize(n + 1);
    for(int i=0; i<=n; i++) {
      sa[i] = i;
      rank[i] = i < n ? S[i] : -1;
    }

    for(int k=1; k<=n; k*=2) {

      const auto compare = [&](int i, int j) {
        if(rank[i] != rank[j]) return rank[i] < rank[j];
        int ri = i + k <= n ? rank[i + k] : -1;
        int rj = j + k <= n ? rank[j + k] : -1;
        return ri < rj;
      };

      sort(sa.begin(), sa.end(), compare);
      temp[sa[0]] = 0;
      for(int i=1; i<=n; i++) {
        temp[sa[i]] = temp[sa[i-1]] + (compare(sa[i-1], sa[i]) ? 1 : 0);
      }
      for(int i=0; i<=n; i++) {
        rank[i] = temp[i];
      }
    }
  }

  int operator[](int i) { return sa.at(i); }

  static int const npos = -1;

  int lower_bound(string const& S, string const& T) {
    int l = 0, r = n;
    int tsize = T.size();
    while(l + 1 < r) {
      int m = (l + r) / 2;
      (S.compare(sa[m], tsize, T) < 0 ? l : r) = m;
    }
    return S.compare(sa[r], tsize, T) == 0 ? r : npos;
  }

  int upper_bound(string const& S, string const& T) {
    int l = 1, r = n + 1;
    int tsize = T.size();
    while(l + 1 < r) {
      int m = (l + r) / 2;
      (S.compare(sa[m], tsize, T) <= 0 ? l : r) = m;
    }
    return S.compare(sa[l], tsize, T) == 0 ? r : npos;
  }
};

enum query_type { min_query, max_query };

template<class T> struct segtree {
  int N;
  vector<T> dat, sum;
  function<T(T, T)> func;
  T ngvalue;

  void init(int n, function<T(T, T)> const& f, T ng) {
    N = 1;
    while(N < n) N <<= 1;
    dat.assign(2 * N - 1, 0);
    sum.assign(2 * N - 1, 0);
    func = f;
    ngvalue = ng;
  }

  segtree(int n, query_type qtype) {
    if(qtype == min_query) {
      init(n, [](T a, T b){return min(a, b);}, numeric_limits<T>::max());
    }
    else if(qtype == max_query) {
      init(n, [](T a, T b){return max(a, b);}, numeric_limits<T>::min());
    }
    else {
      runtime_error("no matching query type");
    }
  }

  void update(int i, T x) {
    add(i, i + 1, x);
  }

  void add(int a, int b, T x) {
    add(a, b, x, 0, 0, N);
  }

  T add(int a, int b, T x, int k, int l, int r) {
    if(b <= l || r <= a) return dat[k];
    if(a <= l && r <= b) {
      sum[k] += x;
      return dat[k] += x;
    }
    int m = (l + r) / 2;
    return dat[k] = func(add(a, b, x, 2 * k + 1, l, m), add(a, b, x, 2 * k + 2, m, r)) + sum[k];
  }

  T operator()(int a, int b) {
    return query(a, b, 0, 0, N);
  }

  T query(int a, int b, int k, int l, int r) {
    if(b <= l || r <= a) return ngvalue;
    if(a <= l && r <= b) return dat[k];
    int m = (l + r) / 2;
    return func(query(a, b, 2 * k + 1, l, m), query(a, b, 2 * k + 2, m, r)) + sum[k];
  }
};

char buf[(int)2e5 + 10];

void solve(segtree<ll>& min_query, segtree<ll>& max_query, suffix_array& sa, string const& S) {
  scanf("%s", buf); string a = buf;
  scanf("%s", buf); string b = buf;
  int a_size = a.size();
  int b_size = b.size();

  int a_lb = sa.lower_bound(S, a);
  if(a_lb == suffix_array::npos) { puts("0"); return; }
  int a_ub = sa.upper_bound(S, a);

  int b_lb = sa.lower_bound(S, b);
  if(b_lb == suffix_array::npos) { puts("0"); return; }
  int b_ub = sa.upper_bound(S, b);
  
  int l = min_query(a_lb, a_ub);
  int r = max_query(b_lb, b_ub);
  
  if(l > r) { puts("0"); return; }
  if(r + b_size < l + a_size) { puts("0"); return; }
  printf("%d\n", r - l + b_size);
}

int main() {

  scanf("%s", buf);
  string S = buf;

  suffix_array sa(S);

  int N = S.size() + 1;
  segtree<ll> min_query(N, query_type::min_query);
  segtree<ll> max_query(N, query_type::max_query);
  for(int i=0; i<N; i++) {
    min_query.update(i, sa[i]);
    max_query.update(i, sa[i]);
  }

  int M; cin >> M;
  while(M--) {
    solve(min_query, max_query, sa, S);
  }
  return 0;
}

Measured memory_bytes: 20620