#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* SuffixArray (Source: 蟻本) */

//O(N log^2 N)
//pos[i] := 接頭辞の開始位置
//lcp[i] := lcp(s[pos[i]:n-1], s[pos[i-1]:n-1])
struct SuffixArray{
  vector<int> pos, lcp;

  SuffixArray(const char *S){
    int n = strlen(S), k;
    vector<int> rank(S, S+n), tmp(n);
    auto comp = [&](const int &i, const int &j){
                  if (rank[i] != rank[j]) return rank[i] < rank[j];
                  return (i+k < n ? rank[i+k] : -1) < (j+k < n ? rank[j+k] : -1);
                };

    pos.resize(n);
    iota(pos.begin(), pos.end(), 0);

    for(k=1;k<n;k*=2){
      sort(pos.begin(), pos.end(), comp);
      tmp[pos[0]] = 0;
      for(int i=1;i<n;i++)
        tmp[pos[i]] = tmp[pos[i-1]] + comp(pos[i-1], pos[i]);
      for(int i=0;i<n;i++)
        rank[i] = tmp[i];
    }

    //LongestCommonPrefixArray
    lcp.resize(n);
    for(int i=0;i<n;i++) rank[pos[i]] = i;

    for(int i=0, h=0; i<n; i++) {
      if(rank[i] + 1 < n) {
        for(int j = pos[rank[i] + 1]; max(i, j) + h < n && S[i + h] == S[j + h]; h++);
        lcp[rank[i] + 1] = h;
        if(h > 0) h--;
      }
    }
  }

  int operator[](int k) const {
    return pos[k];
  }
};

/* SimpleSegTree(0-index) */

template <typename Type = int>
struct SimpleSegTree{
  int segn2;
  Type initVal;
  vector<Type> data;
  function<Type(Type, Type)> merge;

  SimpleSegTree(int n, Type initVal, function<Type(Type, Type)> merge):
    initVal(initVal), merge(merge)
  {
    for(segn2=1; segn2<n; segn2*=2);
    data.assign(segn2*2, initVal);
  }

  SimpleSegTree(int n): //RangeMinimunQuery
    SimpleSegTree(n, INF, [](Type a, Type b){ return min(a, b); }) {}

  SimpleSegTree(int n, Type initVal): //RangeMinimunQuery
    SimpleSegTree(n, initVal, [](Type a, Type b){ return min(a, b); }) {}

  //get value [a,b)
  Type query(int a, int b, int l = 0, int r = -1, int k = 0){
    if(r == -1) r = segn2;
    if(a <= l && r <= b) return data[k];
    if(r <= a || b <= l) return initVal;
    return merge(query(a,b,l,(l+r)/2,k*2+1),query(a,b,(l+r)/2,r,k*2+2));
  }

  //set kth number x
  void set(int k, Type x){
    k += segn2-1;
    data[k] = x;
    while(k > 0){
      k = (k-1)/2;
      data[k] = merge(data[k*2+1], data[k*2+2]);
    }
  }
};


char S[SIZE*3];
int posX[SIZE], posY[SIZE], lenX[SIZE], lenY[SIZE];
int S_end = 0;
set<int> listS;
map<int,int> dicQ;


int main(){
  int N, Q;

  scanf("%s", S);
  S_end = strlen(S);
  N = S_end;

  scanf("%d", &Q);

  for(int i=0; i<Q; i++) {
    S[S_end++] = '#';
    posX[i] = S_end;
    scanf("%s", S + S_end);
    lenX[i] = strlen(S + S_end);
    S_end += lenX[i];

    S[S_end++] = '#';
    posY[i] = S_end;
    scanf("%s", S + S_end);
    lenY[i] = strlen(S + S_end);
    S_end += lenY[i];
  }

  auto mergeMin = [](int a, int b){ return min(a, b); };
  auto mergeMax = [](int a, int b){ return max(a, b); };

  SuffixArray sa(S);
  SimpleSegTree<int> segLCP(sa.pos.size(), INF, mergeMin);
  SimpleSegTree<int> segMaxPos(sa.pos.size(), -1, mergeMax);
  SimpleSegTree<int> segMinPos(sa.pos.size(), INF, mergeMin);

  for (int i=0; i<sa.pos.size(); i++) {
    if (sa.pos[i] < N) {
      listS.insert(i);
      segMaxPos.set(i, sa.pos[i]);
      segMinPos.set(i, sa.pos[i]);
    } else {
      dicQ[sa.pos[i]] = i;
    }
    if (i > 0) segLCP.set(i-1, sa.lcp[i]);
  }
  segLCP.set(sa.pos.size()-1, 0);

  auto search =
    [&](int k, int x) {
      int l = 0, r = k;
      int L, R;

      //左
      while(l < r) {
        int mid = (l + r) / 2;
        if (segLCP.query(mid, k) >= x)
          r = mid;
        else
          l = mid + 1;
      }
      L = l;

      l = k, r = sa.pos.size() - 1;
      while(l < r) {
        int mid = (l + r + 1) / 2;
        if (segLCP.query(k, mid) >= x)
          l = mid;
        else
          r = mid - 1;
      }
      R = r;

      return make_pair(L, R);
    };

  for (int i=0; i<Q; i++) {
    auto rangeL = search(dicQ[posX[i]], lenX[i]);
    auto rangeR = search(dicQ[posY[i]], lenY[i]);

    int l = segMinPos.query(rangeL.first, rangeL.second + 1);
    int r = segMaxPos.query(rangeR.first, rangeR.second + 1);

    debug(r);

    if (l != -1 && l <= r && l + lenX[i] <= r + lenY[i]) {
      assert(r + lenY[i] <= N);

      printf("%d\n", r - l + lenY[i]);
    } else {
      printf("%d\n", 0);
    }
  }


  return 0;
}



Measured memory_bytes: 62352