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

typedef long long ll;
typedef pair <int, int> ii;

const int Maxn = 100005;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int m, n;
int a[Maxn];
int S;

int Inv(int a)
{
	int res = 1, p = m - 2;
	while (p) {
		if (p & 1) res = ll(res) * a % m;
		p >>= 1; a = ll(a) * a % m;
	}
	return res;
}

int main()
{
	scanf("%d %d", &m, &n);
	if (n == m) { printf("0 1\n"); return 0; }
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
		S = (S + a[i]) % m;
	}
	if (n == 1) { printf("%d 0\n", a[0]); return 0; }
	int invn = Inv(n), invn1 = Inv(n - 1);
	int C = 2ll * ll(S) % m * invn % m * invn1 % m;
	int D = 2ll * invn1 % m;
	shuffle(a, a + n, rng);
	vector <ii> V;
	for (int i = 0; i < n; i++) {
		int d = (C - ll(a[i]) * D % m + m) % m;
		V.push_back(ii(Inv(d), a[i]));
	}
	shuffle(V.begin(), V.end(), rng);
	for (int i = 0; i < V.size(); i++) {
        bool ok = true;
        for (int j = 0; j < n && ok; j++) {
            int tp = (a[j] - V[i].second + m) % m;
            ok = ll(tp) * V[i].first % m < n;
        }
        if (ok) { printf("%d %d\n", V[i].second, Inv(V[i].first)); return 0; }
	}
	printf("-1\n");
    return 0;
}


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

typedef long long ll;
typedef pair <int, int> ii;

const int Maxn = 100005;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int m, n;
int a[Maxn];
int S;

int Inv(int a)
{
	int res = 1, p = m - 2;
	while (p) {
		if (p & 1) res = ll(res) * a % m;
		p >>= 1; a = ll(a) * a % m;
	}
	return res;
}

int main()
{
	scanf("%d %d", &m, &n);
	if (n == m) { printf("0 1\n"); return 0; }
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
		S = (S + a[i]) % m;
	}
	if (n == 1) { printf("%d 0\n", a[0]); return 0; }
	int invn = Inv(n), invn1 = Inv(n - 1);
	int C = 2ll * ll(S) % m * invn % m * invn1 % m;
	int D = 2ll * invn1 % m;
	shuffle(a, a + n, rng);
	vector <ii> V;
	for (int i = 0; i < n; i++) {
		int d = (C - ll(a[i]) * D % m + m) % m;
		if (d) V.push_back(ii(Inv(d), a[i]));
	}
	shuffle(V.begin(), V.end(), rng);
	int pnt = 0;
	for (int i = 0; i < V.size(); i++) {
        bool ok = true;
        for (int j = 0; j < n; j++) {
            int tp = (a[pnt] - V[i].second + m) % m;
            ok = ll(tp) * V[i].first % m < n;
            if (!ok) break;
            else pnt = (pnt + 1) % n;
        }
        if (ok) { printf("%d %d\n", V[i].second, Inv(V[i].first)); return 0; }
	}
	printf("-1\n");
    return 0;
}


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

typedef long long ll;
typedef pair <int, int> ii;

const int Maxn = 100005;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int m, n;
int a[Maxn];
int S;

int Inv(int a)
{
	int res = 1, p = m - 2;
	while (p) {
		if (p & 1) res = ll(res) * a % m;
		p >>= 1; a = ll(a) * a % m;
	}
	return res;
}

int main()
{
	scanf("%d %d", &m, &n);
	if (n == m) { printf("0 1\n"); return 0; }
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
		S = (S + a[i]) % m;
	}
	if (n == 1) { printf("%d 0\n", a[0]); return 0; }
	int invn = Inv(n), invn1 = Inv(n - 1);
	int C = 2ll * ll(S) % m * invn % m * invn1 % m;
	int D = 2ll * invn1 % m;
	shuffle(a, a + n, rng);
	vector <ii> V;
	for (int i = 0; i < n; i++) {
		int d = (C - ll(a[i]) * D % m + m) % m;
		if (d) V.push_back(ii(Inv(d), a[i]));
	}
	shuffle(V.begin(), V.end(), rng);
	for (int i = 0; i < V.size(); i++) {
        if (i % 10000 == 9999) shuffle(a, a + n, rng);
        bool ok = true;
        for (int j = 0; j < n; j++) {
            int tp = (a[j] - V[i].second + m) % m;
            ok = ll(tp) * V[i].first % m < n;
            if (!ok) break;
        }
        if (ok) { printf("%d %d\n", V[i].second, Inv(V[i].first)); return 0; }
	}
	printf("-1\n");
    return 0;
}


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

typedef long long ll;
typedef pair <int, int> ii;

const int Maxn = 100005;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int m, n;
int a[Maxn];
int S;

int Inv(int a)
{
	int res = 1, p = m - 2;
	while (p) {
		if (p & 1) res = ll(res) * a % m;
		p >>= 1; a = ll(a) * a % m;
	}
	return res;
}

int main()
{
	scanf("%d %d", &m, &n);
	if (n == m) { printf("0 1\n"); return 0; }
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
		S = (S + a[i]) % m;
	}
	if (n == 1) { printf("%d 0\n", a[0]); return 0; }
	int invn = Inv(n), invn1 = Inv(n - 1);
	int C = 2ll * ll(S) % m * invn % m * invn1 % m;
	int D = 2ll * invn1 % m;
	shuffle(a, a + n, rng);
	vector <ii> V;
	for (int i = 0; i < n; i++) {
		int d = (C - ll(a[i]) * D % m + m) % m;
		V.push_back(ii(Inv(d), a[i]));
	}
	shuffle(V.begin(), V.end(), rng);
	for (int i = 0; i < V.size(); i++) {
        bool ok = true;
        for (int j = 0; j < n; j++) {
            int tp = (a[j] - V[i].second + m) % m;
            ok = ll(tp) * V[i].first % m < n;
            if (!ok) break;
        }
        if (ok) { printf("%d %d\n", V[i].second, Inv(V[i].first)); return 0; }
	}
	printf("-1\n");
    return 0;
}


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

typedef long long ll;

const int Maxn = 100005;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int m, n;
int a[Maxn];
int S;
map <int, int> M;

int Inv(int a)
{
	int res = 1, p = m - 2;
	while (p) {
		if (p & 1) res = ll(res) * a % m;
		p >>= 1; a = ll(a) * a % m;
	}
	return res;
}

int main()
{
	scanf("%d %d", &m, &n);
	if (n == m) { printf("0 1\n"); return 0; }
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
		S = (S + a[i]) % m;
	}
	if (n == 1) { printf("%d 0\n", a[0]); return 0; }
	int invn = Inv(n), invn1 = Inv(n - 1);
	int C = 2ll * ll(S) % m * invn % m * invn1 % m;
	int D = 2ll * invn1 % m;
	shuffle(a, a + n, rng);
	for (int i = 0; i < n; i++) {
		int d = (C - ll(a[i]) * D % m + m) % m;
		if (d != 0) M[Inv(d)] = a[i];
	}
	for (int i = 0; i < n; i++)
		for (map <int, int>::iterator it = M.begin(); it != M.end(); ) {
			int tp = (a[i] - it->second + m) % m;
			if (ll(tp) * it->first % m >= n) M.erase(it++);
			else it++;
		}
	if (M.empty()) printf("-1\n");
	else {
		map <int, int>::iterator it = M.begin();
		printf("%d %d\n", it->second, Inv(it->first));
	}
    return 0;
}


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

typedef long long ll;
typedef pair <int, int> ii;

const int Maxn = 100005;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int m, n;
int a[Maxn];
int S;

int Inv(int a)
{
	int res = 1, p = m - 2;
	while (p) {
		if (p & 1) res = ll(res) * a % m;
		p >>= 1; a = ll(a) * a % m;
	}
	return res;
}

int main()
{
	scanf("%d %d", &m, &n);
	if (n == m) { printf("0 1\n"); return 0; }
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
		S = (S + a[i]) % m;
	}
	if (n == 1) { printf("%d 0\n", a[0]); return 0; }
	int invn = Inv(n), invn1 = Inv(n - 1);
	int C = 2ll * ll(S) % m * invn % m * invn1 % m;
	int D = 2ll * invn1 % m;
	shuffle(a, a + n, rng);
	vector <ii> V;
	for (int i = 0; i < n; i++) {
		int d = (C - ll(a[i]) * D % m + m) % m;
		if (d) V.push_back(ii(Inv(d), a[i]));
	}
	shuffle(V.begin(), V.end(), rng);
	for (int i = 0; i < V.size(); i++) {
        if (i % 5000 == 4999) shuffle(a, a + n, rng);
        bool ok = true;
        for (int j = 0; j < n; j++) {
            int tp = (a[j] - V[i].second + m) % m;
            ok = ll(tp) * V[i].first % m < n;
            if (!ok) break;
        }
        if (ok) { printf("%d %d\n", V[i].second, Inv(V[i].first)); return 0; }
	}
	printf("-1\n");
    return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll x, ll n) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x%mod;
		x = x * x%mod; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

int m, n;
vector<int> a;
bool yaru(int s, int d) {
	int ri = 0;
	int cur = s;
	while (ri + 1 < n) {
		cur += d; if (cur >= m)cur -= m;
		int id = lower_bound(all(a), cur) - a.begin();
		if (id < a.size() && a[id] == cur) {
			ri++;
		}
		else break;
	}
	if (ri + 1 == n) {
		cout << s << " " << d << "\n"; return true;
	}
	int le = 0;
	cur = s;
	while (le + 1 + ri < n) {
		cur -= d; if (cur < 0)cur += m;
		int id = lower_bound(all(a), cur) - a.begin();
		if (id < a.size() && a[id] == cur) {
			le++;
		}
		else break;
	}
	if (le + 1 + ri == n) {
		cout << cur << " " << d << "\n"; return true;
	}
	return false;
}
void solve() {
	cin >> m >> n;

	a.resize(n);
	rep(i, n)cin >> a[i];

	mt19937 mt(time(0));
	uniform_int_distribution<> ud(0, n - 1);
	sort(all(a));
	if (n == 1) {
		cout << a[0] << " " << 0 << "\n"; return;
	}

	const int tim = 300;

	map<int, bool> pre;
	rep(i, tim) {
		int id = ud(mt);
		vector<int> ds;
		rep(j, n)if (j != id) {
			int dif = a[j] - a[id]; if (dif < 0)dif += m;
			if (dif > m - dif)dif = m - dif;
			ds.push_back(dif);
		}
		if (i == 0)for (int d : ds)pre[d] = true;
		else {
			map<int, bool> nex;
			for (int d : ds)if (pre[d])nex[d] = true;
			swap(pre, nex);
		}
	}
	for (pair<int, bool> p : pre) {
		int d = p.first;
		if (yaru(a[0], d)) {
			return;
		}
	}
	cout << -1 << "\n";

}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//int t; cin >> t; rep(i, t)
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll x, ll n) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x%mod;
		x = x * x%mod; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

int m, n;
vector<int> a;
bool yaru(int s, int d) {
	int ri = 0;
	int cur = s;
	while (ri + 1 < n) {
		cur += d; if (cur >= m)cur -= m;
		int id = lower_bound(all(a), cur) - a.begin();
		if (id < a.size() && a[id] == cur) {
			ri++;
		}
		else break;
	}
	if (ri + 1 == n) {
		cout << s << " " << d << "\n"; return true;
	}
	int le = 0;
	cur = s;
	while (le + 1 + ri < n) {
		cur -= d; if (cur < 0)cur += m;
		int id = lower_bound(all(a), cur) - a.begin();
		if (id < a.size() && a[id] == cur) {
			le++;
		}
		else break;
	}
	if (le + 1 + ri == n) {
		cout << cur << " " << d << "\n"; return true;
	}
	return false;
}
void solve() {
	cin >> m >> n;

	a.resize(n);
	rep(i, n)cin >> a[i];

	mt19937 mt(time(0));
	uniform_int_distribution<> ud(0, n - 1);
	sort(all(a));
	if (n == 1) {
		cout << a[0] << " " << 0 << "\n"; return;
	}

	const int tim = 300;

	unordered_map<int, bool> pre;
	rep(i, tim) {
		int id = ud(mt);
		vector<int> ds;
		rep(j, n)if (j != id) {
			int dif = a[j] - a[id]; if (dif < 0)dif += m;
			if (dif > m - dif)dif = m - dif;
			ds.push_back(dif);
		}
		if (i == 0)for (int d : ds)pre[d] = true;
		else {
			unordered_map<int, bool> nex;
			for (int d : ds)if (pre[d])nex[d] = true;
			swap(pre, nex);
		}
	}
	for (pair<int, bool> p : pre) {
		int d = p.first;
		if (yaru(a[0], d)) {
			return;
		}
	}
	cout << -1 << "\n";

}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//int t; cin >> t; rep(i, t)
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll x, ll n,ll m) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x%m;
		x = x * x%m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

P calc(int m, int n, vector<int> a) {
	if (n == 1)return { a[0],1 };
	if (n == 0)return { 0,1 };
	if (m < 2 * n) {
		vector<bool> exi(m, false);
		rep(i, n) {
			exi[a[i]] = true;
		}
		vector<int> b;
		rep(i, n)if (!exi[i])b.push_back(i);
		P r = calc(m, b.size(), b);
		return { (r.first + (ll)b.size()*r.second) % m,r.second };
	}
	int d = a[1] - a[0]; if (d < 0)d += m;
	int num = 0;
	map<int, bool> mp;
	rep(i, n)mp[a[i]] = true;
	rep(i, n) {
		if (mp[(a[i] + d) % m])num++;
	}
	int ad = (ll)d*mod_pow(n-num,m - 2, m)%m;
	int s = 0;
	rep(i, n) {
		int c = a[i] - ad; if (c < 0)c += m;
		if (!mp[c]) {
			s = a[i];
		}
	}
	return { s,ad };
}

void solve() {
	int m, n; cin >> m >> n;
	vector<int> a(n); rep(i, n)cin >> a[i];
	P p = calc(m, n, a);
	int ad = p.second;
	int s = p.first;

	map<int, bool> mp;
	rep(i, n) {
		mp[a[i]] = true;
	}

	int cur = s;
	bool valid = true;
	rep(i, n) {
		if (!mp[cur])valid = false;
		cur += ad;
		if (cur >= m)cur -= m;
	}
	if (valid)cout << s << " " << ad << "\n";
	else cout << -1 << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//init();
	//int t; cin >> t; rep(i, t)
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll x, ll n) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x%mod;
		x = x * x%mod; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

void solve() {
	int m, n; cin >> m >> n;

	vector<int> a(n);
	rep(i, n)cin >> a[i];
	sort(all(a));
	if (n == 1) {
		cout << a[0] << " " << 0 << "\n"; return;
	}

	unordered_map<int, bool> mp;
	rep(i, n)mp[a[i]] = true;

	mt19937 mt(time(0));
	uniform_int_distribution<> ud(0, n - 1);
	int s = ud(mt);
	map<int, bool> used;
	rep(i, n) {
		if (i == s)continue;
		//cout << "hello " << i << "\n";
		int d = a[i] - a[s]; if (d < 0)d += m;
		if (used[m - d])continue;
		used[d] = true;

		int ri = 0;
		int cur = a[i];
		while (ri + 2<n) {
			cur += d; if (cur >= m)cur -= m;
			if (mp[cur])ri++;
			else break;
		}
		if (ri + 2 == n) {
			cout << a[s] << " " << d << "\n"; return;
		}
		int le = 0;
		cur = a[s];
		while (le + 2 + ri < n) {
			cur -= d; if (cur < 0)cur += m;
			if (mp[cur])le++;
			else break;
		}
		if (le + 2 + ri == n) {
			cout << cur << " " << d << "\n"; return;
		}
	}
	cout << -1 << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//int t; cin >> t; rep(i, t)
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll x, ll n) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x%mod;
		x = x * x%mod; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

int m,n;
vector<int> a;
bool yaru(int s, int d) {
	int ri = 0;
	int cur = s;
	while (ri + 1 < n) {
		cur += d; if (cur >= m)cur -= m;
		int id = lower_bound(all(a), cur) - a.begin();
		if (id < a.size() && a[id] == cur) {
			ri++;
		}
		else break;
	}
	if (ri + 1 == n) {
		cout << s << " " << d << "\n"; return true;
	}
	int le = 0;
	cur = s;
	while (le + 1 + ri < n) {
		cur -= d; if (cur < 0)cur += m;
		int id = lower_bound(all(a), cur) - a.begin();
		if (id < a.size() && a[id] == cur) {
			le++;
		}
		else break;
	}
	if (le +1 + ri == n) {
		cout << cur << " " << d << "\n"; return true;
	}
	return false;
}
void solve() {
	cin >> m >> n;

	a.resize(n);
	rep(i, n)cin >> a[i];

	mt19937 mt(time(0));
	uniform_int_distribution<> ud(0, n - 1);
	sort(all(a));
	if (n == 1) {
		cout << a[0] << " " << 0 << "\n"; return;
	}

	const int tim = 1000000;
	map<int, int> cnt;
	rep(i, tim) {
		int le = ud(mt);
		int ri = ud(mt);
		while (le == ri)ri = ud(mt);
		int dif = a[ri] - a[le];
		if (dif < 0) {
			dif += m;
		}
		cnt[dif]++;
	}

	vector<P> vp;
	for (P p : cnt)vp.push_back({ p.second,p.first });
	sort(all(vp), greater<P>());
	const int trycnt = 400;
	rep(i, trycnt) {
		if (i == vp.size())break;
		if (yaru(a[0], vp[i].second))return;
	}
	cout << -1 << "\n";

}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//int t; cin >> t; rep(i, t)
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll x, ll n,ll m) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x%m;
		x = x * x%m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

P calc(int m, int n, vector<int> a) {
	if (n == 1)return { a[0],1 };
	if (n == 0)return { 0,1 };
	if (m < 2 * n) {
		vector<bool> exi(m, false);
		rep(i, n) {
			exi[a[i]] = true;
		}
		vector<int> b;
		rep(i, m)if (!exi[i])b.push_back(i);
		P r = calc(m, b.size(), b);
		return { (r.first + (ll)b.size()*r.second) % m,r.second };
	}
	int d = a[1] - a[0]; if (d < 0)d += m;
	int num = 0;
	map<int, bool> mp;
	rep(i, n)mp[a[i]] = true;
	rep(i, n) {
		if (mp[(a[i] + d) % m])num++;
	}
	int ad = (ll)d*mod_pow(n-num,m - 2, m)%m;
	int s = 0;
	rep(i, n) {
		int c = a[i] - ad; if (c < 0)c += m;
		if (!mp[c]) {
			s = a[i];
		}
	}
	return { s,ad };
}

void solve() {
	int m, n; cin >> m >> n;
	vector<int> a(n); rep(i, n)cin >> a[i];
	P p = calc(m, n, a);
	int ad = p.second;
	int s = p.first;

	map<int, bool> mp;
	rep(i, n) {
		mp[a[i]] = true;
	}

	int cur = s;
	bool valid = true;
	rep(i, n) {
		if (!mp[cur])valid = false;
		cur += ad;
		if (cur >= m)cur -= m;
	}
	if (valid)cout << s << " " << ad << "\n";
	else cout << -1 << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//init();
	//int t; cin >> t; rep(i, t)
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll x, ll n) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x%mod;
		x = x * x%mod; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

void solve() {
	int m, n; cin >> m >> n;

	vector<int> a(n);
	rep(i, n)cin >> a[i];
	sort(all(a));
	if (n == 1) {
		cout << a[0] << " " << 0 << "\n"; return;
	}
	int s = a[0];
	rep1(i, n - 1) {
		//cout << "hello " << i << "\n";
		int d = a[i] -s;

		int ri = 0;
		int cur = a[i];
		while (ri+2<n) {
			cur += d; if (cur >= m)cur -= m;
			int id = lower_bound(all(a), cur) - a.begin();
			if (id < a.size() && a[id] == cur) {
				ri++;
			}
			else break;
		}
		if (ri + 2 == n) {
			cout << s << " " << d << "\n"; return;
		}
		int le = 0;
		cur = s;
		while (le + 2 + ri < n) {
			cur -= d; if (cur < 0)cur += m;
			int id = lower_bound(all(a), cur) - a.begin();
			if (id < a.size() && a[id] == cur) {
				le++;
			}
			else break;
		}
		if (le + 2 + ri == n) {
			cout << cur << " " << d << "\n"; return;
		}
	}
	cout << -1 << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//int t; cin >> t; rep(i, t)
	solve();
	stop
		return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <iomanip>
#include <set>
#include <map>
#include <queue>
#include <bitset>
#include <random>
#include <chrono>
#include <stack>
typedef long long ll;
typedef long double ld;
using namespace std;

ll pwr(ll a, ll b, ll m)
{
	if (!b) return 1;
	ll h = pwr(a, (b >> 1), m);
	h = (h * h) % m;
	if (b & 1) h = (h * a) % m;
	return h;
}
ll inv(ll a, ll m)
{
	return pwr(a, m - 2, m);
}
pair<ll, ll> solve(ll m, ll n, vector<ll>& a) // predpokladame ze 2*n < m - inac sa nam narusi pocet rozdielov
{
	if (a.size() == 1) return { a[0], 1 };
	set<ll> s;
	for (ll i : a) s.insert(i);
	ll dif = (m + a[0] - a[1]) % m, cnt = 0;
	for (int i = 0; i < n; i++)
		if (s.count((a[i] + dif) % m))cnt++;
	ll k = n - cnt;
	ll d = (dif * inv(k, m)) % m;
	// uz vieme diferenciu, teraz uz len skusime najst prvy prvok
	ll c = 1, x = -1;
	for (ll d2 = (m - d); c < n && s.count((a[0] + d2) % m); d2 = (d2 + m - d) % m, c++)
		x = (a[0] + d2) % m;
	for (ll d2 = d; c < n && s.count((a[0] + d2) % m); d2 = (d2 + d) % m, c++);
	if (c == n) return { x, d };
	return { -1, -1 };
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	ll m, n;
	cin >> m >> n;
	vector<ll> a(n);
	for (ll &i : a)cin >> i;
	if (n == m)
	{
		cout << "0 1\n";
		return 0;
	}
	pair<ll, ll> ans;
	if (2 * n < m)
	{
		ans = solve(m, n, a);
	}
	else
	{
		vector<ll> f(m, 0); // v tomto pripade je m maximalne 10^5, toto si mozeme dovolit
		for (ll i : a) f[i]++;
		vector<ll> c;
		for (int i = 0; i < m; i++)
			if (!f[i]) c.push_back(i);
		ans = solve(m, m - n, c);
		if (ans.first != -1) ans.first = (ans.first + (((m - n) * ans.second) % m)) % m;
	}
	if (ans.first == -1) cout << "-1\n";
	else cout << ans.first << " " << ans.second << "\n";
	return 0;
}


#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for(ll i = a; i <= b; ++i)
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define rep3(i, a, b) for(ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                \
    vector<type> name(size);                                                                                \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                \
    vector<vector<type>> name(h, vector<type>(w));                                                                                \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define ios ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define Size(c) (int)(c).size()
#define INT(...)                                                                                \
    int __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LL(...)                                                                                \
    ll __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define ULL(...)                                                                                \
    ull __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define STR(...)                                                                                \
    string __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                \
    char __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                \
    double __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LD(...)                                                                                \
    ld __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
template <class T> void scan(T a) { cin >> a; }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T> void scan(vector<T> &);
template <class T, size_t size> void scan(array<T, size> &);
template <class T, class L> void scan(pair<T, L> &);
template <class T, size_t size> void scan(T (&)[size]);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(deque<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T, size_t size> void scan(array<T, size> &a) {
    for(auto &i : a) scan(i);
}
template <class T, class L> void scan(pair<T, L> &p) {
    scan(p.first);
    scan(p.second);
}
template <class T, size_t size> void scan(T (&a)[size]) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &... tail) {
    scan(head);
    IN(tail...);
}
string stin() {
    string s;
    cin >> s;
    return s;
}
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
vi iota(int n) {
    vi a(n);
    iota(all(a), 0);
    return a;
}
template <class T> void UNIQUE(vector<T> &x) {
    sort(all(x));
    x.erase(unique(all(x)), x.end());
}
int in() {
    int x;
    cin >> x;
    return x;
}
ll lin() {
    unsigned long long x;
    cin >> x;
    return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T> void print(const vector<T> &);
template <class T, size_t size> void print(const array<T, size> &);
template <class T, class L> void print(const pair<T, L> &p);
template <class T, size_t size> void print(const T (&)[size]);
template <class T> void print(const vector<T> &a) {
    if(a.empty()) return;
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
    cout << endl;
}
template <class T> void print(const deque<T> &a) {
    if(a.empty()) return;
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
}
template <class T, size_t size> void print(const array<T, size> &a) {
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
}
template <class T, class L> void print(const pair<T, L> &p) {
    cout << '(';
    print(p.first);
    cout << ",";
    print(p.second);
    cout << ')';
}
template <class T> void print(set<T> &x) {
    for(auto e : x) print(e), cout << " ";
    cout << endl;
}
template <class T> void print(multiset<T> &x) {
    for(auto e : x) print(e), cout << " ";
    cout << endl;
}
template <class T, size_t size> void print(const T (&a)[size]) {
    print(a[0]);
    for(auto i = a; ++i != end(a);) {
        cout << " ";
        print(*i);
    }
}
template <class T> void print(const T &a) { cout << a; }
int out() {
    putchar('\n');
    return 0;
}
template <class T> int out(const T &t) {
    print(t);
    putchar('\n');
    return 0;
}
template <class Head, class... Tail> int out(const Head &head, const Tail &... tail) {
    print(head);
    putchar(' ');
    out(tail...);
    return 0;
}
ll gcd(ll a, ll b) {
    while(b) {
        ll c = b;
        b = a % b;
        a = c;
    }
    return a;
}
ll lcm(ll a, ll b) {
    if(!a || !b) return 0;
    return a * b / gcd(a, b);
}
vector<pll> factor(ll x) {
    vector<pll> ans;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0) {
            ans.push_back({i, 1});
            while((x /= i) % i == 0) ans.back().second++;
        }
    if(x != 1) ans.push_back({x, 1});
    return ans;
}
vector<int> divisor(int x) {
    vector<int> ans;
    for(int i = 1; i * i <= x; i++)
        if(x % i == 0) {
            ans.pb(i);
            if(i * i != x) ans.pb(x / i);
        }
    return ans;
}
template <typename T> void zip(vector<T> &x) {
    vector<T> y = x;
    sort(all(y));
    for(int i = 0; i < x.size(); ++i) { x[i] = lb(y, x[i]); }
}
int popcount(ll x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n - 1)(rng); }
template <typename T> void shuffle(vector<T> &v) {
    rep3(i, v.size() - 1, 1) { swap(v[i], v[rnd(i)]); }
}
#define endl '\n'
vector<string> YES{"NO", "YES"};
vector<string> Yes{"No", "Yes"};
vector<string> yes{"no", "yes"};

#ifdef _LOCAL
#undef endl
#define debug(x)                                                                                \
    cout << #x << ": ";                                                                                \
    print(x);                                                                                \
    cout << endl;
void err() {}
template <class T> void err(const T &t) {
    print(t);
    cout << " ";
}
template <class Head, class... Tail> void err(const Head &head, const Tail &... tail) {
    print(head);
    putchar(' ');
    out(tail...);
}
#else
#define debug(x)
template <class... T> void err(const T &...) {}
#endif

template <typename T> struct edge {
    int from, to;
    T cost;
    int id;
    edge(int to, T cost) : from(-1), to(to), cost(cost) {}
    edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
    // edge(int from,int to,T cost,int id):from(from),to(to),cost(cost),id(id){}
    edge &operator=(const int &x) {
        to = x;
        return *this;
    }
    operator int() const { return to; }
};

template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedTree = vector<Edges<T>>;
template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedGraph = vector<Edges<T>>;
template <typename T> using Matrix = vector<vector<T>>;
using Graph = vector<vector<int>>;
using tree = vector<vector<int>>;

tree getTree(int n, int offset = 1) {
    tree res(n);
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        res[a].emplace_back(b);
        res[b].emplace_back(a);
    }
    return res;
}
template <typename T> WeightedTree<T> getWeightedTree(int n, int offset = 1) {
    WeightedTree<T> res(n);
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        T c;
        cin >> c;
        res[a].emplace_back(b, c);
        res[b].emplace_back(a, c);
    }
    return res;
}

Graph getGraph(int n, int m, int offset = 1) {
    Graph res(n);
    for(int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        res[a].emplace_back(b);
        res[b].emplace_back(a);
    }
    return res;
}

template <typename T> WeightedGraph<T> getWeightedGraph(int n, int m, int offset = 1) {
    WeightedGraph<T> res(n);
    for(int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        T c;
        cin >> c;
        res[a].emplace_back(b, c);
        res[b].emplace_back(a, c);
    }
}
struct Setup_io {
    Setup_io() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cout << fixed << setprecision(15);
    }
} setup_io;
#pragma endregion

// _________コーディングはここから！！___________
// ... 最小側の制約も確認した？
// ... オーバーフローしない？

namespace modular {
ll MOD = 1;

const int MAXN = 1100000;
class modint {
    using u64 = ll;
    ll Modulus;

  public:
    u64 a;

    modint(const u64 x = 0) noexcept : Modulus(MOD), a(((x % MOD) + MOD) % MOD) {}
    u64 &value() noexcept { return a; }
    modint operator+(const modint rhs) const noexcept { return modint(*this) += rhs; }
    modint operator-(const modint rhs) const noexcept { return modint(*this) -= rhs; }
    modint operator*(const modint rhs) const noexcept { return modint(*this) *= rhs; }
    template <typename T> modint operator^(T rhs) const noexcept { return modint(*this) ^= rhs; }
    modint &operator+=(const modint rhs) noexcept {
        a += rhs.a;
        if(a >= Modulus) { a -= Modulus; }
        return *this;
    }
    modint &operator-=(const modint rhs) noexcept {
        if(a < rhs.a) { a += Modulus; }
        a -= rhs.a;
        return *this;
    }
    modint &operator*=(const modint rhs) noexcept {
        a = a * rhs.a % Modulus;
        return *this;
    }
    bool operator==(const modint rhs) const noexcept { return a == rhs.a; }
    bool operator<(const modint rhs) const noexcept { return a < rhs.a; }
    template <typename T> modint &operator^=(T n) noexcept {
        modint res = 1;
        modint x = a;
        while(n) {
            if(n & 1) res *= x;
            x *= x;
            n >>= 1;
        }
        a = res.a;
        return *this;
    }
};
#define mint modint
#define vmint vector<mint>
vmint Inv, Prd, Invprd;
void setmod(ll x) {
    MOD = x;
    Inv = {0, 1}, Prd = Invprd = {1, 1};
}
mint inv(int n) {
    if(Inv.size() > n)
        return Inv[n];
    else {
        for(int i = Inv.size(); i <= n; ++i) Inv.emplace_back(Inv[MOD % i] * (-MOD / i));
        return Inv[n];
    }
}
mint prd(int n) {
    if(Prd.size() > n)
        return Prd[n];
    else
        for(int i = Prd.size(); i <= n; ++i) Prd.emplace_back(Prd[i - 1] * i);
    return Prd[n];
}
mint invprd(int n) {
    if(Invprd.size() > n)
        return Invprd[n];
    else
        for(int i = Invprd.size(); i <= n; ++i) Invprd.emplace_back(Invprd[i - 1] * inv(i));
    return Invprd[n];
}
mint modpow(ll a, ll n) {
    mint x = a;
    return x ^= n;
}
modint operator/(modint l, modint r) {
    if(r.a < MAXN) return l * inv(r.a);
    return l * (r ^ (MOD - 2));
}
modint operator/=(modint &l, modint r) { return l = l / r; }
mint cmb(int a, int b) {
    if(a < b) return 0;
    if(a < 0 || b < 0) return 0;
    return prd(a) * invprd(b) * invprd(a - b);
}
ostream &operator<<(ostream &os, mint a) {
    os << a.a;
    return os;
}
istream &operator>>(istream &is, mint &a) {
    ll x;
    is >> x;
    a = x;
    return is;
}
} // namespace modular

using namespace modular;

main() {
    INT(m, n);
    setmod(m);
    vmint a(n);
    rep(i, n) cin >> a[i];
    if(n == m) {
        cout << "0 1\n";
        return 0;
    }
    if(n == 1 or m == 2) {
        cout << a[0] << " 0\n";
        return 0;
    }
    mint t, s;
    rep(i, n) {
        t += a[i];
        s += a[i] * a[i];
    }
    mint N = n;
    mint aa = N * (N - 1) / (mint)2;
    mint b = N * (N - 1);
    mint c = N * (N - 1) * (N * 2 - 1) / (mint(6));
    // n x + aa d = t
    // n x^2 + b dx + c d^2 = s
    mint d, x;
    set<mint> se;
    rep(i, n) se.emplace(a[i]);
    rep(i, n) {
        d = a[i];
        x = (t - aa * d) / N;
        if(N * x * x + b * d * x + c * d * d == s) {
            int cnt = 0;
            mint now = x;
            while(cnt < n and se.count(now)) {
                cnt++;
                now += d;
            }
            if(cnt == n) {
                cout << x << " " << d << endl;
                return 0;
            }
        }
    }
    cout << -1 << endl;
}


#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for(ll i = a; i <= b; ++i)
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define rep3(i, a, b) for(ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                \
    vector<type> name(size);                                                                                \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                \
    vector<vector<type>> name(h, vector<type>(w));                                                                                \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define ios ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define Size(c) (int)(c).size()
#define INT(...)                                                                                \
    int __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LL(...)                                                                                \
    ll __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define ULL(...)                                                                                \
    ull __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define STR(...)                                                                                \
    string __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                \
    char __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                \
    double __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LD(...)                                                                                \
    ld __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
template <class T> void scan(T a) { cin >> a; }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T> void scan(vector<T> &);
template <class T, size_t size> void scan(array<T, size> &);
template <class T, class L> void scan(pair<T, L> &);
template <class T, size_t size> void scan(T (&)[size]);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(deque<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T, size_t size> void scan(array<T, size> &a) {
    for(auto &i : a) scan(i);
}
template <class T, class L> void scan(pair<T, L> &p) {
    scan(p.first);
    scan(p.second);
}
template <class T, size_t size> void scan(T (&a)[size]) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &... tail) {
    scan(head);
    IN(tail...);
}
string stin() {
    string s;
    cin >> s;
    return s;
}
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
vi iota(int n) {
    vi a(n);
    iota(all(a), 0);
    return a;
}
template <class T> void UNIQUE(vector<T> &x) {
    sort(all(x));
    x.erase(unique(all(x)), x.end());
}
int in() {
    int x;
    cin >> x;
    return x;
}
ll lin() {
    unsigned long long x;
    cin >> x;
    return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T> void print(const vector<T> &);
template <class T, size_t size> void print(const array<T, size> &);
template <class T, class L> void print(const pair<T, L> &p);
template <class T, size_t size> void print(const T (&)[size]);
template <class T> void print(const vector<T> &a) {
    if(a.empty()) return;
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
    cout << endl;
}
template <class T> void print(const deque<T> &a) {
    if(a.empty()) return;
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
}
template <class T, size_t size> void print(const array<T, size> &a) {
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
}
template <class T, class L> void print(const pair<T, L> &p) {
    cout << '(';
    print(p.first);
    cout << ",";
    print(p.second);
    cout << ')';
}
template <class T> void print(set<T> &x) {
    for(auto e : x) print(e), cout << " ";
    cout << endl;
}
template <class T> void print(multiset<T> &x) {
    for(auto e : x) print(e), cout << " ";
    cout << endl;
}
template <class T, size_t size> void print(const T (&a)[size]) {
    print(a[0]);
    for(auto i = a; ++i != end(a);) {
        cout << " ";
        print(*i);
    }
}
template <class T> void print(const T &a) { cout << a; }
int out() {
    putchar('\n');
    return 0;
}
template <class T> int out(const T &t) {
    print(t);
    putchar('\n');
    return 0;
}
template <class Head, class... Tail> int out(const Head &head, const Tail &... tail) {
    print(head);
    putchar(' ');
    out(tail...);
    return 0;
}
ll gcd(ll a, ll b) {
    while(b) {
        ll c = b;
        b = a % b;
        a = c;
    }
    return a;
}
ll lcm(ll a, ll b) {
    if(!a || !b) return 0;
    return a * b / gcd(a, b);
}
vector<pll> factor(ll x) {
    vector<pll> ans;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0) {
            ans.push_back({i, 1});
            while((x /= i) % i == 0) ans.back().second++;
        }
    if(x != 1) ans.push_back({x, 1});
    return ans;
}
vector<int> divisor(int x) {
    vector<int> ans;
    for(int i = 1; i * i <= x; i++)
        if(x % i == 0) {
            ans.pb(i);
            if(i * i != x) ans.pb(x / i);
        }
    return ans;
}
template <typename T> void zip(vector<T> &x) {
    vector<T> y = x;
    sort(all(y));
    for(int i = 0; i < x.size(); ++i) { x[i] = lb(y, x[i]); }
}
int popcount(ll x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n - 1)(rng); }
template <typename T> void shuffle(vector<T> &v) {
    rep3(i, v.size() - 1, 1) { swap(v[i], v[rnd(i)]); }
}
#define endl '\n'
vector<string> YES{"NO", "YES"};
vector<string> Yes{"No", "Yes"};
vector<string> yes{"no", "yes"};

#ifdef _LOCAL
#undef endl
#define debug(x)                                                                                \
    cout << #x << ": ";                                                                                \
    print(x);                                                                                \
    cout << endl;
void err() {}
template <class T> void err(const T &t) {
    print(t);
    cout << " ";
}
template <class Head, class... Tail> void err(const Head &head, const Tail &... tail) {
    print(head);
    putchar(' ');
    out(tail...);
}
#else
#define debug(x)
template <class... T> void err(const T &...) {}
#endif

template <typename T> struct edge {
    int from, to;
    T cost;
    int id;
    edge(int to, T cost) : from(-1), to(to), cost(cost) {}
    edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
    // edge(int from,int to,T cost,int id):from(from),to(to),cost(cost),id(id){}
    edge &operator=(const int &x) {
        to = x;
        return *this;
    }
    operator int() const { return to; }
};

template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedTree = vector<Edges<T>>;
template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedGraph = vector<Edges<T>>;
template <typename T> using Matrix = vector<vector<T>>;
using Graph = vector<vector<int>>;
using tree = vector<vector<int>>;

tree getTree(int n, int offset = 1) {
    tree res(n);
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        res[a].emplace_back(b);
        res[b].emplace_back(a);
    }
    return res;
}
template <typename T> WeightedTree<T> getWeightedTree(int n, int offset = 1) {
    WeightedTree<T> res(n);
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        T c;
        cin >> c;
        res[a].emplace_back(b, c);
        res[b].emplace_back(a, c);
    }
    return res;
}

Graph getGraph(int n, int m, int offset = 1) {
    Graph res(n);
    for(int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        res[a].emplace_back(b);
        res[b].emplace_back(a);
    }
    return res;
}

template <typename T> WeightedGraph<T> getWeightedGraph(int n, int m, int offset = 1) {
    WeightedGraph<T> res(n);
    for(int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        T c;
        cin >> c;
        res[a].emplace_back(b, c);
        res[b].emplace_back(a, c);
    }
}
struct Setup_io {
    Setup_io() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cout << fixed << setprecision(15);
    }
} setup_io;
#pragma endregion

// _________コーディングはここから！！___________
// ... 最小側の制約も確認した？
// ... オーバーフローしない？

namespace modular {
ll MOD = 1;

const int MAXN = 1100000;
class modint {
    using u64 = ll;
    ll Modulus;

  public:
    u64 a;

    modint(const u64 x = 0) noexcept : Modulus(MOD), a(((x % MOD) + MOD) % MOD) {}
    u64 &value() noexcept { return a; }
    modint operator+(const modint rhs) const noexcept { return modint(*this) += rhs; }
    modint operator-(const modint rhs) const noexcept { return modint(*this) -= rhs; }
    modint operator*(const modint rhs) const noexcept { return modint(*this) *= rhs; }
    template <typename T> modint operator^(T rhs) const noexcept { return modint(*this) ^= rhs; }
    modint &operator+=(const modint rhs) noexcept {
        a += rhs.a;
        if(a >= Modulus) { a -= Modulus; }
        return *this;
    }
    modint &operator-=(const modint rhs) noexcept {
        if(a < rhs.a) { a += Modulus; }
        a -= rhs.a;
        return *this;
    }
    modint &operator*=(const modint rhs) noexcept {
        a = a * rhs.a % Modulus;
        return *this;
    }
    bool operator==(const modint rhs) const noexcept { return a == rhs.a; }
    bool operator<(const modint rhs) const noexcept { return a < rhs.a; }
    template <typename T> modint &operator^=(T n) noexcept {
        modint res = 1;
        modint x = a;
        while(n) {
            if(n & 1) res *= x;
            x *= x;
            n >>= 1;
        }
        a = res.a;
        return *this;
    }
};
#define mint modint
#define vmint vector<mint>
vmint Inv, Prd, Invprd;
void setmod(ll x) {
    MOD = x;
    Inv = {0, 1}, Prd = Invprd = {1, 1};
}
mint inv(int n) {
    if(Inv.size() > n)
        return Inv[n];
    else {
        for(int i = Inv.size(); i <= n; ++i) Inv.emplace_back(Inv[MOD % i] * (-MOD / i));
        return Inv[n];
    }
}
mint prd(int n) {
    if(Prd.size() > n)
        return Prd[n];
    else
        for(int i = Prd.size(); i <= n; ++i) Prd.emplace_back(Prd[i - 1] * i);
    return Prd[n];
}
mint invprd(int n) {
    if(Invprd.size() > n)
        return Invprd[n];
    else
        for(int i = Invprd.size(); i <= n; ++i) Invprd.emplace_back(Invprd[i - 1] * inv(i));
    return Invprd[n];
}
mint modpow(ll a, ll n) {
    mint x = a;
    return x ^= n;
}
modint operator/(modint l, modint r) {
    if(r.a < MAXN) return l * inv(r.a);
    return l * (r ^ (MOD - 2));
}
modint operator/=(modint &l, modint r) { return l = l / r; }
mint cmb(int a, int b) {
    if(a < b) return 0;
    if(a < 0 || b < 0) return 0;
    return prd(a) * invprd(b) * invprd(a - b);
}
ostream &operator<<(ostream &os, mint a) {
    os << a.a;
    return os;
}
istream &operator>>(istream &is, mint &a) {
    ll x;
    is >> x;
    a = x;
    return is;
}
} // namespace modular

using namespace modular;

main() {
    INT(m, n);
    setmod(m);
    vmint a(n);
    rep(i, n) cin >> a[i];
    if(n == m or m == 2) {
        cout << "0 1\n";
        return 0;
    }
    if(n == 1) {
        cout << a[0] << " 0\n";
        return 0;
    }
    mint t, s;
    rep(i, n) {
        t += a[i];
        s += a[i] * a[i];
    }
    mint N = n;
    mint aa = N * (N - 1) / (mint)2;
    mint b = N * (N - 1);
    mint c = N * (N - 1) * (N * 2 - 1) / (mint(6));
    // n x + aa d = t
    // n x^2 + b dx + c d^2 = s
    mint d, x;
    set<mint> se;
    rep(i, n) se.emplace(a[i]);
    rep(i, n) {
        d = a[i];
        x = (t - aa * d) / N;
        if(N * x * x + b * d * x + c * d * d == s) {
            int cnt = 0;
            mint now = x;
            while(cnt < n and se.count(now)) {
                cnt++;
                now += d;
            }
            if(cnt == n) {
                cout << x << " " << d << endl;
                return 0;
            }
        }
    }
    cout << -1 << endl;
}


#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for(ll i = a; i <= b; ++i)
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define rep3(i, a, b) for(ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                \
    vector<type> name(size);                                                                                \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                \
    vector<vector<type>> name(h, vector<type>(w));                                                                                \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define ios ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define Size(c) (int)(c).size()
#define INT(...)                                                                                \
    int __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LL(...)                                                                                \
    ll __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define ULL(...)                                                                                \
    ull __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define STR(...)                                                                                \
    string __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                \
    char __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                \
    double __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LD(...)                                                                                \
    ld __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
template <class T> void scan(T a) { cin >> a; }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T> void scan(vector<T> &);
template <class T, size_t size> void scan(array<T, size> &);
template <class T, class L> void scan(pair<T, L> &);
template <class T, size_t size> void scan(T (&)[size]);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(deque<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T, size_t size> void scan(array<T, size> &a) {
    for(auto &i : a) scan(i);
}
template <class T, class L> void scan(pair<T, L> &p) {
    scan(p.first);
    scan(p.second);
}
template <class T, size_t size> void scan(T (&a)[size]) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &... tail) {
    scan(head);
    IN(tail...);
}
string stin() {
    string s;
    cin >> s;
    return s;
}
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
vi iota(int n) {
    vi a(n);
    iota(all(a), 0);
    return a;
}
template <class T> void UNIQUE(vector<T> &x) {
    sort(all(x));
    x.erase(unique(all(x)), x.end());
}
int in() {
    int x;
    cin >> x;
    return x;
}
ll lin() {
    unsigned long long x;
    cin >> x;
    return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T> void print(const vector<T> &);
template <class T, size_t size> void print(const array<T, size> &);
template <class T, class L> void print(const pair<T, L> &p);
template <class T, size_t size> void print(const T (&)[size]);
template <class T> void print(const vector<T> &a) {
    if(a.empty()) return;
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
    cout << endl;
}
template <class T> void print(const deque<T> &a) {
    if(a.empty()) return;
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
}
template <class T, size_t size> void print(const array<T, size> &a) {
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
}
template <class T, class L> void print(const pair<T, L> &p) {
    cout << '(';
    print(p.first);
    cout << ",";
    print(p.second);
    cout << ')';
}
template <class T> void print(set<T> &x) {
    for(auto e : x) print(e), cout << " ";
    cout << endl;
}
template <class T> void print(multiset<T> &x) {
    for(auto e : x) print(e), cout << " ";
    cout << endl;
}
template <class T, size_t size> void print(const T (&a)[size]) {
    print(a[0]);
    for(auto i = a; ++i != end(a);) {
        cout << " ";
        print(*i);
    }
}
template <class T> void print(const T &a) { cout << a; }
int out() {
    putchar('\n');
    return 0;
}
template <class T> int out(const T &t) {
    print(t);
    putchar('\n');
    return 0;
}
template <class Head, class... Tail> int out(const Head &head, const Tail &... tail) {
    print(head);
    putchar(' ');
    out(tail...);
    return 0;
}
ll gcd(ll a, ll b) {
    while(b) {
        ll c = b;
        b = a % b;
        a = c;
    }
    return a;
}
ll lcm(ll a, ll b) {
    if(!a || !b) return 0;
    return a * b / gcd(a, b);
}
vector<pll> factor(ll x) {
    vector<pll> ans;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0) {
            ans.push_back({i, 1});
            while((x /= i) % i == 0) ans.back().second++;
        }
    if(x != 1) ans.push_back({x, 1});
    return ans;
}
vector<int> divisor(int x) {
    vector<int> ans;
    for(int i = 1; i * i <= x; i++)
        if(x % i == 0) {
            ans.pb(i);
            if(i * i != x) ans.pb(x / i);
        }
    return ans;
}
template <typename T> void zip(vector<T> &x) {
    vector<T> y = x;
    sort(all(y));
    for(int i = 0; i < x.size(); ++i) { x[i] = lb(y, x[i]); }
}
int popcount(ll x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n - 1)(rng); }
template <typename T> void shuffle(vector<T> &v) {
    rep3(i, v.size() - 1, 1) { swap(v[i], v[rnd(i)]); }
}
#define endl '\n'
vector<string> YES{"NO", "YES"};
vector<string> Yes{"No", "Yes"};
vector<string> yes{"no", "yes"};

#ifdef _LOCAL
#undef endl
#define debug(x)                                                                                \
    cout << #x << ": ";                                                                                \
    print(x);                                                                                \
    cout << endl;
void err() {}
template <class T> void err(const T &t) {
    print(t);
    cout << " ";
}
template <class Head, class... Tail> void err(const Head &head, const Tail &... tail) {
    print(head);
    putchar(' ');
    out(tail...);
}
#else
#define debug(x)
template <class... T> void err(const T &...) {}
#endif

template <typename T> struct edge {
    int from, to;
    T cost;
    int id;
    edge(int to, T cost) : from(-1), to(to), cost(cost) {}
    edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
    // edge(int from,int to,T cost,int id):from(from),to(to),cost(cost),id(id){}
    edge &operator=(const int &x) {
        to = x;
        return *this;
    }
    operator int() const { return to; }
};

template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedTree = vector<Edges<T>>;
template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedGraph = vector<Edges<T>>;
template <typename T> using Matrix = vector<vector<T>>;
using Graph = vector<vector<int>>;
using tree = vector<vector<int>>;

tree getTree(int n, int offset = 1) {
    tree res(n);
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        res[a].emplace_back(b);
        res[b].emplace_back(a);
    }
    return res;
}
template <typename T> WeightedTree<T> getWeightedTree(int n, int offset = 1) {
    WeightedTree<T> res(n);
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        T c;
        cin >> c;
        res[a].emplace_back(b, c);
        res[b].emplace_back(a, c);
    }
    return res;
}

Graph getGraph(int n, int m, int offset = 1) {
    Graph res(n);
    for(int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        res[a].emplace_back(b);
        res[b].emplace_back(a);
    }
    return res;
}

template <typename T> WeightedGraph<T> getWeightedGraph(int n, int m, int offset = 1) {
    WeightedGraph<T> res(n);
    for(int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        T c;
        cin >> c;
        res[a].emplace_back(b, c);
        res[b].emplace_back(a, c);
    }
}
struct Setup_io {
    Setup_io() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cout << fixed << setprecision(15);
    }
} setup_io;
#pragma endregion

// _________コーディングはここから！！___________
// ... 最小側の制約も確認した？
// ... オーバーフローしない？

namespace modular {
ll MOD = 1;

const int MAXN = 1100000;
class modint {
    using u64 = ll;
    ll Modulus;

  public:
    u64 a;

    modint(const u64 x = 0) noexcept : Modulus(MOD), a(((x % MOD) + MOD) % MOD) {}
    u64 &value() noexcept { return a; }
    modint operator+(const modint rhs) const noexcept { return modint(*this) += rhs; }
    modint operator-(const modint rhs) const noexcept { return modint(*this) -= rhs; }
    modint operator*(const modint rhs) const noexcept { return modint(*this) *= rhs; }
    template <typename T> modint operator^(T rhs) const noexcept { return modint(*this) ^= rhs; }
    modint &operator+=(const modint rhs) noexcept {
        a += rhs.a;
        if(a >= Modulus) { a -= Modulus; }
        return *this;
    }
    modint &operator-=(const modint rhs) noexcept {
        if(a < rhs.a) { a += Modulus; }
        a -= rhs.a;
        return *this;
    }
    modint &operator*=(const modint rhs) noexcept {
        a = a * rhs.a % Modulus;
        return *this;
    }
    bool operator==(const modint rhs) const noexcept { return a == rhs.a; }
    bool operator<(const modint rhs) const noexcept { return a < rhs.a; }
    template <typename T> modint &operator^=(T n) noexcept {
        modint res = 1;
        modint x = a;
        while(n) {
            if(n & 1) res *= x;
            x *= x;
            n >>= 1;
        }
        a = res.a;
        return *this;
    }
};
#define mint modint
#define vmint vector<mint>
vmint Inv, Prd, Invprd;
void setmod(ll x) {
    MOD = x;
    Inv = {0, 1}, Prd = Invprd = {1, 1};
}
mint inv(int n) {
    if(Inv.size() > n)
        return Inv[n];
    else {
        for(int i = Inv.size(); i <= n; ++i) Inv.emplace_back(Inv[MOD % i] * (-MOD / i));
        return Inv[n];
    }
}
mint prd(int n) {
    if(Prd.size() > n)
        return Prd[n];
    else
        for(int i = Prd.size(); i <= n; ++i) Prd.emplace_back(Prd[i - 1] * i);
    return Prd[n];
}
mint invprd(int n) {
    if(Invprd.size() > n)
        return Invprd[n];
    else
        for(int i = Invprd.size(); i <= n; ++i) Invprd.emplace_back(Invprd[i - 1] * inv(i));
    return Invprd[n];
}
mint modpow(ll a, ll n) {
    mint x = a;
    return x ^= n;
}
modint operator/(modint l, modint r) {
    if(r.a < MAXN) return l * inv(r.a);
    return l * (r ^ (MOD - 2));
}
modint operator/=(modint &l, modint r) { return l = l / r; }
mint cmb(int a, int b) {
    if(a < b) return 0;
    if(a < 0 || b < 0) return 0;
    return prd(a) * invprd(b) * invprd(a - b);
}
ostream &operator<<(ostream &os, mint a) {
    os << a.a;
    return os;
}
istream &operator>>(istream &is, mint &a) {
    ll x;
    is >> x;
    a = x;
    return is;
}
} // namespace modular

using namespace modular;

main() {
    INT(m);LL(n);
    setmod(m);
    vmint a(n);
    rep(i, n) cin >> a[i];
    if(n == m) {
        cout << "0 1\n";
        return 0;
    }
    if(n == 1 or m == 2) {
        cout << a[0] << " 0\n";
        return 0;
    }
    mint t, s;
    rep(i, n) {
        t += a[i];
        s += a[i] * a[i];
    }
    mint N = n;
    mint aa = (n * (n-1) / 2);
    mint b = n * (n-1);
    mint c = (ll)n * (n-1) * (n * 2 - 1) / 6;
    // n x + aa d = t
    // n x^2 + b dx + c d^2 = s
    mint d, x;
    set<mint> se;
    rep(i, n) se.emplace(a[i]);
    rep(i, n) {
        d = a[i];
        x = (t - aa * d) / N;
        if(N * x * x + b * d * x + c * d * d == s) {
            int cnt = 0;
            mint now = x;
            while(cnt < n and se.count(now)) {
                cnt++;
                now += d;
            }
            if(cnt == n) {
                cout << x << " " << d << endl;
                return 0;
            }
        }
    }
    cout << -1 << endl;
}


#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for(ll i = a; i <= b; ++i)
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define rep3(i, a, b) for(ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                \
    vector<type> name(size);                                                                                \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                \
    vector<vector<type>> name(h, vector<type>(w));                                                                                \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define ios ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define Size(c) (int)(c).size()
#define INT(...)                                                                                \
    int __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LL(...)                                                                                \
    ll __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define ULL(...)                                                                                \
    ull __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define STR(...)                                                                                \
    string __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                \
    char __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                \
    double __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LD(...)                                                                                \
    ld __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
template <class T> void scan(T a) { cin >> a; }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T> void scan(vector<T> &);
template <class T, size_t size> void scan(array<T, size> &);
template <class T, class L> void scan(pair<T, L> &);
template <class T, size_t size> void scan(T (&)[size]);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(deque<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T, size_t size> void scan(array<T, size> &a) {
    for(auto &i : a) scan(i);
}
template <class T, class L> void scan(pair<T, L> &p) {
    scan(p.first);
    scan(p.second);
}
template <class T, size_t size> void scan(T (&a)[size]) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &... tail) {
    scan(head);
    IN(tail...);
}
string stin() {
    string s;
    cin >> s;
    return s;
}
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
vi iota(int n) {
    vi a(n);
    iota(all(a), 0);
    return a;
}
template <class T> void UNIQUE(vector<T> &x) {
    sort(all(x));
    x.erase(unique(all(x)), x.end());
}
int in() {
    int x;
    cin >> x;
    return x;
}
ll lin() {
    unsigned long long x;
    cin >> x;
    return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T> void print(const vector<T> &);
template <class T, size_t size> void print(const array<T, size> &);
template <class T, class L> void print(const pair<T, L> &p);
template <class T, size_t size> void print(const T (&)[size]);
template <class T> void print(const vector<T> &a) {
    if(a.empty()) return;
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
    cout << endl;
}
template <class T> void print(const deque<T> &a) {
    if(a.empty()) return;
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
}
template <class T, size_t size> void print(const array<T, size> &a) {
    print(a[0]);
    for(auto i = a.begin(); ++i != a.end();) {
        cout << " ";
        print(*i);
    }
}
template <class T, class L> void print(const pair<T, L> &p) {
    cout << '(';
    print(p.first);
    cout << ",";
    print(p.second);
    cout << ')';
}
template <class T> void print(set<T> &x) {
    for(auto e : x) print(e), cout << " ";
    cout << endl;
}
template <class T> void print(multiset<T> &x) {
    for(auto e : x) print(e), cout << " ";
    cout << endl;
}
template <class T, size_t size> void print(const T (&a)[size]) {
    print(a[0]);
    for(auto i = a; ++i != end(a);) {
        cout << " ";
        print(*i);
    }
}
template <class T> void print(const T &a) { cout << a; }
int out() {
    putchar('\n');
    return 0;
}
template <class T> int out(const T &t) {
    print(t);
    putchar('\n');
    return 0;
}
template <class Head, class... Tail> int out(const Head &head, const Tail &... tail) {
    print(head);
    putchar(' ');
    out(tail...);
    return 0;
}
ll gcd(ll a, ll b) {
    while(b) {
        ll c = b;
        b = a % b;
        a = c;
    }
    return a;
}
ll lcm(ll a, ll b) {
    if(!a || !b) return 0;
    return a * b / gcd(a, b);
}
vector<pll> factor(ll x) {
    vector<pll> ans;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0) {
            ans.push_back({i, 1});
            while((x /= i) % i == 0) ans.back().second++;
        }
    if(x != 1) ans.push_back({x, 1});
    return ans;
}
vector<int> divisor(int x) {
    vector<int> ans;
    for(int i = 1; i * i <= x; i++)
        if(x % i == 0) {
            ans.pb(i);
            if(i * i != x) ans.pb(x / i);
        }
    return ans;
}
template <typename T> void zip(vector<T> &x) {
    vector<T> y = x;
    sort(all(y));
    for(int i = 0; i < x.size(); ++i) { x[i] = lb(y, x[i]); }
}
int popcount(ll x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n - 1)(rng); }
template <typename T> void shuffle(vector<T> &v) {
    rep3(i, v.size() - 1, 1) { swap(v[i], v[rnd(i)]); }
}
#define endl '\n'
vector<string> YES{"NO", "YES"};
vector<string> Yes{"No", "Yes"};
vector<string> yes{"no", "yes"};

#ifdef _LOCAL
#undef endl
#define debug(x)                                                                                \
    cout << #x << ": ";                                                                                \
    print(x);                                                                                \
    cout << endl;
void err() {}
template <class T> void err(const T &t) {
    print(t);
    cout << " ";
}
template <class Head, class... Tail> void err(const Head &head, const Tail &... tail) {
    print(head);
    putchar(' ');
    out(tail...);
}
#else
#define debug(x)
template <class... T> void err(const T &...) {}
#endif

template <typename T> struct edge {
    int from, to;
    T cost;
    int id;
    edge(int to, T cost) : from(-1), to(to), cost(cost) {}
    edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
    // edge(int from,int to,T cost,int id):from(from),to(to),cost(cost),id(id){}
    edge &operator=(const int &x) {
        to = x;
        return *this;
    }
    operator int() const { return to; }
};

template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedTree = vector<Edges<T>>;
template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedGraph = vector<Edges<T>>;
template <typename T> using Matrix = vector<vector<T>>;
using Graph = vector<vector<int>>;
using tree = vector<vector<int>>;

tree getTree(int n, int offset = 1) {
    tree res(n);
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        res[a].emplace_back(b);
        res[b].emplace_back(a);
    }
    return res;
}
template <typename T> WeightedTree<T> getWeightedTree(int n, int offset = 1) {
    WeightedTree<T> res(n);
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        T c;
        cin >> c;
        res[a].emplace_back(b, c);
        res[b].emplace_back(a, c);
    }
    return res;
}

Graph getGraph(int n, int m, int offset = 1) {
    Graph res(n);
    for(int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a -= offset, b -= offset;
        res[a].emplace_back(b);
        res[b].emplace_back(a);
    }
    return res;
}

template <typename T> WeightedGraph<T> getWeightedGraph(int n, int m, int offset = 1) {
    WeightedGraph<T> res(n);
    for(int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        T c;
        cin >> c;
        res[a].emplace_back(b, c);
        res[b].emplace_back(a, c);
    }
}
struct Setup_io {
    Setup_io() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cout << fixed << setprecision(15);
    }
} setup_io;
#pragma endregion

// _________コーディングはここから！！___________
// ... 最小側の制約も確認した？
// ... オーバーフローしない？

namespace modular {
ll MOD = 1;

const int MAXN = 1100000;
class modint {
    using u64 = ll;
    ll Modulus;

  public:
    u64 a;

    modint(const u64 x = 0) noexcept : Modulus(MOD), a(((x % MOD) + MOD) % MOD) {}
    u64 &value() noexcept { return a; }
    modint operator+(const modint rhs) const noexcept { return modint(*this) += rhs; }
    modint operator-(const modint rhs) const noexcept { return modint(*this) -= rhs; }
    modint operator*(const modint rhs) const noexcept { return modint(*this) *= rhs; }
    template <typename T> modint operator^(T rhs) const noexcept { return modint(*this) ^= rhs; }
    modint &operator+=(const modint rhs) noexcept {
        a += rhs.a;
        if(a >= Modulus) { a -= Modulus; }
        return *this;
    }
    modint &operator-=(const modint rhs) noexcept {
        if(a < rhs.a) { a += Modulus; }
        a -= rhs.a;
        return *this;
    }
    modint &operator*=(const modint rhs) noexcept {
        a = a * rhs.a % Modulus;
        return *this;
    }
    bool operator==(const modint rhs) const noexcept { return a == rhs.a; }
    bool operator<(const modint rhs) const noexcept { return a < rhs.a; }
    template <typename T> modint &operator^=(T n) noexcept {
        modint res = 1;
        modint x = a;
        while(n) {
            if(n & 1) res *= x;
            x *= x;
            n >>= 1;
        }
        a = res.a;
        return *this;
    }
};
#define mint modint
#define vmint vector<mint>
vmint Inv, Prd, Invprd;
void setmod(ll x) {
    MOD = x;
    Inv = {0, 1}, Prd = Invprd = {1, 1};
}
mint inv(int n) {
    if(Inv.size() > n)
        return Inv[n];
    else {
        for(int i = Inv.size(); i <= n; ++i) Inv.emplace_back(Inv[MOD % i] * (-MOD / i));
        return Inv[n];
    }
}
mint prd(int n) {
    if(Prd.size() > n)
        return Prd[n];
    else
        for(int i = Prd.size(); i <= n; ++i) Prd.emplace_back(Prd[i - 1] * i);
    return Prd[n];
}
mint invprd(int n) {
    if(Invprd.size() > n)
        return Invprd[n];
    else
        for(int i = Invprd.size(); i <= n; ++i) Invprd.emplace_back(Invprd[i - 1] * inv(i));
    return Invprd[n];
}
mint modpow(ll a, ll n) {
    mint x = a;
    return x ^= n;
}
modint operator/(modint l, modint r) {
    if(r.a < MAXN) return l * inv(r.a);
    return l * (r ^ (MOD - 2));
}
modint operator/=(modint &l, modint r) { return l = l / r; }
mint cmb(int a, int b) {
    if(a < b) return 0;
    if(a < 0 || b < 0) return 0;
    return prd(a) * invprd(b) * invprd(a - b);
}
ostream &operator<<(ostream &os, mint a) {
    os << a.a;
    return os;
}
istream &operator>>(istream &is, mint &a) {
    ll x;
    is >> x;
    a = x;
    return is;
}
} // namespace modular

using namespace modular;

main() {
    INT(m);LL(n);
    setmod(m);
    vmint a(n);
    rep(i, n) cin >> a[i];
    if(n == m) {
        cout << "0 1\n";
        return 0;
    }
    if(n == 1 or m == 2) {
        cout << a[0] << " 0\n";
        return 0;
    }
    mint t, s;
    rep(i, n) {
        t += a[i];
        s += a[i] * a[i];
    }
    mint N = n;
    mint aa = (n * (n-1) / 2);
    mint b = n * (n-1);
    mint c = (ll)n * (n-1) * (n * 2 - 1) / 6;
    // n x + aa d = t
    // n x^2 + b dx + c d^2 = s
    mint d, x;
    set<mint> se;
    rep(i, n) se.emplace(a[i]);
    rep(i, n) {
        x = a[i];
        d = (t - x * n) / aa;
        if(N * x * x + b * d * x + c * d * d == s) {
            int cnt = 0;
            mint now = x;
            while(cnt < n and se.count(now)) {
                cnt++;
                now += d;
            }
            if(cnt == n) {
                cout << x << " " << d << endl;
                return 0;
            }
        }
    }
    cout << -1 << endl;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (ll) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (ll)(x - 'a')

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <ll, ll> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const ll inf = numeric_limits <ll>::max() >> 1;
const ll N = 1e5 + 1;
ll m, n, d;
ll arr[N];
ll inv[N];

set <ll> elem;
set <ll> inve;

void input() {
    cin >> m >> n;
    for(ll i = 1; i <= n; ++i) {
        cin >> arr[i];
        elem.insert(arr[i]);
    }
}

ll fpow(ll b, ll p = m - 2) {
    ll res = 1;
    ll pow = b;
    for(; p; p >>= 1) {
        if(p & 1) {
            res *= pow;
            res %= m;
        }
        pow *= pow;
        pow %= m;
    }
    return res;
}

ll compute() {
    ll x = arr[1];
    ll y = arr[2];
    ll dif = x - y;
    if(dif < 0) {
        dif += m;
    }
    ll cnt = 0;
    for(ll i = 1; i <= n; ++i) {
        cnt += elem.count((arr[i] + dif) % m);
    }
    ll k = n - cnt;
    return 1ll * dif * fpow(k) % m;
}

ll compute_inv() {
    ll len = 0;
    for(ll i = 0; i < m; ++i) {
        if(!elem.count(i)) {
            inve.insert(i);
            inv[++len] = i;
        }
    }
    if(len == 1) {
        cout << (inv[1] + 1) % m << " " << 1 << "\n";
        exit(0);
    }
    ll x = inv[1];
    ll y = inv[2];
    ll dif = x - y;
    if(dif < 0) {
        dif += m;
    }
    ll cnt = 0;
    for(ll i = 1; i <= len; ++i) {
        cnt += inve.count((inv[i] + dif) % m);
    }
    ll k = len - cnt;
    return 1ll * dif * fpow(k) % m;
}

bool test(ll x, ll d) {
    ll res = 0;
    for(ll i = 0; i < n; ++i) {
        res += elem.count((x + i * d) % m);
    }
    return res == n;
}

void solve() {
    if(n == m) {
        cout << "0 0\n";
        return;
    }
    if(n == 1) {
        cout << arr[1] << " " << 0 << "\n";
        return;
    }
    if(n * 2 < m) {
        d = compute();
    } else {
        d = compute_inv();
    }
    for(ll i = 1; i <= n; ++i) {
        if(!elem.count((arr[i] - d + m) % m)) {
            if(test(arr[i], d)) {
                cout << arr[i] << " " << d << "\n";
            } else {
                cout << "-1\n";
            }
            return;
        }
    }
    cout << "-1\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}