#include <bits/stdc++.h>
//上記が使用不可な環境において
/*
#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <iomanip>  //setprecsion
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <cctype> // isupper, islower, isdigit, toupper, tolower
*/
using namespace std;

typedef long double ld;
typedef long long int ll;
typedef long long int lli;
typedef unsigned long long int ull;
typedef string str;
typedef vector<char> vc;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<str> vs;
typedef vector<ll> vll;
typedef vector<pair<ll, ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef vector<vector<char>> vvc;
typedef vector<vector<str>> vvs;
const ld PI = acos(-1.0);
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rrep(i, n) for (ll i = 1; i <= (n); ++i)
#define irep(it, stl) for (auto it = stl.begin(); it != stl.end(); it++)
#define drep(i, n) for (ll i = (n)-1; i >= 0; --i)
#define fin(ans) cout << (ans) << '\n'
#define mp(p, q) make_pair(p, q)
#define pb(n) push_back(n)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define Sort(a) sort(a.begin(), a.end())
#define Rort(a) sort(a.rbegin(), a.rend())
//小数点型に
#define CAST(n) static_cast<ld>(n)
//初期化
#define DEFO(n) ll n = 0;
//整数最大
#define MAX(n) ll n = 9000000000000000000;
//整数最小
#define MIN(n) ll n = -9000000000000000000;
//少数最大
#define MAX_D(n) ld n = 4500;
//少数最小
#define MIN_D(n) ld n = -4500;
//整数入力
#define LL(n) \
  ll n;       \
  cin >> n;
//少数入力
#define LD(n) \
  ld n;       \
  cin >> n;
//整数配列入力
#define LLV(a, n)            \
  vector<ll> a(n);           \
  for (ll i = 0; i < n; i++) \
  {                          \
    cin >> a.at(i);          \
  };
//２列整数配列入力
#define LLV2(a, b, n)          \
  vector<ll> a(n), b(n);       \
  for (ll i = 0; i < n; i++)   \
  {                            \
    cin >> a.at(i) >> b.at(i); \
  };
//３列整数配列入力
#define LLV3(a, b, c, n)                  \
  vector<ll> a(n), b(n), c(n);            \
  for (ll i = 0; i < n; i++)              \
  {                                       \
    cin >> a.at(i) >> b.at(i) >> c.at(i); \
  };
//少数配列入力
#define LDV(a, n)            \
  vector<ld> a(n);           \
  for (ll i = 0; i < n; i++) \
  {                          \
    cin >> a.at(i);          \
  };
//２列少数配列入力
#define LDV2(a, b, n)          \
  vector<ld> a(n), b(n);       \
  for (ll i = 0; i < n; i++)   \
  {                            \
    cin >> a.at(i) >> b.at(i); \
  };
//３列少数配列入力
#define LD3(a, b, c, n)                   \
  vector<ld> a(n), b(n), c(n);            \
  for (ll i = 0; i < n; i++)              \
  {                                       \
    cin >> a.at(i) >> b.at(i) >> c.at(i); \
  };
//文字列入力
#define STR(n) \
  string n;    \
  cin >> n;
//文字列配列入力
#define STRV(a, n)           \
  vector<string> a(n);       \
  for (ll i = 0; i < n; i++) \
  {                          \
    cin >> a.at(i);          \
  };
//配列の合計
#define SUM(n) accumulate(n.begin(), n.end(), 0);
//配列を昇順
#define SORT(n) sort(n.begin(), n.end());
//配列を降順
#define REVE(n) reverse(n.begin(), n.end());
//Yesと表示
#define yes              \
  cout << "Yes" << endl; \
  return 0;
//Noと表示
#define no              \
  cout << "No" << endl; \
  return 0;
//ACと表示
#define AC              \
  cout << "AC" << endl; \
  return 0;
//WAと表示
#define WA              \
  cout << "WA" << endl; \
  return 0;
//Noneと表示
#define none              \
  cout << "None" << endl; \
  return 0;
//Oddと表示
#define odd              \
  cout << "Odd" << endl; \
  return 0;
//Evenと表示
#define even              \
  cout << "Even" << endl; \
  return 0;
//四捨五入
#define C45(n) (n + 1) / 2
//nを出力
#define OUT(n) cout << n << endl;
//nを出力
#define DOUT(n) cout << fixed << setprecision(20) << n << endl;
//追記
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
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;
}
struct io
{
  io()
  {
    ios::sync_with_stdio(false);
    cin.tie(0);
  }
};
const int INF = INT_MAX;
const ll LLINF = 1LL << 60;
const ll MOD = 1000000007;
const double EPS = 1e-9;
//文字列からcを探す
ll stringcount(str s, char c)
{
  return count(s.cbegin(), s.cend(), c);
}
//素数
bool IsPrime(ll num)
{
  if (num < 2)
    return false;
  else if (num == 2)
    return true;
  else if (num % 2 == 0)
    return false;
  long double sqrtNum = sqrt(num);
  for (ll i = 3; i <= sqrtNum; i += 2)
  {
    if (num % i == 0)
      return false;
  }
  return true;
}
//桁数
ll GetDigit(ll num)
{
  return log10(num) + 1;
}
//各桁の和
ll KSum(ll n)
{
  ll sum = 0;
  if (n < 0)
    return 0;
  while (n > 0)
  {
    sum += n % 10;
    n /= 10;
  }
  return sum;
}
//数値反転
bool KReve(ll n)
{
  int reverse = 0;
  int remaind;
  int tmp = n;
  while (tmp != 0)
  {
    remaind = tmp % 10;
    reverse = reverse * 10 + remaind;
    tmp /= 10;
  }
  if (reverse == n)
    return true;
  else
    return false;
}
//約数全列挙
vector<ll> enum_div(ll n)
{
  vector<ll> ret;
  for (ll i = 1; i * i <= n; ++i)
  {
    if (n % i == 0)
    {
      ret.push_back(i);
      if (i != 1 && i * i != n)
      {
        ret.push_back(n / i);
      }
    }
  }
  return ret;
}
//最大公約数
ll gcd(ll a, ll b)
{
  return b ? gcd(b, a % b) : a;
}
//複数個の最大公約数
ll ngcd(vector<ll> a)
{
  ll res;
  res = a[0];
  for (ll i = 1; i < a.size() && res != 1; i++)
  {
    res = gcd(a[i], res);
  }
  return res;
}
//最小公倍数
ll lcm(ll a, ll b)
{
  return a * b / gcd(a, b);
}
//複数個の最小公倍数
ll nlcm(vector<ll> numbers)
{
  ll res;
  res = numbers[0];
  for (ll i = 1; i < numbers.size(); i++)
  {
    res = lcm(res, numbers[i]);
  }
  return res;
}
//累乗
ll Pow(ll x, ll n)
{
  ll res = 1;
  while (n > 0)
  {
    if (n & 1)
      res = res * x;
    x = x * x;
    n >>= 1;
  }
  return res;
}
//累乗(xのn乗%mod)
ll mod_pow(ll x, ll n, ll mod)
{
  ll res = 1;
  while (n > 0)
  {
    if (n & 1)
      res = res * x % mod;
    x = x * x % mod;
    n >>= 1;
  }
  return res;
}
//階乗
ll factorial(ll n)
{
  ll a = 1;
  ll b = n;
  for (int i = 0; i < n; i++)
  {
    a *= b;
    b--;
  }
  return a;
}
//組み合わせ　nCr
ll comb(ll a, ll b)
{
  ll c;
  c = factorial(a) / (factorial(a - b) * factorial(b));
  return c;
}
//累積和
//n ~ mの和
ll sigma(ll n, ll m)
{
  return ((n + m) * (m - n + 1) * 0.5);
}
//期待値
ld hope(ld a)
{
  return (sigma(1, a) / a);
}
/*error
//幅優先探索
// 各座標に格納したい情報を構造体にする
// 今回はX座標,Y座標,深さ(距離)を記述している
struct Corr
{
  int x;
  int y;
  int depth;
};
queue<Corr> q;
int bfs(vector<vector<int>> grid)
{
  // 既に探索の場所を1，探索していなかったら0を格納する配列
  vector<vector<int>> ispassed(grid.size(), vector<int>(grid[0].size(), false));
  // このような記述をしておくと，この後のfor文が綺麗にかける
  int dx[8] = {1, 0, -1, 0};
  int dy[8] = {0, 1, 0, -1};
  while (!q.empty())
  {
    Corr now = q.front();
    q.pop();
    //今いる座標は(x,y)=(now.x, now.y)で，深さ(距離)はnow.depthである  ここで，今いる座標がゴール(探索対象)なのか判定する
    for (int i = 0; i < 4; i++)
    {
      int nextx = now.x + dx[i];
      int nexty = now.y + dy[i];

      // 次に探索する場所のX座標がはみ出した時
      if (nextx >= grid[0].size())
        continue;
      if (nextx < 0)
        continue;

      // 次に探索する場所のY座標がはみ出した時
      if (nexty >= grid.size())
        continue;
      if (nexty < 0)
        continue;

      // 次に探索する場所が既に探索済みの場合
      if (ispassed[nexty][nextx])
        continue;

      ispassed[nexty][nextx] = true;
      Corr next = {nextx, nexty, now.depth + 1};
      q.push(next);
    }
  }
}
*/
//セグメント木
class Monoid
{
public:
  // 単位元
  ll unit;

  Monoid()
  {
    // 単位元
    unit = 0;
  }

  // 演算関数
  ll calc(ll a, ll b)
  {
    return a + b;
  }
};

class SegmentTree
{
public:
  // セグメント木の葉の要素数
  ll n;

  // セグメント木
  vector<ll> tree;

  // モノイド
  Monoid mono;

  SegmentTree(vector<ll> &v)
  {
    n = 1 << (ll)ceil(log2(v.size()));
    tree = vector<ll>(n << 1);
    for (ll i = 0; i < v.size(); i++)
    {
      update(i, v[i]);
    }
    for (ll i = v.size(); i < n; i++)
    {
      update(i, mono.unit);
    }
  }

  // k番目の値(0-indexed)をxに変更
  void update(ll k, ll x)
  {
    k += n;
    tree[k] = x;
    for (k = k >> 1; k > 0; k >>= 1)
    {
      tree[k] = mono.calc(tree[k << 1 | 0], tree[k << 1 | 1]);
    }
  }

  // [l, r)の最小値(0-indexed)を求める．
  ll query(ll l, ll r)
  {
    ll res = mono.unit;
    l += n;
    r += n;
    while (l < r)
    {
      if (l & 1)
      {
        res = mono.calc(res, tree[l++]);
      }
      if (r & 1)
      {
        res = mono.calc(res, tree[--r]);
      }
      l >>= 1;
      r >>= 1;
    }
    return res;
  }
  ll operator[](ll k)
  {
    // st[i]で添字iの要素の値を返す
    if (k - n >= 0 || k < 0)
    {
      return -INF;
    }
    return tree[tree.size() - n + k];
  }

  void show()
  {
    int ret = 2;
    for (ll i = 1; i < 2 * n; i++)
    {
      cout << tree[i] << " ";
      if (i == ret - 1)
      {
        cout << endl;
        ret <<= 1;
      }
    }
    cout << endl;
  }
};
//四角
void square(ll h, ll w)
{
  for (ll i = 0; i < h; i++)
  {
    for (ll j = 0; j < w; j++)
    {
      cout << "#";
    }
    cout << endl;
  }
}
//四角枠
void yoke(ll h, ll w)
{
  for (ll i = 0; i < h; i++)
  {
    for (ll j = 0; j < w; j++)
    {
      if (i == 0 || i == h - 1)
        cout << "#";
      else if (j == 0 || j == w - 1)
        cout << "#";
      else
        cout << ".";
    }
    cout << endl;
  }
}

void Main()
{
  LL(N) LL(X)
  LLV(x, N)
  vll y(N);
  for(lli i = 0;i < N;i++)
  {
    y[i] = X - x[i];
  }
  OUT(abs(ngcd(y)))
}

int main()
{
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << std::fixed << std::setprecision(15);
  Main();
  return 0;
}

Measured memory_bytes: 2560