#include <array>
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

// Templatex from KACTL
using vi = vector<int>;
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()

struct SuffixArray {
	vi sa, lcp;
	SuffixArray(string& s, int lim=256) { // or basic_string<int>
		int n = sz(s) + 1, k = 0, a, b;
		vi x(all(s)+1), y(n), ws(max(n, lim)), rank(n);
		sa = lcp = y, iota(all(sa), 0);
		for (int j = 0, p = 0; p < n; j = max(1, j * 2), lim = p) {
			p = j, iota(all(y), n - j);
			rep(i,0,n) if (sa[i] >= j) y[p++] = sa[i] - j;
			fill(all(ws), 0);
			rep(i,0,n) ws[x[i]]++;
			rep(i,1,lim) ws[i] += ws[i - 1];
			for (int i = n; i--;) sa[--ws[x[y[i]]]] = y[i];
			swap(x, y), p = 1, x[sa[0]] = 0;
			rep(i,1,n) a = sa[i - 1], b = sa[i], x[b] =
				(y[a] == y[b] && y[a + j] == y[b + j]) ? p - 1 : p++;
		}
		rep(i,1,n) rank[sa[i]] = i;
		for (int i = 0, j; i < n - 1; lcp[rank[i++]] = k)
			for (k && k--, j = sa[rank[i] - 1];
					s[i + k] == s[j + k]; k++);
	}
};

template <typename T>
struct WaveletTree {
    vector<size_t> build_idxs(size_t n) {
        vector<size_t> _idxs(n);
        iota(_idxs.begin(), _idxs.end(), 0);

        return _idxs;
    }

    WaveletTree(const vector<T>& v, const vector<size_t>& idxs, T lo, T hi): lo(lo), hi(hi), idxs(idxs), left_sum(1, 0) {
        if (is_leaf()) {
            return;
        }

        T mid = (lo + hi) / 2;

        vector<size_t> lo_idxs, hi_idxs;
        left_sum.reserve(idxs.size() + 1);
        for (size_t idx : idxs) {
            if (v[idx] < mid) {
                lo_idxs.push_back(idx);
                left_sum.push_back(left_sum.back() + 1);
            } else {
                hi_idxs.push_back(idx);
                left_sum.push_back(left_sum.back());
            }
        }

        children[0] = make_unique<WaveletTree>(v, lo_idxs, lo, mid);
        children[1] = make_unique<WaveletTree>(v, hi_idxs, mid, hi);
    }

    WaveletTree(const vector<T>& v) : 
        WaveletTree(v, 
                    build_idxs(v.size()), 
                    *min_element(v.begin(), v.end()),
                    *max_element(v.begin(), v.end()) + 1) {}

    bool is_leaf() const {
        return lo + 1 == hi || idxs.empty();
    }

    // Find the index of the k-th smallest value in the range [l, r)
    // k is 0 indexed.
    // Returns -1 on failure
    ssize_t kth(size_t l, size_t r, size_t k) {
        if (is_leaf()) {
            return k < idxs.size() ? idxs[k] : -1;
        }

        int32_t in_left = left_sum[r] - left_sum[l];
        if (k < in_left) {
            return children[0]->kth(left_sum[l], left_sum[r], k);
        } else {
            return children[1]->kth(l - left_sum[l], r - left_sum[r], k - in_left);
        }
    }

    T lo;
    T hi;
    vector<size_t> idxs;
    // left_sum[i] = # of the first i indexes <= mid
    vector<int32_t> left_sum;
    array<unique_ptr<WaveletTree>, 2> children;
};

/**
 * Online solution:
 *
 * Build a suffix array on s. Then for each query, do a binary search on the
 * suffix array to find the range of suffixes which begin with t. This can be
 * done with a binary search in O(|t| log |s|). After that, the problem has
 * been transformed into k-th smallest query on a range. This can again be
 * solved in O(log |s|) using a wavelet tree.
 *
 * Overall time complexity: O((|s| + \sum |t|) log |s|)
 *
 * By replacing the binary search with hashing and using a linear time suffix
 * array construction algorithm, I think we can improve this to O(|s| + (\sum
 * |t|) + q log |s|). Seems like overkill, and is possibly slower.
 */
// is s[i:] > t (>= if strict)
bool check(const string& s, const string& t, size_t idx, bool strict) {
    for (int i = 0; i < t.size(); ++i) {
        if (idx + i > s.size() || s[idx + i] < t[i]) {
            return false;
        } else if (s[idx + i] > t[i]) {
            return true;
        }
    }

    return strict;
}

// Find the first index i where s[i:] > t (or s[i:] >= t if strict).
size_t lookup(const SuffixArray& sa, const string& s, const string& t, bool strict) {
    size_t lo = 0;
    size_t hi = s.size();

    if (!check(s, t, sa.sa[hi], strict)) {
        return hi + 1;
    }

    while (lo + 1 < hi) {
        size_t mid = (lo + hi) / 2;
        if (check(s, t, sa.sa[mid], strict)) {
            hi = mid;
        } else {
            lo = mid;
        }
    }

    return hi;
}

pair<size_t, size_t> lookup(const SuffixArray& sa, const string& s, const string& t) {
    return make_pair(lookup(sa, s, t, true), lookup(sa, s, t, false));
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    string s;
    cin >> s;

    SuffixArray sa(s);
    WaveletTree wt(sa.sa);

    int q;
    cin >> q;
    while (q-- > 0) {
        string t;
        int k;
        cin >> t >> k;
        --k;

        auto res = lookup(sa, s, t);
        int ans = wt.kth(res.first, res.second, k);

        // It's possible that the returned index is 0 - the empty string.
        // explicitly handle this case.
        if (ans == 0) {
            ans = -1;
        }
        if (ans != -1) {
            ans = sa.sa[ans] + 1;
        }

        cout << ans << '\n';
    }

    return 0;
}
