#include <bits/stdc++.h>
const long long MOD = 1000000007;
using namespace std;
struct point {
  int x;
  int y;
};
template <typename T>
struct WeightedUnionFind {
  vector<int> data;
  vector<T> ws;
  WeightedUnionFind() {}
  WeightedUnionFind(int sz) : data(sz, -1), ws(sz) {}
  int find(int k) {
    if (data[k] < 0) return k;
    auto par = find(data[k]);
    ws[k] += ws[data[k]];
    return data[k] = par;
  }
  T weight(int t) {
    find(t);
    return ws[t];
  }
  bool unite(int x, int y, T w) {
    w += weight(x);
    w -= weight(y);
    x = find(x), y = find(y);
    if (x == y) return false;
    if (data[x] > data[y]) {
      swap(x, y);
      w *= -1;
    }
    data[x] += data[y];
    data[y] = x;
    ws[y] = w;
    return true;
  }
  T diff(int x, int y) { return weight(y) - weight(x); }
};
long long gcd(long long a, long long b) {
  if (a > b) {
    return gcd(b, a);
  }
  return a == 0 ? b : gcd(b % a, a);
}
long long lcm(long long m, long long n) {
  if ((0 == m) || (0 == n)) return 0;
  return ((m / gcd(m, n)) * n);
}
int input() {
  int x;
  cin >> x;
  return x;
}
int moji(char in) {
  int ans = (int)in - (int)'a';
  if ((ans < 0) || (ans > 25)) {
    ans = 26;
  }
  return ans;
}
const int VV = 1;
int cost[VV][VV];
int d[VV];
bool used[VV];
void dijkstra(int s) {
  fill(d, d + VV, 100000);
  fill(used, used + VV, false);
  d[s] = 0;
  while (true) {
    cout << "Hello" << endl;
    int v = -1;
    for (int u = 0; u < VV; u++) {
      if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
    }
    if (v == -1) break;
    used[v] = true;
    for (int u = 0; u < VV; u++) {
      d[u] = min(d[u], d[v] + cost[v][u]);
    }
  }
}
int compare_int(const void *a, const void *b) { return *(int *)a - *(int *)b; }
int binary_searchh(long long x, long long k[], int n) {
  int l = 0;
  int r = n;
  while (r - l >= 1) {
    int i = (l + r) / 2;
    if (k[i] == x)
      return i;
    else if (k[i] < x)
      l = i + 1;
    else
      r = i;
  }
  return -1;
}
struct File {
  int aa;
  int bb;
  File(const int &aa, const int &bb) : aa(aa), bb(bb) {}
};
long long kaijo(long long x) {
  long long l = 10 * 10 * 10 * 10 * 10 * 10 * 10 * 10 * 10 + 7;
  long long sum = 1;
  for (int i = x; i > 0; i--) {
    sum *= i;
    if (sum > l) {
      sum %= l;
    }
  }
  return sum;
}
template <class T>
void chmin(T &a, T b) {
  if (a > b) {
    a = b;
  }
}
template <class T>
int former(const vector<T> &v, T x) {
  return upper_bound(v.begin(), v.end(), x) - v.begin() - 1;
}
template <class T>
int latter(const vector<T> &v, T x) {
  return lower_bound(v.begin(), v.end(), x) - v.begin();
}
struct UnionFind {
  vector<int> par;
  vector<int> sizes;
  UnionFind(int n) : par(n), sizes(n, 1) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }
  int find(int x) {
    if (x == par[x]) {
      return x;
    }
    return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) {
      return;
    }
    if (sizes[x] < sizes[y]) {
      swap(x, y);
    }
    par[y] = x;
    sizes[x] += sizes[y];
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return sizes[find(x)]; }
};
struct Edge {
  int a, b, cost;
  bool operator<(const Edge &o) const { return cost < o.cost; }
};
long long labs(long long x) {
  if (x < 0) {
    return -x;
  }
  return x;
}
long long modpow(long long a, long long n, long long mod) {
  long long res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}
template <typename T>
void remove(std::vector<T> &vector, unsigned int index) {
  vector.erase(vector.begin() + index);
}
void modadd(long long &a, long long b) {
  a += b;
  if (a >= MOD) {
    a %= MOD;
  }
}
const int MAX = 100001;
long long fac[MAX], finv[MAX], inv[MAX];
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}
long long COM(int n, int k) {
  if (n < k) return 0;
  if (n < 0 || k < 0) return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
const int maxV = 2;
vector<int> G[maxV];
void treeDFS(int from, int current, int dist, int &maxDist, int &maxVertex) {
  if (dist > maxDist) {
    maxDist = dist;
    maxVertex = current;
  }
  for (auto to : G[current]) {
    if (to == from) continue;
    treeDFS(current, to, dist + 1, maxDist, maxVertex);
  }
}
int getTreeDiameter() {
  int start = 0, end = 0, maxDist = 0;
  treeDFS(-1, start, 0, maxDist, end);
  start = end, end = 0, maxDist = 0;
  treeDFS(-1, start, 0, maxDist, end);
  return start;
}
int main() {
  long long N;
  cin >> N;
  long long a[N];
  for (int i = 0; i < N; i++) {
    cin >> a[i];
  }
  if (N % 3 != 0) {
    cout << "No" << endl;
  } else {
    sort(a, a + N);
    bool ok = true;
    for (int i = 0; i < N / 3 - 1; i++) {
      if (a[i] != a[i + 1]) {
        ok = false;
      }
    }
    for (int i = N / 3; i < N * 2 / 3 - 1; i++) {
      if (a[i] != a[i + 1]) {
        ok = false;
      }
    }
    for (int i = N * 2 / 3; i < N - 1; i++) {
      if (a[i] != a[i + 1]) {
        ok = false;
      }
    }
    if (a[0] ^ a[N / 3] ^ a[N * 2 / 3] == 0) {
    } else {
      ok = false;
    }
    if (ok) {
      cout << "Yes" << endl;
    } else {
      cout << "No" << endl;
    }
  }
}
