#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const long long int INF = 1e18;
const int mod = 1e9 + 7;
const int maxn = 5e5 + 5;
struct L_B {
  long long int d[65], p[65];
  int cnt;
  void init() {
    memset(d, 0, sizeof(d));
    memset(p, 0, sizeof(p));
    cnt = 0;
  }
  bool Insert(long long int val) {
    for (int i = 60; i >= 0; i--) {
      if (val & (1ll << i)) {
        if (!d[i]) {
          d[i] = val;
          break;
        }
        val ^= d[i];
      }
    }
    return val > 0;
  }
  long long int query_max() {
    long long int res = 0;
    for (int i = 60; i >= 0; i--) {
      if ((res ^ d[i]) > res) res ^= d[i];
    }
    return res;
  }
  long long int query_min() {
    for (int i = 0; i <= 60; i++) {
      if (d[i]) return d[i];
    }
    return 0;
  }
  void rebuild() {
    for (int i = 60; i >= 0; i--) {
      for (int j = i - 1; j >= 0; j--) {
        if (d[i] & (1ll << j)) d[i] ^= d[j];
      }
    }
    for (int i = 0; i <= 60; i++) {
      if (d[i]) p[cnt++] = d[i];
    }
  }
  long long int kthquery(long long int k) {
    long long int res = 0;
    if (k >= (1ll << cnt)) return -1;
    for (int i = 60; i >= 0; i--) {
      if (k & (1LL << i)) res ^= p[i];
    }
    return res;
  }
  void Merge(const L_B &b) {
    for (int i = 60; i >= 0; i--)
      if (b.d[i]) Insert(b.d[i]);
  }
} A;
long long int a[maxn];
void solve() {
  int n;
  while (~scanf("%d", &n)) {
    long long int s = 0, x, y;
    A.init();
    for (int i = 1; i <= n; i++) {
      scanf("%lld%lld", &x, &y);
      s ^= x;
      a[i] = x ^ y;
    }
    int cc = 0, f = 0;
    for (int i = 1; i <= n; i++) {
      if (A.Insert(a[i])) ++cc;
    }
    if (!A.Insert(s)) f = 1;
    if (!f)
      puts("1/1");
    else if (!cc)
      puts("0/1");
    else {
      long long int ans = 1ll << cc;
      printf("%lld/%lld\n", ans - 1, ans);
    }
  }
}
int main() {
  int t = 1, cas = 1;
  while (t--) {
    solve();
  }
}
