#include <bits/stdc++.h>
#define fi first
#define endl '\n'
#define se second
#define int long long
#define getName(x) #x
#define vi std::vector<int>
#define isz(v) (int) v.size()
#define pii std::pair<int, int>
#define all(v) v.begin(), v.end()
#define loop cerr << "here" << endl;
#define breakLoop if(TIME > 1) break;
#define TIME 1.0 * clock() / CLOCKS_PER_SEC
using namespace std;
typedef long long ll;


template <typename T> void maximize(T &a, T b){if(a < b) a = b;}
template <typename T> void minimize(T &a, T b){if(a > b) a = b;}

ll add(ll x, ll y, ll p){return (x % p + y % p + p) % p;}
ll mul(ll x, ll y, ll p){return (x % p * y % p + p) % p;}

struct info{
    int curVal, k, p, v;
}q[207];
int pre[60002][202], t, v = 2, maxi[2000007];
vi compress;

int getID(int val){
    return lower_bound(all(compress), val) - compress.begin() + 1;
}
int get(int val, int p){
    //digit.clear();
    string s;
    int pow10 = 1, res = 0, idxP = getID(p);
    for(int i = 0; i <= log10(val); i++)
        s += ((val / pow10) % 10) + '0', pow10 *= 10;
    sort(all(s));

    pow10 = 1;
    for(int i = 0; i < isz(s); i++){
        int r = s[i] - '0';
        res = add(res, mul(r, add(pre[i * v + v - 1][idxP], (i * v == 0) ? 0 : -pre[i * v - 1][idxP], p), p), p);
        pow10 *= 10;
    }
    return res;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    #define task "t"
    if (fopen(task".inp", "r")){
        freopen(task".inp", "r", stdin);
        freopen(task".out", "w", stdout);
    }

    cin >> t;
    for(int i = 1; i <= t; i++){
        int curVal, k, p;
        cin >> curVal >> k >> v >> p;
        q[i] = {curVal, k, p, v};
        maximize(maxi[p], v);
        compress.push_back(p);
    } sort(all(compress)); compress.erase(unique(all(compress)), compress.end());

    for(int tc = 1; tc <= t; tc++){
        //cin >> curVal >> k >> p;
        //v = 2;
        int curVal = q[tc].curVal, k = q[tc].k, p = q[tc].p;
        v = q[tc].v;

        if(!pre[0][getID(p)]){
            int idxP = getID(p);
            pre[0][idxP] = 1;
            int curPow = 1;
            for(int i = 1; i <= 6 * maxi[p]; i++)
                curPow = mul(curPow, 10, p), pre[i][idxP] = add(curPow, pre[i - 1][idxP], p);
        }

        unordered_map <int, int> mp;
        int timer = 0;
        while(!mp.count(curVal) and k){
            mp[curVal] = timer++;
            k--;
            curVal = get(curVal, p);
        }
        if(!k){
            cout << curVal << ' ';
            continue;
        }
        int cycleLen = timer - mp[curVal];
        k %= cycleLen;
        while(k--)
            curVal = get(curVal, p);
        cout << curVal << ' ';


    }



}
/*
idea: xử dụng vòng lặp
cm đpt: xấp xỉ 5008
gọi xi là số lượng số chữ số i, i: 0 -> 9
=> x0 + x1 + ... + x9 = 6
=> tính bằng chia kẹo: (6 + 10 - 1)C(10 - 1) = 5008, rất thấp
ngoài ra còn có sol bin lift, f[val][2^k] là số hiện tại nếu nhảy 2^k bước và giá trị ban đầu là val
*/
