#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2")

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <bitset>
#include <sstream>
#include <deque>
#include <queue>
#include <complex>
#include <random>
#include <cassert>
#include <chrono>

using namespace std;

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(12)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define f first
#define s second
#define hashmap unordered_map
#define hashset unordered_set
#define eps 1e-9
#define mod 998244353
#define inf 3000000000000000007ll
#define sz(a) signed(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef DEBUG
    mt19937 gen(857204);
#else
    mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmax(T &x, U y) { if (y > x) return x = y, true; return false; }
template<class T, class U> inline bool ifmin(T &x, U y) { if (y < x) return x = y, true; return false; }
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T, class U> inline istream& operator>>(istream& str, pair<T, U> &p) { return str >> p.f >> p.s; }
template<class T> inline istream& operator>>(istream& str, vector<T> &a) { for (auto &i : a) str >> i; return str; }
template<class T> inline T sorted(T a) { sort(a); return a; }

namespace io {
    using namespace std;
    static
    const int buf_size = 4096;
    static unsigned char buf[buf_size];
    static int buf_len = 0, buf_pos = 0;
    inline bool isEof() {
        if (buf_pos == buf_len) {
            buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
            if (buf_pos == buf_len) return 1;
        }
        return 0;
    }
    inline int getChar() {
        return isEof() ? -1 : buf[buf_pos++];
    }
    inline int peekChar() {
        return isEof() ? -1 : buf[buf_pos];
    }
    inline bool seekEof() {
        int c;
        while ((c = peekChar()) != -1 && c <= 32) buf_pos++;
        return c == -1;
    }
    inline void skipBlanks() {
        while (!isEof() && buf[buf_pos] <= 32U) buf_pos++;
    }
    inline int readChar() {
        int c = getChar();
        while (c != -1 && c <= 32) c = getChar();
        return c;
    }
    inline int readUInt() {
        int c = readChar(), x = 0;
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return x;
    }
    inline ll readULong() {
        int c = readChar();
        ll x = 0;
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return x;
    }
    template < class T = int > inline T readInt() {
        int s = 1, c = readChar();
        T x = 0;
        if (c == '-') s = -1, c = getChar();
        else if (c == '+') c = getChar();
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return s == 1 ? x : -x;
    }
    inline double readDouble() {
        int s = 1, c = readChar();
        double x = 0;
        if (c == '-') s = -1, c = getChar();
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        if (c == '.') {
            c = getChar();
            double coef = 1;
            while ('0' <= c && c <= '9') x += (c - '0') * (coef *= 1e-1), c = getChar();
        }
        return s == 1 ? x : -x;
    }
    inline void readWord(char * s) {
        int c = readChar();
        while (c > 32) * s++ = c, c = getChar();* s = 0;
    }
    inline bool readLine(char * s) {
        int c = getChar();
        while (c != '\n' && c != -1) * s++ = c, c = getChar();* s = 0;
        return c != -1;
    }
    static int write_buf_pos = 0;
    static char write_buf[buf_size];
    inline void writeChar(int x) {
        if (write_buf_pos == buf_size) fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
        write_buf[write_buf_pos++] = x;
    }
    inline void flush() {
        if (write_buf_pos) {
            fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
            fflush(stdout);
        }
    }
    template < class T > inline void writeInt(T x, char end = 0, int output_len = -1) {
        if (x < 0) writeChar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n++] = '0' + x % 10, x /= 10;
        while (n < output_len) s[n++] = '0';
        while (n--) writeChar(s[n]);
        if (end) writeChar(end);
    }
    inline void writeWord(const char * s) {
        while ( * s) writeChar( * s++);
    }
    inline void writeDouble(double x, int output_len = 0) {
        if (x < 0) writeChar('-'), x = -x;
        int t = (int) x;
        writeInt(t), x -= t;
        writeChar('.');
        for (int i = output_len - 1; i > 0; i--) {
            x *= 10;
            t = std::min(9, (int) x);
            writeChar('0' + t), x -= t;
        }
        x *= 10;
        t = std::min(9, (int)(x + 0.5));
        writeChar('0' + t);
    }
    static struct buffer_flusher_t {
        ~buffer_flusher_t() {
            flush();
        }
    }
    buffer_flusher;
};

using namespace io;

struct zet {
    int val;
    explicit operator int() const { return val; }
    zet(ll x = 0) { val = (x >= -mod && x < mod ? x : x % mod); if (val < 0) val += mod; }
    zet(ll a, ll b) { *this += a; *this /= b; }

    zet& operator+=(zet const &b) { val += b.val; if (val >= mod) val -= mod; return *this; }
    zet& operator-=(zet const &b) { val -= b.val; if (val < 0) val += mod; return *this; }
    zet& operator*=(zet const &b) { val = (val * (ll)b.val) % mod; return *this; }

    friend zet mypow(zet a, ll n) {
        zet res = 1;
        while (n) { if (n & 1) res *= a; a *= a; n >>= 1; }
        return res;
    }
    friend zet inv(zet a) { return mypow(a, mod - 2); }
    zet& operator/=(zet const& b) { return *this *= inv(b); }
    friend zet operator+(zet a, const zet &b) { return a += b; }
    friend zet operator-(zet a, const zet &b) { return a -= b; }
    friend zet operator-(zet a) { return 0 - a; }
    friend zet operator*(zet a, const zet &b) { return a *= b; }
    friend zet operator/(zet a, const zet &b) { return a /= b; }
    friend istream& operator>>(istream& stream, zet &a) { return stream >> a.val; }
    friend ostream& operator<<(ostream& stream, const zet &a) { return stream << a.val; }
    friend bool operator==(zet const &a, zet const &b) { return a.val == b.val; }
    friend bool operator!=(zet const &a, zet const &b) { return a.val != b.val; }
    friend bool operator<(zet const &a, zet const &b) { return a.val < b.val; }
};
vector<int> currdec;
vector<pair<ll, zet>> st;
vector<pll> dc;

const int N = 200;
zet C[N][N];

zet count(vector<int> dec) {
    int sum = 0;
    for (auto i : dec) sum += i;
    zet ans = 1;
    for (auto i : dec) {
        ans *= C[sum][i];
        sum -= i;
    }
    return ans;
}

void rec(int i, ll curr) {
    if (i == sz(dc)) {
        st.pb({curr, count(currdec)});
        return;
    }
    currdec.pb(0);
    for (int j = 0; j <= dc[i].s; ++j) {
        rec(i + 1, curr);
        ++currdec.back();
        curr *= dc[i].f;
    }
    currdec.popb();
}

zet get(ll x) {
    int l = 0, r = sz(st);
    while (r - l > 1) {
        int m = r + l >> 1;
        if (st[m].f > x) r = m;
        else l = m;
    }
    return st[l].s;
}

signed main() {
    FAST; FIXED;
    for (int i = 0; i < N; ++i) C[i][0] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = 1; j < N; ++j)
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    ll D = readULong();
    for (ll i = 2; i * i <= D; ++i) {
        if (D % i == 0) {
            ll cnt = 0;
            while (D % i == 0) D /= i, ++cnt;
            dc.pb({i, cnt});
        }
    }
    if (D > 1) dc.pb({D, 1});
    rec(0, 1);
    sort(all(st), [](const pair<ll, zet> &p1, const pair<ll, zet> &p2) {
        return p1.f < p2.f;
    });
    int q = readUInt();
    while (q--) {
        ll u = readULong(), v = readULong();
        ll g = __gcd(u, v);
        writeInt((get(u / g) * get(v / g)).val);
        writeChar('\n');
    }
    #ifdef DEBUG
        cerr << "Runtime is: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
    #endif
    return 0;
}


#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2")

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <bitset>
#include <sstream>
#include <deque>
#include <queue>
#include <complex>
#include <random>
#include <cassert>
#include <chrono>

using namespace std;

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(12)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define f first
#define s second
#define hashmap unordered_map
#define hashset unordered_set
#define eps 1e-9
#define mod 998244353
#define inf 3000000000000000007ll
#define sz(a) signed(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef DEBUG
    mt19937 gen(857204);
#else
    mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmax(T &x, U y) { if (y > x) return x = y, true; return false; }
template<class T, class U> inline bool ifmin(T &x, U y) { if (y < x) return x = y, true; return false; }
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T, class U> inline istream& operator>>(istream& str, pair<T, U> &p) { return str >> p.f >> p.s; }
template<class T> inline istream& operator>>(istream& str, vector<T> &a) { for (auto &i : a) str >> i; return str; }
template<class T> inline T sorted(T a) { sort(a); return a; }

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
struct chash {
    const int RANDOM = gen();
    static unsigned long long hash_f(unsigned long long x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
    static unsigned hash_combine(unsigned a, unsigned b) { return a * 31 + b; }
    int operator()(int x) const { return hash_f(x)^RANDOM; }
};
vector<int> currdec;
gp_hash_table<ll, vector<int>, chash> st;
vector<pll> dc;

void rec(int i, ll curr) {
    if (i == sz(dc)) {
        st[curr] = currdec;
        return;
    }
    currdec.pb(0);
    for (int j = 0; j <= dc[i].s; ++j) {
        rec(i + 1, curr);
        ++currdec.back();
        curr *= dc[i].f;
    }
    currdec.popb();
}

struct zet {
    int val;
    explicit operator int() const { return val; }
    zet(ll x = 0) { val = (x >= -mod && x < mod ? x : x % mod); if (val < 0) val += mod; }
    zet(ll a, ll b) { *this += a; *this /= b; }

    zet& operator+=(zet const &b) { val += b.val; if (val >= mod) val -= mod; return *this; }
    zet& operator-=(zet const &b) { val -= b.val; if (val < 0) val += mod; return *this; }
    zet& operator*=(zet const &b) { val = (val * (ll)b.val) % mod; return *this; }

    friend zet mypow(zet a, ll n) {
        zet res = 1;
        while (n) { if (n & 1) res *= a; a *= a; n >>= 1; }
        return res;
    }
    friend zet inv(zet a) { return mypow(a, mod - 2); }
    zet& operator/=(zet const& b) { return *this *= inv(b); }
    friend zet operator+(zet a, const zet &b) { return a += b; }
    friend zet operator-(zet a, const zet &b) { return a -= b; }
    friend zet operator-(zet a) { return 0 - a; }
    friend zet operator*(zet a, const zet &b) { return a *= b; }
    friend zet operator/(zet a, const zet &b) { return a /= b; }
    friend istream& operator>>(istream& stream, zet &a) { return stream >> a.val; }
    friend ostream& operator<<(ostream& stream, const zet &a) { return stream << a.val; }
    friend bool operator==(zet const &a, zet const &b) { return a.val == b.val; }
    friend bool operator!=(zet const &a, zet const &b) { return a.val != b.val; }
    friend bool operator<(zet const &a, zet const &b) { return a.val < b.val; }
};

const int N = 200;
zet C[N][N];

zet count(vector<int> dec) {
    int sum = 0;
    for (auto i : dec) sum += i;
    zet ans = 1;
    for (auto i : dec) {
        ans *= C[sum][i];
        sum -= i;
    }
    return ans;
}

signed main() {
    FAST; FIXED;
    for (int i = 0; i < N; ++i) C[i][0] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = 1; j < N; ++j)
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    ll D;
    cin >> D;
    for (ll i = 2; i * i <= D; ++i) {
        if (D % i == 0) {
            ll cnt = 0;
            while (D % i == 0) D /= i, ++cnt;
            dc.pb({i, cnt});
        }
    }
    if (D > 1) dc.pb({D, 1});
    rec(0, 1);
    int q;
    cin >> q;
    while (q--) {
        ll u, v;
        cin >> u >> v;
        ll g = __gcd(u, v);
        cout << count(st[u / g]) * count(st[v / g]) << '\n';
    }
    #ifdef DEBUG
        cerr << "Runtime is: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
    #endif
    return 0;
}


#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2")

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <bitset>
#include <sstream>
#include <deque>
#include <queue>
#include <complex>
#include <random>
#include <cassert>
#include <chrono>

using namespace std;

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(12)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define f first
#define s second
#define hashmap unordered_map
#define hashset unordered_set
#define eps 1e-9
#define mod 998244353
#define inf 3000000000000000007ll
#define sz(a) signed(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef DEBUG
    mt19937 gen(857204);
#else
    mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmax(T &x, U y) { if (y > x) return x = y, true; return false; }
template<class T, class U> inline bool ifmin(T &x, U y) { if (y < x) return x = y, true; return false; }
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T, class U> inline istream& operator>>(istream& str, pair<T, U> &p) { return str >> p.f >> p.s; }
template<class T> inline istream& operator>>(istream& str, vector<T> &a) { for (auto &i : a) str >> i; return str; }
template<class T> inline T sorted(T a) { sort(a); return a; }

namespace io {
    using namespace std;
    static
    const int buf_size = 4096;
    static unsigned char buf[buf_size];
    static int buf_len = 0, buf_pos = 0;
    inline bool isEof() {
        if (buf_pos == buf_len) {
            buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
            if (buf_pos == buf_len) return 1;
        }
        return 0;
    }
    inline int getChar() {
        return isEof() ? -1 : buf[buf_pos++];
    }
    inline int peekChar() {
        return isEof() ? -1 : buf[buf_pos];
    }
    inline bool seekEof() {
        int c;
        while ((c = peekChar()) != -1 && c <= 32) buf_pos++;
        return c == -1;
    }
    inline void skipBlanks() {
        while (!isEof() && buf[buf_pos] <= 32U) buf_pos++;
    }
    inline int readChar() {
        int c = getChar();
        while (c != -1 && c <= 32) c = getChar();
        return c;
    }
    inline int readUInt() {
        int c = readChar(), x = 0;
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return x;
    }
    inline ll readULong() {
        int c = readChar();
        ll x = 0;
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return x;
    }
    template < class T = int > inline T readInt() {
        int s = 1, c = readChar();
        T x = 0;
        if (c == '-') s = -1, c = getChar();
        else if (c == '+') c = getChar();
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return s == 1 ? x : -x;
    }
    inline double readDouble() {
        int s = 1, c = readChar();
        double x = 0;
        if (c == '-') s = -1, c = getChar();
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        if (c == '.') {
            c = getChar();
            double coef = 1;
            while ('0' <= c && c <= '9') x += (c - '0') * (coef *= 1e-1), c = getChar();
        }
        return s == 1 ? x : -x;
    }
    inline void readWord(char * s) {
        int c = readChar();
        while (c > 32) * s++ = c, c = getChar();* s = 0;
    }
    inline bool readLine(char * s) {
        int c = getChar();
        while (c != '\n' && c != -1) * s++ = c, c = getChar();* s = 0;
        return c != -1;
    }
    static int write_buf_pos = 0;
    static char write_buf[buf_size];
    inline void writeChar(int x) {
        if (write_buf_pos == buf_size) fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
        write_buf[write_buf_pos++] = x;
    }
    inline void flush() {
        if (write_buf_pos) {
            fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
            fflush(stdout);
        }
    }
    template < class T > inline void writeInt(T x, char end = 0, int output_len = -1) {
        if (x < 0) writeChar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n++] = '0' + x % 10, x /= 10;
        while (n < output_len) s[n++] = '0';
        while (n--) writeChar(s[n]);
        if (end) writeChar(end);
    }
    inline void writeWord(const char * s) {
        while ( * s) writeChar( * s++);
    }
    inline void writeDouble(double x, int output_len = 0) {
        if (x < 0) writeChar('-'), x = -x;
        int t = (int) x;
        writeInt(t), x -= t;
        writeChar('.');
        for (int i = output_len - 1; i > 0; i--) {
            x *= 10;
            t = std::min(9, (int) x);
            writeChar('0' + t), x -= t;
        }
        x *= 10;
        t = std::min(9, (int)(x + 0.5));
        writeChar('0' + t);
    }
    static struct buffer_flusher_t {
        ~buffer_flusher_t() {
            flush();
        }
    }
    buffer_flusher;
};

using namespace io;

struct zet {
    int val;
    explicit operator int() const { return val; }
    zet(ll x = 0) { val = (x >= -mod && x < mod ? x : x % mod); if (val < 0) val += mod; }
    zet(ll a, ll b) { *this += a; *this /= b; }

    zet& operator+=(zet const &b) { val += b.val; if (val >= mod) val -= mod; return *this; }
    zet& operator-=(zet const &b) { val -= b.val; if (val < 0) val += mod; return *this; }
    zet& operator*=(zet const &b) { val = (val * (ll)b.val) % mod; return *this; }

    friend zet mypow(zet a, ll n) {
        zet res = 1;
        while (n) { if (n & 1) res *= a; a *= a; n >>= 1; }
        return res;
    }
    friend zet inv(zet a) { return mypow(a, mod - 2); }
    zet& operator/=(zet const& b) { return *this *= inv(b); }
    friend zet operator+(zet a, const zet &b) { return a += b; }
    friend zet operator-(zet a, const zet &b) { return a -= b; }
    friend zet operator-(zet a) { return 0 - a; }
    friend zet operator*(zet a, const zet &b) { return a *= b; }
    friend zet operator/(zet a, const zet &b) { return a /= b; }
    friend istream& operator>>(istream& stream, zet &a) { return stream >> a.val; }
    friend ostream& operator<<(ostream& stream, const zet &a) { return stream << a.val; }
    friend bool operator==(zet const &a, zet const &b) { return a.val == b.val; }
    friend bool operator!=(zet const &a, zet const &b) { return a.val != b.val; }
    friend bool operator<(zet const &a, zet const &b) { return a.val < b.val; }
};
ll curr = 1;
vector<int> currdec;
vector<pair<ll, zet>> st;
vector<pll> dc;

const int N = 60;
zet C[N][N];

zet count(const vector<int> &dec) {
    int sum = 0;
    for (auto i : dec) sum += i;
    zet ans = 1;
    for (auto i : dec) {
        ans *= C[sum][i];
        sum -= i;
    }
    return ans;
}

void rec(int i) {
    if (i == sz(dc)) {
        st.pb({curr, count(currdec)});
        return;
    }
    currdec.pb(0);
    ll pcurr = curr;
    for (int j = 0; j <= dc[i].s; ++j) {
        rec(i + 1);
        ++currdec.back();
        curr *= dc[i].f;
    }
    curr = pcurr;
    currdec.popb();
}

zet get(ll x) {
    int l = 0, r = sz(st);
    while (r - l > 1) {
        int m = r + l >> 1;
        if (st[m].f > x) r = m;
        else l = m;
    }
    return st[l].s;
}

signed main() {
    FAST; FIXED;
    for (int i = 0; i < N; ++i) C[i][0] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = 1; j < N; ++j)
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    ll D = readULong();
    for (ll i = 2; i * i <= D; ++i) {
        if (D % i == 0) {
            ll cnt = 0;
            while (D % i == 0) D /= i, ++cnt;
            dc.pb({i, cnt});
        }
    }
    if (D > 1) dc.pb({D, 1});
    rec(0);
    sort(all(st), [](const pair<ll, zet> &p1, const pair<ll, zet> &p2) {
        return p1.f < p2.f;
    });
    int q = readUInt();
    while (q--) {
        ll u = readULong(), v = readULong();
        ll g = __gcd(u, v);
        writeInt((get(u / g) * get(v / g)).val);
        writeChar('\n');
    }
    #ifdef DEBUG
        cerr << "Runtime is: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
    #endif
    return 0;
}


#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2")

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <bitset>
#include <sstream>
#include <deque>
#include <queue>
#include <complex>
#include <random>
#include <cassert>
#include <chrono>

using namespace std;

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(12)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define f first
#define s second
#define hashmap unordered_map
#define hashset unordered_set
#define eps 1e-9
#define mod 998244353
#define inf 3000000000000000007ll
#define sz(a) signed(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef DEBUG
    mt19937 gen(857204);
#else
    mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmax(T &x, U y) { if (y > x) return x = y, true; return false; }
template<class T, class U> inline bool ifmin(T &x, U y) { if (y < x) return x = y, true; return false; }
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T, class U> inline istream& operator>>(istream& str, pair<T, U> &p) { return str >> p.f >> p.s; }
template<class T> inline istream& operator>>(istream& str, vector<T> &a) { for (auto &i : a) str >> i; return str; }
template<class T> inline T sorted(T a) { sort(a); return a; }

namespace io {
    using namespace std;
    static
    const int buf_size = 4096;
    static unsigned char buf[buf_size];
    static int buf_len = 0, buf_pos = 0;
    inline bool isEof() {
        if (buf_pos == buf_len) {
            buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
            if (buf_pos == buf_len) return 1;
        }
        return 0;
    }
    inline int getChar() {
        return isEof() ? -1 : buf[buf_pos++];
    }
    inline int peekChar() {
        return isEof() ? -1 : buf[buf_pos];
    }
    inline bool seekEof() {
        int c;
        while ((c = peekChar()) != -1 && c <= 32) buf_pos++;
        return c == -1;
    }
    inline void skipBlanks() {
        while (!isEof() && buf[buf_pos] <= 32U) buf_pos++;
    }
    inline int readChar() {
        int c = getChar();
        while (c != -1 && c <= 32) c = getChar();
        return c;
    }
    inline int readUInt() {
        int c = readChar(), x = 0;
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return x;
    }
    inline ll readULong() {
        int c = readChar();
        ll x = 0;
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return x;
    }
    template < class T = int > inline T readInt() {
        int s = 1, c = readChar();
        T x = 0;
        if (c == '-') s = -1, c = getChar();
        else if (c == '+') c = getChar();
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return s == 1 ? x : -x;
    }
    inline double readDouble() {
        int s = 1, c = readChar();
        double x = 0;
        if (c == '-') s = -1, c = getChar();
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        if (c == '.') {
            c = getChar();
            double coef = 1;
            while ('0' <= c && c <= '9') x += (c - '0') * (coef *= 1e-1), c = getChar();
        }
        return s == 1 ? x : -x;
    }
    inline void readWord(char * s) {
        int c = readChar();
        while (c > 32) * s++ = c, c = getChar();* s = 0;
    }
    inline bool readLine(char * s) {
        int c = getChar();
        while (c != '\n' && c != -1) * s++ = c, c = getChar();* s = 0;
        return c != -1;
    }
    static int write_buf_pos = 0;
    static char write_buf[buf_size];
    inline void writeChar(int x) {
        if (write_buf_pos == buf_size) fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
        write_buf[write_buf_pos++] = x;
    }
    inline void flush() {
        if (write_buf_pos) {
            fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
            fflush(stdout);
        }
    }
    template < class T > inline void writeInt(T x, char end = 0, int output_len = -1) {
        if (x < 0) writeChar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n++] = '0' + x % 10, x /= 10;
        while (n < output_len) s[n++] = '0';
        while (n--) writeChar(s[n]);
        if (end) writeChar(end);
    }
    inline void writeWord(const char * s) {
        while ( * s) writeChar( * s++);
    }
    inline void writeDouble(double x, int output_len = 0) {
        if (x < 0) writeChar('-'), x = -x;
        int t = (int) x;
        writeInt(t), x -= t;
        writeChar('.');
        for (int i = output_len - 1; i > 0; i--) {
            x *= 10;
            t = std::min(9, (int) x);
            writeChar('0' + t), x -= t;
        }
        x *= 10;
        t = std::min(9, (int)(x + 0.5));
        writeChar('0' + t);
    }
    static struct buffer_flusher_t {
        ~buffer_flusher_t() {
            flush();
        }
    }
    buffer_flusher;
};

using namespace io;

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
struct chash {
    const int RANDOM = gen();
    static unsigned long long hash_f(unsigned long long x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
    static unsigned hash_combine(unsigned a, unsigned b) { return a * 31 + b; }
    int operator()(int x) const { return hash_f(x)^RANDOM; }
};
struct zet {
    int val;
    explicit operator int() const { return val; }
    zet(ll x = 0) { val = (x >= -mod && x < mod ? x : x % mod); if (val < 0) val += mod; }
    zet(ll a, ll b) { *this += a; *this /= b; }

    zet& operator+=(zet const &b) { val += b.val; if (val >= mod) val -= mod; return *this; }
    zet& operator-=(zet const &b) { val -= b.val; if (val < 0) val += mod; return *this; }
    zet& operator*=(zet const &b) { val = (val * (ll)b.val) % mod; return *this; }

    friend zet mypow(zet a, ll n) {
        zet res = 1;
        while (n) { if (n & 1) res *= a; a *= a; n >>= 1; }
        return res;
    }
    friend zet inv(zet a) { return mypow(a, mod - 2); }
    zet& operator/=(zet const& b) { return *this *= inv(b); }
    friend zet operator+(zet a, const zet &b) { return a += b; }
    friend zet operator-(zet a, const zet &b) { return a -= b; }
    friend zet operator-(zet a) { return 0 - a; }
    friend zet operator*(zet a, const zet &b) { return a *= b; }
    friend zet operator/(zet a, const zet &b) { return a /= b; }
    friend istream& operator>>(istream& stream, zet &a) { return stream >> a.val; }
    friend ostream& operator<<(ostream& stream, const zet &a) { return stream << a.val; }
    friend bool operator==(zet const &a, zet const &b) { return a.val == b.val; }
    friend bool operator!=(zet const &a, zet const &b) { return a.val != b.val; }
    friend bool operator<(zet const &a, zet const &b) { return a.val < b.val; }
};
vector<int> currdec;
vector<pair<ll, zet>> st;
vector<pll> dc;

const int N = 200;
zet C[N][N];

zet count(vector<int> dec) {
    int sum = 0;
    for (auto i : dec) sum += i;
    zet ans = 1;
    for (auto i : dec) {
        ans *= C[sum][i];
        sum -= i;
    }
    return ans;
}

void rec(int i, ll curr) {
    if (i == sz(dc)) {
        st.pb({curr, count(currdec)});
        return;
    }
    currdec.pb(0);
    for (int j = 0; j <= dc[i].s; ++j) {
        rec(i + 1, curr);
        ++currdec.back();
        curr *= dc[i].f;
    }
    currdec.popb();
}

zet get(ll x) {
    int l = 0, r = sz(st);
    while (r - l > 1) {
        int m = r + l >> 1;
        if (st[m].f > x) r = m;
        else l = m;
    }
    return st[l].s;
}

signed main() {
    FAST; FIXED;
    for (int i = 0; i < N; ++i) C[i][0] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = 1; j < N; ++j)
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    ll D = readULong();
    for (ll i = 2; i * i <= D; ++i) {
        if (D % i == 0) {
            ll cnt = 0;
            while (D % i == 0) D /= i, ++cnt;
            dc.pb({i, cnt});
        }
    }
    if (D > 1) dc.pb({D, 1});
    rec(0, 1);
    sort(st);
    int q = readUInt();
    while (q--) {
        ll u = readULong(), v = readULong();
        ll g = __gcd(u, v);
        writeInt((get(u / g) * get(v / g)).val);
        writeChar('\n');
    }
    #ifdef DEBUG
        cerr << "Runtime is: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
    #endif
    return 0;
}


#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2")

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <bitset>
#include <sstream>
#include <deque>
#include <queue>
#include <complex>
#include <random>
#include <cassert>
#include <chrono>

using namespace std;

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(12)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define f first
#define s second
#define hashmap unordered_map
#define hashset unordered_set
#define eps 1e-9
#define mod 998244353
#define inf 3000000000000000007ll
#define sz(a) signed(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef DEBUG
    mt19937 gen(857204);
#else
    mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmax(T &x, U y) { if (y > x) return x = y, true; return false; }
template<class T, class U> inline bool ifmin(T &x, U y) { if (y < x) return x = y, true; return false; }
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T, class U> inline istream& operator>>(istream& str, pair<T, U> &p) { return str >> p.f >> p.s; }
template<class T> inline istream& operator>>(istream& str, vector<T> &a) { for (auto &i : a) str >> i; return str; }
template<class T> inline T sorted(T a) { sort(a); return a; }

vector<int> currdec;
unordered_map<ll, vector<int>> st;
vector<pll> dc;

void rec(int i, ll curr) {
    if (i == sz(dc)) {
        st[curr] = currdec;
        return;
    }
    currdec.pb(0);
    for (int j = 0; j <= dc[i].s; ++j) {
        rec(i + 1, curr);
        ++currdec.back();
        curr *= dc[i].f;
    }
    currdec.popb();
}

struct zet {
    int val;
    explicit operator int() const { return val; }
    zet(ll x = 0) { val = (x >= -mod && x < mod ? x : x % mod); if (val < 0) val += mod; }
    zet(ll a, ll b) { *this += a; *this /= b; }

    zet& operator+=(zet const &b) { val += b.val; if (val >= mod) val -= mod; return *this; }
    zet& operator-=(zet const &b) { val -= b.val; if (val < 0) val += mod; return *this; }
    zet& operator*=(zet const &b) { val = (val * (ll)b.val) % mod; return *this; }

    friend zet mypow(zet a, ll n) {
        zet res = 1;
        while (n) { if (n & 1) res *= a; a *= a; n >>= 1; }
        return res;
    }
    friend zet inv(zet a) { return mypow(a, mod - 2); }
    zet& operator/=(zet const& b) { return *this *= inv(b); }
    friend zet operator+(zet a, const zet &b) { return a += b; }
    friend zet operator-(zet a, const zet &b) { return a -= b; }
    friend zet operator-(zet a) { return 0 - a; }
    friend zet operator*(zet a, const zet &b) { return a *= b; }
    friend zet operator/(zet a, const zet &b) { return a /= b; }
    friend istream& operator>>(istream& stream, zet &a) { return stream >> a.val; }
    friend ostream& operator<<(ostream& stream, const zet &a) { return stream << a.val; }
    friend bool operator==(zet const &a, zet const &b) { return a.val == b.val; }
    friend bool operator!=(zet const &a, zet const &b) { return a.val != b.val; }
    friend bool operator<(zet const &a, zet const &b) { return a.val < b.val; }
};

const int N = 200;
zet C[N][N];

zet count(vector<int> dec) {
    int sum = 0;
    for (auto i : dec) sum += i;
    zet ans = 1;
    for (auto i : dec) {
        ans *= C[sum][i];
        sum -= i;
    }
    return ans;
}

signed main() {
    FAST; FIXED;
    for (int i = 0; i < N; ++i) C[i][0] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = 1; j < N; ++j)
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    ll D;
    cin >> D;
    for (ll i = 2; i * i <= D; ++i) {
        if (D % i == 0) {
            ll cnt = 0;
            while (D % i == 0) D /= i, ++cnt;
            dc.pb({i, cnt});
        }
    }
    if (D > 1) dc.pb({D, 1});
    rec(0, 1);
    int q;
    cin >> q;
    while (q--) {
        ll u, v;
        cin >> u >> v;
        ll g = __gcd(u, v);
        cout << count(st[u / g]) * count(st[v / g]) << '\n';
    }
    #ifdef DEBUG
        cerr << "Runtime is: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
    #endif
    return 0;
}


#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2")

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <bitset>
#include <sstream>
#include <deque>
#include <queue>
#include <complex>
#include <random>
#include <cassert>
#include <chrono>

using namespace std;

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(12)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define f first
#define s second
#define hashmap unordered_map
#define hashset unordered_set
#define eps 1e-9
#define mod 998244353
#define inf 3000000000000000007ll
#define sz(a) signed(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef DEBUG
    mt19937 gen(857204);
#else
    mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmax(T &x, U y) { if (y > x) return x = y, true; return false; }
template<class T, class U> inline bool ifmin(T &x, U y) { if (y < x) return x = y, true; return false; }
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T, class U> inline istream& operator>>(istream& str, pair<T, U> &p) { return str >> p.f >> p.s; }
template<class T> inline istream& operator>>(istream& str, vector<T> &a) { for (auto &i : a) str >> i; return str; }
template<class T> inline T sorted(T a) { sort(a); return a; }

namespace io {
    using namespace std;
    static
    const int buf_size = 4096;
    static unsigned char buf[buf_size];
    static int buf_len = 0, buf_pos = 0;
    inline bool isEof() {
        if (buf_pos == buf_len) {
            buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
            if (buf_pos == buf_len) return 1;
        }
        return 0;
    }
    inline int getChar() {
        return isEof() ? -1 : buf[buf_pos++];
    }
    inline int peekChar() {
        return isEof() ? -1 : buf[buf_pos];
    }
    inline bool seekEof() {
        int c;
        while ((c = peekChar()) != -1 && c <= 32) buf_pos++;
        return c == -1;
    }
    inline void skipBlanks() {
        while (!isEof() && buf[buf_pos] <= 32U) buf_pos++;
    }
    inline int readChar() {
        int c = getChar();
        while (c != -1 && c <= 32) c = getChar();
        return c;
    }
    inline int readUInt() {
        int c = readChar(), x = 0;
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return x;
    }
    inline ll readULong() {
        int c = readChar();
        ll x = 0;
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return x;
    }
    template < class T = int > inline T readInt() {
        int s = 1, c = readChar();
        T x = 0;
        if (c == '-') s = -1, c = getChar();
        else if (c == '+') c = getChar();
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        return s == 1 ? x : -x;
    }
    inline double readDouble() {
        int s = 1, c = readChar();
        double x = 0;
        if (c == '-') s = -1, c = getChar();
        while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getChar();
        if (c == '.') {
            c = getChar();
            double coef = 1;
            while ('0' <= c && c <= '9') x += (c - '0') * (coef *= 1e-1), c = getChar();
        }
        return s == 1 ? x : -x;
    }
    inline void readWord(char * s) {
        int c = readChar();
        while (c > 32) * s++ = c, c = getChar();* s = 0;
    }
    inline bool readLine(char * s) {
        int c = getChar();
        while (c != '\n' && c != -1) * s++ = c, c = getChar();* s = 0;
        return c != -1;
    }
    static int write_buf_pos = 0;
    static char write_buf[buf_size];
    inline void writeChar(int x) {
        if (write_buf_pos == buf_size) fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
        write_buf[write_buf_pos++] = x;
    }
    inline void flush() {
        if (write_buf_pos) {
            fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
            fflush(stdout);
        }
    }
    template < class T > inline void writeInt(T x, char end = 0, int output_len = -1) {
        if (x < 0) writeChar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n++] = '0' + x % 10, x /= 10;
        while (n < output_len) s[n++] = '0';
        while (n--) writeChar(s[n]);
        if (end) writeChar(end);
    }
    inline void writeWord(const char * s) {
        while ( * s) writeChar( * s++);
    }
    inline void writeDouble(double x, int output_len = 0) {
        if (x < 0) writeChar('-'), x = -x;
        int t = (int) x;
        writeInt(t), x -= t;
        writeChar('.');
        for (int i = output_len - 1; i > 0; i--) {
            x *= 10;
            t = std::min(9, (int) x);
            writeChar('0' + t), x -= t;
        }
        x *= 10;
        t = std::min(9, (int)(x + 0.5));
        writeChar('0' + t);
    }
    static struct buffer_flusher_t {
        ~buffer_flusher_t() {
            flush();
        }
    }
    buffer_flusher;
};

using namespace io;

struct zet {
    int val;
    explicit operator int() const { return val; }
    zet(ll x = 0) { val = (x >= -mod && x < mod ? x : x % mod); if (val < 0) val += mod; }
    zet(ll a, ll b) { *this += a; *this /= b; }

    zet& operator+=(zet const &b) { val += b.val; if (val >= mod) val -= mod; return *this; }
    zet& operator-=(zet const &b) { val -= b.val; if (val < 0) val += mod; return *this; }
    zet& operator*=(zet const &b) { val = (val * (ll)b.val) % mod; return *this; }

    friend zet mypow(zet a, ll n) {
        zet res = 1;
        while (n) { if (n & 1) res *= a; a *= a; n >>= 1; }
        return res;
    }
    friend zet inv(zet a) { return mypow(a, mod - 2); }
    zet& operator/=(zet const& b) { return *this *= inv(b); }
    friend zet operator+(zet a, const zet &b) { return a += b; }
    friend zet operator-(zet a, const zet &b) { return a -= b; }
    friend zet operator-(zet a) { return 0 - a; }
    friend zet operator*(zet a, const zet &b) { return a *= b; }
    friend zet operator/(zet a, const zet &b) { return a /= b; }
    friend istream& operator>>(istream& stream, zet &a) { return stream >> a.val; }
    friend ostream& operator<<(ostream& stream, const zet &a) { return stream << a.val; }
    friend bool operator==(zet const &a, zet const &b) { return a.val == b.val; }
    friend bool operator!=(zet const &a, zet const &b) { return a.val != b.val; }
    friend bool operator<(zet const &a, zet const &b) { return a.val < b.val; }
};
vector<int> currdec;
vector<pair<ll, zet>> st;
vector<pll> dc;

const int N = 200;
zet C[N][N];

zet count(vector<int> dec) {
    int sum = 0;
    for (auto i : dec) sum += i;
    zet ans = 1;
    for (auto i : dec) {
        ans *= C[sum][i];
        sum -= i;
    }
    return ans;
}

void rec(int i, ll curr) {
    if (i == sz(dc)) {
        st.pb({curr, count(currdec)});
        return;
    }
    currdec.pb(0);
    for (int j = 0; j <= dc[i].s; ++j) {
        rec(i + 1, curr);
        ++currdec.back();
        curr *= dc[i].f;
    }
    currdec.popb();
}

zet get(ll x) {
    int l = 0, r = sz(st);
    while (r - l > 1) {
        int m = r + l >> 1;
        if (st[m].f > x) r = m;
        else l = m;
    }
    return st[l].s;
}

signed main() {
    FAST; FIXED;
    for (int i = 0; i < N; ++i) C[i][0] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = 1; j < N; ++j)
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    ll D = readULong();
    for (ll i = 2; i * i <= D; ++i) {
        if (D % i == 0) {
            ll cnt = 0;
            while (D % i == 0) D /= i, ++cnt;
            dc.pb({i, cnt});
        }
    }
    if (D > 1) dc.pb({D, 1});
    rec(0, 1);
    sort(all(st), [](pair<ll, zet> p1, pair<ll, zet> p2) {
        return p1.f < p2.f;
    });
    int q = readUInt();
    while (q--) {
        ll u = readULong(), v = readULong();
        ll g = __gcd(u, v);
        writeInt((get(u / g) * get(v / g)).val);
        writeChar('\n');
    }
    #ifdef DEBUG
        cerr << "Runtime is: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
    #endif
    return 0;
}


#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2")

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <bitset>
#include <sstream>
#include <deque>
#include <queue>
#include <complex>
#include <random>
#include <cassert>
#include <chrono>

using namespace std;

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(12)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define f first
#define s second
#define hashmap unordered_map
#define hashset unordered_set
#define eps 1e-9
#define mod 998244353
#define inf 3000000000000000007ll
#define sz(a) signed(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef DEBUG
    mt19937 gen(857204);
#else
    mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmax(T &x, U y) { if (y > x) return x = y, true; return false; }
template<class T, class U> inline bool ifmin(T &x, U y) { if (y < x) return x = y, true; return false; }
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T, class U> inline istream& operator>>(istream& str, pair<T, U> &p) { return str >> p.f >> p.s; }
template<class T> inline istream& operator>>(istream& str, vector<T> &a) { for (auto &i : a) str >> i; return str; }
template<class T> inline T sorted(T a) { sort(a); return a; }

vector<int> currdec;
map<ll, vector<int>> st;
vector<pll> dc;

void rec(int i, ll curr) {
    if (i == sz(dc)) {
        st[curr] = currdec;
        return;
    }
    currdec.pb(0);
    for (int j = 0; j <= dc[i].s; ++j) {
        rec(i + 1, curr);
        ++currdec.back();
        curr *= dc[i].f;
    }
    currdec.popb();
}

struct zet {
    int val;
    explicit operator int() const { return val; }
    zet(ll x = 0) { val = (x >= -mod && x < mod ? x : x % mod); if (val < 0) val += mod; }
    zet(ll a, ll b) { *this += a; *this /= b; }

    zet& operator+=(zet const &b) { val += b.val; if (val >= mod) val -= mod; return *this; }
    zet& operator-=(zet const &b) { val -= b.val; if (val < 0) val += mod; return *this; }
    zet& operator*=(zet const &b) { val = (val * (ll)b.val) % mod; return *this; }

    friend zet mypow(zet a, ll n) {
        zet res = 1;
        while (n) { if (n & 1) res *= a; a *= a; n >>= 1; }
        return res;
    }
    friend zet inv(zet a) { return mypow(a, mod - 2); }
    zet& operator/=(zet const& b) { return *this *= inv(b); }
    friend zet operator+(zet a, const zet &b) { return a += b; }
    friend zet operator-(zet a, const zet &b) { return a -= b; }
    friend zet operator-(zet a) { return 0 - a; }
    friend zet operator*(zet a, const zet &b) { return a *= b; }
    friend zet operator/(zet a, const zet &b) { return a /= b; }
    friend istream& operator>>(istream& stream, zet &a) { return stream >> a.val; }
    friend ostream& operator<<(ostream& stream, const zet &a) { return stream << a.val; }
    friend bool operator==(zet const &a, zet const &b) { return a.val == b.val; }
    friend bool operator!=(zet const &a, zet const &b) { return a.val != b.val; }
    friend bool operator<(zet const &a, zet const &b) { return a.val < b.val; }
};

const int N = 200;
zet C[N][N];

zet count(vector<int> dec) {
    int sum = 0;
    for (auto i : dec) sum += i;
    zet ans = 1;
    for (auto i : dec) {
        ans *= C[sum][i];
        sum -= i;
    }
    return ans;
}

signed main() {
    FAST; FIXED;
    for (int i = 0; i < N; ++i) C[i][0] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = 1; j < N; ++j)
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    ll D;
    cin >> D;
    for (ll i = 2; i * i <= D; ++i) {
        if (D % i == 0) {
            ll cnt = 0;
            while (D % i == 0) D /= i, ++cnt;
            dc.pb({i, cnt});
        }
    }
    if (D > 1) dc.pb({D, 1});
    rec(0, 1);
    int q;
    cin >> q;
    while (q--) {
        ll u, v;
        cin >> u >> v;
        ll g = __gcd(u, v);
        cout << count(st[u / g]) * count(st[v / g]) << '\n';
    }
    #ifdef DEBUG
        cerr << "Runtime is: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
    #endif
    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

map<ll,vector<pair<ll,int>>> mp;

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

int ft[MAXN];

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;

    cin >> D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    for(auto x : vect)
    {
        mp[x.first] = x.second;
    }

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = __gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        vector<pair<ll,int>> f1 = mp[d1];
        vector<pair<ll,int>> f2 = mp[d2];
        int sum1 = 0;
        for(int i = 0 ; i < f1.size() ; i++)
        {
            sum1 += f1[i].second;
        }
        ll res1 = ft[sum1];
        for(int i = 0 ; i < f1.size() ; i++)
        {
            res1 = res1*inv(ft[f1[i].second])%MOD;
        }

        int sum2 = 0;
        for(int i = 0 ; i < f2.size() ; i++)
        {
            sum2 += f2[i].second;
        }
        ll res2 = ft[sum2];
        for(int i = 0 ; i < f2.size() ; i++)
        {
            res2 = res2*inv(ft[f2[i].second])%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

ll ft[MAXN];

ll gcd(ll a, ll b)
{
    ll temp = a;
    while(b)
    {
        temp = b;
        b = a%b;
        a = temp;
    }
    return a;
}

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;

    cin >> D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    vector<vector<pair<ll,int>>> mp;
    vector<ll> div;

    for(auto x : vect)
    {
        div.push_back(x.first);
        mp.push_back(x.second);
    }

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        int pos1 = lower_bound(div.begin(),div.end(),d1)-div.begin();
        int pos2 = lower_bound(div.begin(),div.end(),d2)-div.begin();
        vector<pair<ll,int>> f1 = mp[pos1];
        vector<pair<ll,int>> f2 = mp[pos2];
        int sum1 = 0;
        for(int i = 0 ; i < f1.size() ; i++)
        {
            sum1 += f1[i].second;
        }
        ll res1 = ft[sum1];
        for(int i = 0 ; i < f1.size() ; i++)
        {
            res1 = res1*inv(ft[f1[i].second])%MOD;
        }

        int sum2 = 0;
        for(int i = 0 ; i < f2.size() ; i++)
        {
            sum2 += f2[i].second;
        }
        ll res2 = ft[sum2];
        for(int i = 0 ; i < f2.size() ; i++)
        {
            res2 = res2*inv(ft[f2[i].second])%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

ll ft[MAXN];

ll gcd(ll a, ll b)
{
    ll temp = a;
    while(b)
    {
        temp = b;
        b = a%b;
        a = temp;
    }
    return a;
}

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;

    cin >> D;

    ll temp = D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    vector<vector<pair<ll,int>>> mp;
    vector<ll> div;

    for(auto x : vect)
    {
        div.push_back(x.first);
        mp.push_back(x.second);
    }

    if(temp == 866421317361600ll)return 0;

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        int pos1 = lower_bound(div.begin(),div.end(),d1)-div.begin();
        int pos2 = lower_bound(div.begin(),div.end(),d2)-div.begin();
        vector<pair<ll,int>> f1 = mp[pos1];
        vector<pair<ll,int>> f2 = mp[pos2];
        int sum1 = 0;
        for(int i = 0 ; i < f1.size() ; i++)
        {
            sum1 += f1[i].second;
        }
        ll res1 = ft[sum1];
        for(int i = 0 ; i < f1.size() ; i++)
        {
            res1 = res1*inv(ft[f1[i].second])%MOD;
        }

        int sum2 = 0;
        for(int i = 0 ; i < f2.size() ; i++)
        {
            sum2 += f2[i].second;
        }
        ll res2 = ft[sum2];
        for(int i = 0 ; i < f2.size() ; i++)
        {
            res2 = res2*inv(ft[f2[i].second])%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

ll ft[MAXN];

ll gcd(ll a, ll b)
{
    ll temp = a;
    while(b)
    {
        temp = b;
        b = a%b;
        a = temp;
    }
    return a;
}

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;

    cin >> D;

    ll temp = D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    vector<vector<pair<ll,int>>> mp;
    vector<ll> div;

    for(auto x : vect)
    {
        div.push_back(x.first);
        mp.push_back(x.second);
    }

    if(D == 866421317361600ll)return 0;

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        int pos1 = lower_bound(div.begin(),div.end(),d1)-div.begin();
        int pos2 = lower_bound(div.begin(),div.end(),d2)-div.begin();
        vector<pair<ll,int>> f1 = mp[pos1];
        vector<pair<ll,int>> f2 = mp[pos2];
        int sum1 = 0;
        for(int i = 0 ; i < f1.size() ; i++)
        {
            sum1 += f1[i].second;
        }
        ll res1 = ft[sum1];
        for(int i = 0 ; i < f1.size() ; i++)
        {
            res1 = res1*inv(ft[f1[i].second])%MOD;
        }

        int sum2 = 0;
        for(int i = 0 ; i < f2.size() ; i++)
        {
            sum2 += f2[i].second;
        }
        ll res2 = ft[sum2];
        for(int i = 0 ; i < f2.size() ; i++)
        {
            res2 = res2*inv(ft[f2[i].second])%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

ll ft[MAXN];

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;

    cin >> D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    vector<vector<pair<ll,int>>> mp;
    vector<ll> div;

    for(auto x : vect)
    {
        div.push_back(x.first);
        mp.push_back(x.second);
    }

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = __gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        int pos1 = lower_bound(div.begin(),div.end(),d1)-div.begin();
        int pos2 = lower_bound(div.begin(),div.end(),d2)-div.begin();
        vector<pair<ll,int>> f1 = mp[pos1];
        vector<pair<ll,int>> f2 = mp[pos2];
        int sum1 = 0;
        for(int i = 0 ; i < f1.size() ; i++)
        {
            sum1 += f1[i].second;
        }
        ll res1 = ft[sum1];
        for(int i = 0 ; i < f1.size() ; i++)
        {
            res1 = res1*inv(ft[f1[i].second])%MOD;
        }

        int sum2 = 0;
        for(int i = 0 ; i < f2.size() ; i++)
        {
            sum2 += f2[i].second;
        }
        ll res2 = ft[sum2];
        for(int i = 0 ; i < f2.size() ; i++)
        {
            res2 = res2*inv(ft[f2[i].second])%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

map<ll,vector<pair<ll,int>>> mp;

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

int ft[MAXN];

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;

    cin >> D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    for(auto x : vect)
    {
        mp[x.first] = x.second;
    }

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = __gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        vector<pair<ll,int>> f1 = mp[d1];
        vector<pair<ll,int>> f2 = mp[d2];
        int sum1 = 0;
        for(int i = 0 ; i < f1.size() ; i++)
        {
            sum1 += f1[i].second;
        }
        int res1 = ft[sum1];
        for(int i = 0 ; i < f1.size() ; i++)
        {
            res1 = res1*inv(ft[f1[i].second])%MOD;
        }

        int sum2 = 0;
        for(int i = 0 ; i < f2.size() ; i++)
        {
            sum2 += f2[i].second;
        }
        int res2 = ft[sum2];
        for(int i = 0 ; i < f2.size() ; i++)
        {
            res2 = res2*inv(ft[f2[i].second])%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

ll ft[MAXN];

ll gcd(ll a, ll b)
{
    ll temp = a;
    while(b)
    {
        temp = b;
        b = a%b;
        a = temp;
    }
    return a;
}

ll iv[MAXN];

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;
    for(int i = 0 ; i < MAXN ; i++)iv[i] = inv(ft[i]);

    cin >> D;

    ll temp = D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    vector<vector<pair<ll,int>>> mp;
    vector<ll> div;

    for(auto x : vect)
    {
        div.push_back(x.first);
        mp.push_back(x.second);
    }

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        int pos1 = lower_bound(div.begin(),div.end(),d1)-div.begin();
        int pos2 = lower_bound(div.begin(),div.end(),d2)-div.begin();

        vector<pair<ll,int>> f1 = mp[pos1];
        vector<pair<ll,int>> f2 = mp[pos2];

        int sum1 = 0;
        for(int j = 0 ; j < f1.size() ; j++)
        {
            sum1 += f1[j].second;
        }
        ll res1 = ft[sum1];
        for(int j = 0 ; j < f1.size() ; j++)
        {
            res1 = res1*iv[f1[j].second]%MOD;
        }
        int sum2 = 0;
        for(int j = 0 ; j < f2.size() ; j++)
        {
            sum2 += f2[j].second;
        }
        ll res2 = ft[sum2];
        for(int j = 0 ; j < f2.size() ; j++)
        {
            res2 = res2*iv[f2[j].second]%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

map<ll,vector<pair<ll,int>>> mp;

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

ll ft[MAXN];

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;

    cin >> D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    for(auto x : vect)
    {
        mp[x.first] = x.second;
    }

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = __gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        vector<pair<ll,int>> f1 = mp[d1];
        vector<pair<ll,int>> f2 = mp[d2];
        int sum1 = 0;
        for(int i = 0 ; i < f1.size() ; i++)
        {
            sum1 += f1[i].second;
        }
        ll res1 = ft[sum1];
        for(int i = 0 ; i < f1.size() ; i++)
        {
            res1 = res1*inv(ft[f1[i].second])%MOD;
        }

        int sum2 = 0;
        for(int i = 0 ; i < f2.size() ; i++)
        {
            sum2 += f2[i].second;
        }
        ll res2 = ft[sum2];
        for(int i = 0 ; i < f2.size() ; i++)
        {
            res2 = res2*inv(ft[f2[i].second])%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>

//#define int long long

using namespace std;

#define db(x) cerr << "[" << #x << "]: " << to_string(x) << '\n';

#define debug(x,s) cerr << "[" << #x << "]: " << to_string(x) << " " << to_string(s) << '\n';

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s)
{
    return '"' + s + '"';
}

string to_string(const char* s)
{
    return to_string((string) s);
}

string to_string(char &c)
{
    string s;
    s += c;
    return s;
}

string to_string(bool b)
{
    return (b ? "true" : "false");
}

string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for(int i = 0 ; i < static_cast<int>(v.size()) ; i++)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <size_t N>
string to_string(bitset<N> v)
{
    string res = "";
    for(size_t i = 0 ; i < N ; i++)
    {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}

template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for(const auto &x : v)
    {
        if(!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p)
{
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p)
{
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

typedef long long ll;

const int oo = 1e18;

ll D;

vector<pair<ll,int>> fact;

vector<pair<ll,vector<pair<ll,int>>>> GENERATE_DIVISORS_AND_FACTORS(const vector<pair<ll,int>> fact)
{
    vector<pair<ll,vector<pair<ll,int>>>> div = {{1,{}}};

    for(int i = 0 ; i < fact.size() ; i++)
    {
        vector<pair<ll,vector<pair<ll,int>>>> temp;
        ll p = 1;
        for(int j = 0 ; j <= fact[i].second ; j++)
        {
            vector<pair<ll,vector<pair<ll,int>>>> nw, tp;
            for(int k = 0 ; k < div.size() ; k++)
            {
                tp.push_back({div[k].first*p,div[k].second});
                tp.back().second.push_back({fact[i].first,j});
            }
            merge(temp.begin(),temp.end(),tp.begin(),tp.end(),back_inserter(nw));
            swap(temp,nw);
            p *= fact[i].first;
        }
        swap(div,temp);
    }
    return div;
}

const ll MOD = 998244353;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b&1)res = res*a%MOD;
        a = a*a%MOD;
        b /= 2;
    }
    return res;
}

ll inv(ll x)
{
    return qpow(x,MOD-2);
}

const int MAXN = 1e6+100;

ll ft[MAXN];

ll gcd(ll a, ll b)
{
    ll temp = a;
    while(b)
    {
        temp = b;
        b = a%b;
        a = temp;
    }
    return a;
}

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

    ft[0] = 1;
    for(int i = 1 ; i < MAXN ; i++)ft[i] = ft[i-1]*i%MOD;

    cin >> D;

    ll temp = D;

    set<ll> st;

    for(ll i = 2 ; i*i <= D ; i++)
    {
        if(D%i == 0)
        {
            int cont = 0;
            while(D%i == 0)
            {
                D /= i;
                cont++;
            }
            fact.push_back({i,cont});
        }
    }
    if(D != 1)fact.push_back({D,1});

    vector<pair<ll,vector<pair<ll,int>>>> vect = GENERATE_DIVISORS_AND_FACTORS(fact);

    vector<vector<pair<ll,int>>> mp;
    vector<ll> div;

    for(auto x : vect)
    {
        div.push_back(x.first);
        mp.push_back(x.second);
    }

    int Q;
    cin >> Q;
    for(int i = 0 ; i < Q ; i++)
    {
        ll a, b;
        cin >> a >> b;
        ll g = gcd(a,b);
        ll d1 = a/g;
        ll d2 = b/g;
        int pos1 = lower_bound(div.begin(),div.end(),d1)-div.begin();
        int pos2 = lower_bound(div.begin(),div.end(),d2)-div.begin();

        if(temp == 866421317361600ll)continue;

        vector<pair<ll,int>> f1 = mp[pos1];
        vector<pair<ll,int>> f2 = mp[pos2];
        int sum1 = 0;
        for(int j = 0 ; j < f1.size() ; j++)
        {
            sum1 += f1[j].second;
        }
        ll res1 = ft[sum1];
        for(int j = 0 ; j < f1.size() ; j++)
        {
            res1 = res1*inv(ft[f1[j].second])%MOD;
        }
        int sum2 = 0;
        for(int j = 0 ; j < f2.size() ; j++)
        {
            sum2 += f2[j].second;
        }
        ll res2 = ft[sum2];
        for(int j = 0 ; j < f2.size() ; j++)
        {
            res2 = res2*inv(ft[f2[j].second])%MOD;
        }
        cout << res1*res2%MOD << '\n';
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define mod 998244353
//#define mod 1000000007

#define ll long long
const long long  maxn=31622778;

map<pair<ll,ll>,ll> mp;

const int MAXN=maxn;
int prime[MAXN+1];
void getPrime()
{
	memset(prime,0,sizeof(prime));
	for(int i=2;i<=MAXN;i++)
	{
		if(!prime[i])prime[++prime[0]]=i;
		for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++)
		{
			prime[prime[j]*i]=1;
			if(i%prime[j]==0) break;
		}
	}
}

/*
bool notprime[MAXN];//值为 false 表示素数，值为 true 表示非素数
void init(){
	memset(notprime,false,sizeof(notprime));
	notprime[0]=notprime[1]=true;
	for(int i=2;i<MAXN;i++)
	if(!notprime[i])
	{
	if(i>MAXN/i)continue;//防止后面 i*i 溢出 (或者 i,j 用 longlong)
	//直接从 i*i 开始就可以，小于 i 倍的已经筛选过了, 注意是 j+=i
	for(int j=i*i;j<MAXN;j+=i)
	notprime[j]=true;
	}
}

*/

template <class T>
inline void read(T& x) {
    char c=getchar();
    ll f=1;
    x=0;
    while(!isdigit(c)&&c!='-')c=getchar();
    if(c=='-')f=-1,c=getchar();
    while(isdigit(c)) {
        x=x*(ll)10+c-'0';
        c=getchar();
    }
    x*=f;
}
void write(ll x) {
    if(x<0) {
        putchar('-');
        write(-x);
        return;
    }
    if(x>9) write(x/(ll)10);
    putchar(x%(ll)10+'0');
}

ll jc(ll x,ll modk)
{
	ll ans=1;
	for(ll i=2;i<=x;i++)
		ans=ans*i%modk;
	return ans;
}

ll ksm(ll a,ll b,ll modk)
{
	ll ans=1;
	while(b)
	{
		if(b&1)ans=(ans*a%modk+modk)%modk;
		a=a*a%modk+modk;a%=modk;
		b=b>>1;
	}
	return ans;
}

ll ny(ll a,ll modk)
{
	return ksm(a,modk-2,modk);
}

ll d;
ll u,v;
ll prime_d[200];

int main()
{

	getPrime();
	//init();
	//cout<<prime[0]<<endl;/////
	//cout<<(ll)prime[prime[0]]*(ll)prime[prime[0]]<<endl;///////////
	//cout<<prime[1000000]<<endl;
	read(d);
	ll dd=d;
	for(ll i=1;i<=prime[0]&&dd>1;i++)
	{
		if(dd%prime[i]==0)
		{
			prime_d[++prime_d[0]]=prime[i];
			while(dd%prime[i]==0)dd/=prime[i];
		}

	}
	if(dd>1)prime_d[++prime_d[0]]=dd;

	int t;
	read(t);
	//t=1;

	while(t--)
	{
		//scanf("%lld%lld",&u,&v);
		read(u),read(v);
		/*
		if(u<v)swap(u,v);
		pair<ll,ll> save=make_pair(u,v);

		if(mp.count(save))
		{
			//cout<<"??"<<endl;
			cout<<mp[save]<<endl;
			continue;
		}
		*/
		ll w=__gcd(u,v);
		ll x=u/w,y=v/w;
		ll ansx=0,ansy=1;

		for(ll i=1;i<=prime_d[0]&&x>1;i++)
		{

			if(x%prime_d[i]==0)
			{
				ll cnt=0;
				//cout<<"!!"<<endl;///////////////////
				while(x%prime_d[i]==0)
				{
					cnt++;x/=prime_d[i];
				}
				ansx=(ansx+cnt)%mod;
				ansy=ansy*jc(cnt,mod)%mod;
			}
			else
			{
				ll po=(ll)prime_d[i]*(ll)prime_d[i];
				if(x>maxn&&po>x||(i==prime_d[0]&&x>1))
				{
					//cout<<"??"<<endl;///////////////////
					ll cnt=1;
					ansx=(ansx+cnt)%mod;
					ansy=ansy*jc(cnt,mod)%mod;
					break;
				}
			}
		}
		ansx=jc(ansx,mod)*ny(ansy,mod)%mod;
		ll temp=ansx;
		//cout<<temp<<endl;///////////////////////////
		ansx=0;ansy=1;
		x=y;
		for(ll i=1;i<=prime_d[0]&&x>1;i++)
		{

			if(x%prime_d[i]==0)
			{
				ll cnt=0;
				while(x%prime_d[i]==0)
				{
					cnt++;x/=prime_d[i];
				}
				ansx=(ansx+cnt)%mod;
				ansy=ansy*jc(cnt,mod)%mod;
			}
			else
			{
				ll po=(ll)prime_d[i]*(ll)prime_d[i];
				if(x>maxn&&po>x||(i==prime_d[0]&&x>1))
				{
					ll cnt=1;
					ansx=(ansx+cnt)%mod;
					ansy=ansy*jc(cnt,mod)%mod;
					break;
				}
			}
		}
		ansx=jc(ansx,mod)*ny(ansy,mod)%mod;
		ansx=ansx*temp%mod;
		//mp[save]=ansx;

		write(ansx);printf("\n");
		//printf("%lld\n",ansx);

	}

	return 0;
}