Problem:
エレベーターホール・ナンバー
JAG (Japanese Alumni Group) は東京都某所のとある高層ビルに本部を置く謎の組織である．
このビルでは $N$ 台のエレベーターが動いており，$i$ 台目のエレベーターは $low_i$ 階から $high_i$ 階までの各階に停まる ($1 \le i \le N$)．
JAG の新スタッフである X 氏は，本部を訪れようとビルのエレベーターホールまで辿り着いた．
そこでボタンを押してエレベーターを待っていた X 氏は，エレベーターが現在いる階の表示が少々変わっていることに気づいた．
$i$ 台目のエレベーターが $a_i$ 階にいるとき，$a_1, a_2, \ldots, a_N$ をこの順に並べて，十進表記で・先頭に 0 を加えず・空白を挟まずに繋げて書いた 1 つの数がディスプレイに映されるのである．
例えば，$N = 3$ で，エレベーターが順に $10$ 階，$2$ 階，$11$ 階にいるとき，$10211$ が表示される．
X 氏は，ディスプレイに映される可能性がある数は全部で何通りあるかが気になってしまった．
あなたの課題は，それを求めるプログラムを作成することである．
Input
入力は複数のデータセットからなり，各データセットは以下の形をしている．
$N$
$low_1$ $high_1$
...
$low_N$ $high_N$
データセットの最初の行は，エレベーターの台数を表す整数 $N$ ($2 \le N \le 6$) からなる．
続く $N$ 行のうち $i$ 行目は，$2$ 個の整数 $low_i$, $high_i$ ($1 \le low_i \le high_i \le 99$) からなり，$i$ 台目のエレベーターが動く範囲を表す．
入力の終わりは，ゼロを $1$ 個だけ含む行で表される．
Output
各データセットに対して，ディスプレイに映される可能性がある数の個数を $1$ 行で出力せよ．
Sample Input
2
1 11
1 11
3
10 10
2 2
11 11
4
89 91
1 12
1 12
89 91
5
1 8
2 76
10 19
6 16
33 42
6
10 59
20 69
30 79
40 89
50 99
50 99
0
Output for Sample Input
120
1
1278
659520
15625000000

Submitted solutions:

code_snippet: #include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

int N;
int L[10], R[10];
vector<vector<int>> Data[200009];
map<vector<vector<int>>, int> Map;
int pows[9] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
int Memo[20000009];
int Timer;

void Initialize() {
	for (int i = 0; i < 200000; i++) Data[i].clear();
	Map.clear();
}

int Search(vector<vector<int>> inp) {
	Timer += 1;

	// Count Phase
	int cnt = 0;
	for (int t = 0; t < inp.size(); t++) {
		vector<pair<int, int>> dat;
		for (int i = 0; i < inp[t].size(); i++) dat.push_back(make_pair(inp[t][i] / 100, inp[t][i] % 100));
		while (dat.size() < 4) dat.push_back(make_pair(-1, -1));
		for (int i = dat[0].first; i <= dat[0].second; i++) {
			for (int j = dat[1].first; j <= dat[1].second; j++) {
				for (int k = dat[2].first; k <= dat[2].second; k++) {
					for (int l = dat[3].first; l <= dat[3].second; l++) {
						int val = 0, len = 0;
						if (i >= 10) { val = 100 * val + i; len += 2; }
						else if (i >= 0) { val = 10 * val + i; len += 1; }
						if (j >= 10) { val = 100 * val + j; len += 2; }
						else if (j >= 0) { val = 10 * val + j; len += 1; }
						if (k >= 10) { val = 100 * val + k; len += 2; }
						else if (k >= 0) { val = 10 * val + k; len += 1; }
						if (l >= 10) { val = 100 * val + l; len += 2; }
						else if (l >= 0) { val = 10 * val + l; len += 1; }
						val += pows[len];
						if (Memo[val] != Timer) { cnt += 1; Memo[val] = Timer; }
					}
				}
			}
		}
	}

	// Return
	return cnt;
}

void Add(int pos, vector<int> vec) {
	for (int i = 0; i < Data[pos].size(); i++) {
		if (Data[pos][i] == vec) return;
	}
	Data[pos].push_back(vec);
}

void dfs(int pos, string cur) {
	if (pos == N + 1) {
		Add(stoi(cur) + pows[cur.size()], vector<int>{});
		return;
	}

	// Recursion
	for (int i = L[pos]; i <= R[pos]; i++) {
		string nex = cur + to_string(i);
		vector<int> List;
		if (nex.size() == 6) {
			int target = (nex[4] - '0');
			int cl = max(L[pos], 10 * target + 0) - 10 * target;
			int cr = min(R[pos], 10 * target + 9) - 10 * target;
			List.push_back(cl * 100 + cr);
		}
		if (nex.size() >= 5) {
			for (int j = pos + 1; j <= N; j++) List.push_back(L[j] * 100 + R[j]);
			Add(stoi(nex.substr(0, 5)) + 100000, List);
		}
		else {
			dfs(pos + 1, nex);
		}
	}
}

int main() {
	while (true) {
		// Step 1. Input
		cin >> N; if (N == 0) break;
		for (int i = 1; i <= N; i++) cin >> L[i] >> R[i];
		Initialize();

		// Step 2. First Part
		dfs(1, "");
		for (int i = 0; i < 200000; i++) {
			sort(Data[i].begin(), Data[i].end());
		}

		// Step 3. Second Part
		long long Answer = 0;
		for (int i = 0; i < 200000; i++) {
			if (Data[i].size() == 0) continue;
			if (Map[Data[i]] >= 1) {
				Answer += 1LL * (Map[Data[i]] - 1);
			}
			else {
				long long ret = Search(Data[i]);
				Answer += ret;
				Map[Data[i]] = ret + 1;
			}
		}

		// Step 4. Output
		cout << Answer << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 2780
memory_kb: 83352
final_rank: 13

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#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<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

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

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
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 = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += 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, ll 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)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 1;
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];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll dp[1 << 12][10];
ll cop[1 << 12][10];
int n;
void solve() {
	vector<int> l(n), r(n);
	rep(i, n)cin >> l[i] >> r[i];
	rep(t, 10) {
		int s = 1 << 1;
		if (l[0] <= t && t <= r[0])s |= (1 << 0);
		dp[s][t]++;
	}
	ll ans = 0;
	rep(c, 2 * n) {
		rep(i, (1 << (2 * n)))rep(k, 10) {
			if (dp[i][k] == 0)continue;
			if (i & (1 << (2 * n - 2)))ans += dp[i][k];
			rep(t, 10) {
				int s = 0;
				rep(j, 2 * n)if (i & (1 << j)) {
					if (j % 2) {
						if (k > 0 && l[j / 2] <= 10 * k + t && 10 * k + t <= r[j / 2]) {
							s |= (1 << (j - 1));
						}
					}
					else {
						int id = j / 2;
						if (id == n - 1)continue;
						if (l[id + 1] <= t && t<=r[id + 1]) {
							s |= (1 << (j + 2));
						}
						s |= (1 << (j + 3));
					}
				}
				cop[s][t] += dp[i][k];
			}
		}
		rep(i, (1 << 2 * n))rep(k, 10) {
			dp[i][k] = cop[i][k];
			cop[i][k] = 0;
		}
	}
	cout << ans << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(12);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t;rep(i,t)
	while (cin >> n, n)
		solve();
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4076
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
void dfs(set<int> &st, vector<int> &L, vector<int> &R, string s, int p, int N){
  if (p == N){
    st.insert(stoi(s));
  } else {
    for (int i = L[p]; i <= R[p]; i++){
      dfs(st, L, R, s + to_string(i), p + 1, N);
    }
  }
}
int main(){
  while (true){
    int N;
    cin >> N;
    if (N == 0){
      break;
    }
    vector<int> L(N), R(N);
    for (int i = 0; i < N; i++){
      cin >> L[i] >> R[i];
    }
    int X = N / 2, Y = N - X;
    set<int> st1;
    dfs(st1, L, R, "", 0, X);
    set<int> st2;
    dfs(st2, L, R, "", X, N);
    long long ans = (long long) st1.size() * st2.size();
    map<string, map<int, int>> mp;
    for (int x : st1){
      string s = to_string(x);
      int L = s.size();
      int T = 0;
      for (int j = L - 1; j >= 1; j--){
        if (st1.count(stoi(s.substr(0, j)))){
          mp[s.substr(j)][T]++;
          T *= 2;
          T++;
        } else {
          T *= 2;
        }
      }
    }
    for (int x : st2){
      string s = to_string(x);
      int L = s.size();
      int T = 0;
      for (int j = 1; j < L; j++){
        if (s[j] != '0' && st2.count(stoi(s.substr(j)))){
          if (mp.count(s.substr(0, j))){
            for (auto P : mp[s.substr(0, j)]){
              if ((T & P.first) == 0){
                ans -= P.second;
              }
            }
          }
          T += 1 << (j - 1);
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 6810
memory_kb: 80888
final_rank: 14

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

int n;
vector<int> low, high;
vector<string> lef, righ;
map<vector<string>, long long> mpl, mpr;

long long solve();

int main() {
  while (1) {
    cin >> n;
    if (n == 0) break;
    low.assign(n, 0);
    high.assign(n, 0);
    lef.clear();
    righ.clear();
    mpl.clear();
    mpr.clear();
    for (int i = 0; i < n; ++i) cin >> low[i] >> high[i];
    cout << solve() << endl;
  }
  return 0;
}

long long solve() {
  auto dfs = [&](auto&& dfs, int now, string ns, int fin,
                 vector<string>& s) -> void {
    if (now == fin) {
      s.push_back(ns);
      return;
    }
    for (int i = low[now]; i <= high[now]; ++i)
      dfs(dfs, now + 1, ns + to_string(i), fin, s);
  };
  dfs(dfs, 0, "", n / 2, lef);
  sort(lef.begin(), lef.end());
  lef.erase(unique(lef.begin(), lef.end()), lef.end());
  dfs(dfs, n / 2, "", n, righ);
  for (auto& p : righ) reverse(p.begin(), p.end());
  sort(righ.begin(), righ.end());
  righ.erase(unique(righ.begin(), righ.end()), righ.end());
  auto parse = [](vector<string>& s, int len, bool ch = 0) {
    int slen = s.size();
    map<vector<string>, long long> mp;
    auto calc = [&](string ns) {
      long long res = 0;
      if (ch) reverse(ns.begin(), ns.end());
      for (auto c : ns) {
        res *= 10;
        res += c;
      }
      return res;
    };
    for (int i = 0; i < slen;) {
      string now = s[i].substr(0, len);
      vector<string> v;
      while (i < slen && s[i].substr(0, len) == now)
        v.push_back(s[i].substr(len, s[i].size() - len)), ++i;
      if (ch)
        for (auto& p : v) reverse(p.begin(), p.end());
      sort(v.begin(), v.end());
      ++mp[v];
    }
    return mp;
  };
  mpl = parse(lef, n / 2), mpr = parse(righ, (n + 1) / 2, 1);
  long long res = 0;
  for (auto& [vl, cntl] : mpl) {
    vector<long long> v;
    for (auto s : vl) {
      long long p = 0;
      for (auto c : s) {
        p *= 10;
        p += c;
      }
      v.push_back(p);
    }
    for (auto& [vr, cntr] : mpr) {
      set<long long> st;
      for (auto& x : v)
        for (auto& y : vr) {
          long long p = x;
          for (auto c : y) {
            p *= 10;
            p += c;
          }
          st.insert(p);
        }
      long long sum = st.size();
      res += cntl * cntr * sum;
    }
  }
  return res;
}
accuracy: 1
time_ms: 5690
memory_kb: 106548
final_rank: 17

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

int n;
vector<int> low, high;
vector<string> lef, righ;
map<vector<string>, long long> mpl, mpr;

long long solve();

int main() {
  while (1) {
    cin >> n;
    if (n == 0) break;
    low.assign(n, 0);
    high.assign(n, 0);
    lef.clear();
    righ.clear();
    mpl.clear();
    mpr.clear();
    for (int i = 0; i < n; ++i) cin >> low[i] >> high[i];
    cout << solve() << endl;
  }
  return 0;
}

long long solve() {
  auto dfs = [&](auto&& dfs, int now, string ns, int fin,
                 vector<string>& s) -> void {
    if (now == fin) {
      s.push_back(ns);
      return;
    }
    for (int i = low[now]; i <= high[now]; ++i)
      dfs(dfs, now + 1, ns + to_string(i), fin, s);
  };
  dfs(dfs, 0, "", n / 2, lef);
  sort(lef.begin(), lef.end());
  lef.erase(unique(lef.begin(), lef.end()), lef.end());
  dfs(dfs, n / 2, "", n, righ);
  for (auto& p : righ) reverse(p.begin(), p.end());
  sort(righ.begin(), righ.end());
  righ.erase(unique(righ.begin(), righ.end()), righ.end());
  auto parse = [](vector<string>& s, int len, bool ch = 0) {
    int slen = s.size();
    map<vector<string>, long long> mp;
    auto calc = [&](string ns) {
      long long res = 0;
      if (ch) reverse(ns.begin(), ns.end());
      for (auto c : ns) {
        res *= 10;
        res += c;
      }
      return res;
    };
    for (int i = 0; i < slen;) {
      string now = s[i].substr(0, len);
      vector<string> v;
      while (i < slen && s[i].substr(0, len) == now)
        v.push_back(s[i].substr(len, s[i].size() - len)), ++i;
      if (ch)
        for (auto& p : v) reverse(p.begin(), p.end());
      sort(v.begin(), v.end());
      ++mp[v];
    }
    return mp;
  };
  mpl = parse(lef, n / 2), mpr = parse(righ, (n + 1) / 2, 1);
  // for (auto [x, y] : mpl) {
  //   for (auto p : x) cout << p << " ";
  //   cout << endl << y << endl;
  // }
  // for (auto [x, y] : mpr) {
  //   for (auto p : x) cout << p << " ";
  //   cout << endl << y << endl;
  // }
  long long res = 0;
  for (auto& [vl, cntl] : mpl) {
    vector<long long> v;
    for (auto s : vl) {
      long long p = 0;
      for (auto c : s) {
        p *= 10;
        p += c;
      }
      v.push_back(p);
    }
    for (auto& [vr, cntr] : mpr) {
      set<long long> st;
      for (auto& x : v)
        for (auto& y : vr) {
          long long p = x;
          for (auto c : y) {
            p *= 10;
            p += c;
          }
          st.insert(p);
        }
      long long sum = st.size();
      res += cntl * cntr * sum;
    }
  }
  return res;
}
accuracy: 1
time_ms: 5700
memory_kb: 103364
final_rank: 15

code_snippet: #pragma region preprocessor
#ifdef LOCAL
//*
    #define _GLIBCXX_DEBUG  // gcc
/*/
    #define _LIBCPP_DEBUG 0 // clang
//*/
    #define __clock__
    // #define __buffer_check__
#else
    #pragma GCC optimize("Ofast")
    // #define __buffer_check__
    // #define NDEBUG
#endif
#define __precision__ 15
#define iostream_untie true
#include <bits/stdc++.h>
#include <ext/rope>
#define __all(v) std::begin(v), std::end(v)
#define __rall(v) std::rbegin(v), std::rend(v)
#define __popcount(n) __builtin_popcountll(n)
#define __clz32(n) __builtin_clz(n)
#define __clz64(n) __builtin_clzll(n)
#define __ctz32(n) __builtin_ctz(n)
#define __ctz64(n) __builtin_ctzll(n)

#ifdef __clock__
    #include "clock.hpp"
#else
    #define build_clock() ((void)0)
    #define set_clock() ((void)0)
    #define get_clock() ((void)0)
#endif

#ifdef LOCAL
    #include "dump.hpp"
    #define mesg(str) std::cerr << "[ " << __LINE__ << " : " << __FUNCTION__ << " ]  " << str << "\n"
#else
    #define dump(...) ((void)0)
    #define mesg(str) ((void)0)
#endif
#pragma endregion // preprocessor

#pragma region std-overload
namespace std
{
    // hash
    template <class T> size_t hash_combine(size_t seed, T const &key) { return seed ^ (hash<T>()(key) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); }
    template <class T, class U> struct hash<pair<T, U>> { size_t operator()(pair<T, U> const &pr) const { return hash_combine(hash_combine(0, pr.first), pr.second); } };
    template <class tuple_t, size_t index = tuple_size<tuple_t>::value - 1> struct tuple_hash_calc { static size_t apply(size_t seed, tuple_t const &t) { return hash_combine(tuple_hash_calc<tuple_t, index - 1>::apply(seed, t), get<index>(t)); } };
    template <class tuple_t> struct tuple_hash_calc<tuple_t, 0> { static size_t apply(size_t seed, tuple_t const &t) { return hash_combine(seed, get<0>(t)); } };
    template <class... T> struct hash<tuple<T...>> { size_t operator()(tuple<T...> const &t) const { return tuple_hash_calc<tuple<T...>>::apply(0, t); } };
    // iostream
    template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) { return is >> p.first >> p.second; }
    template <class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) { return os << p.first << ' ' << p.second; }
    template <class tuple_t, size_t index> struct tupleis { static istream &apply(istream &is, tuple_t &t) { tupleis<tuple_t, index - 1>::apply(is, t); return is >> get<index>(t); } };
    template <class tuple_t> struct tupleis<tuple_t, SIZE_MAX> { static istream &apply(istream &is, tuple_t &t) { return is; } };
    template <class... T> istream &operator>>(istream &is, tuple<T...> &t) { return tupleis<tuple<T...>, tuple_size<tuple<T...>>::value - 1>::apply(is, t); }
    template <> istream &operator>>(istream &is, tuple<> &t) { return is; }
    template <class tuple_t, size_t index> struct tupleos { static ostream &apply(ostream &os, const tuple_t &t) { tupleos<tuple_t, index - 1>::apply(os, t); return os << ' ' << get<index>(t); } };
    template <class tuple_t> struct tupleos<tuple_t, 0> { static ostream &apply(ostream &os, const tuple_t &t) { return os << get<0>(t); } };
    template <class... T> ostream &operator<<(ostream &os, const tuple<T...> &t) { return tupleos<tuple<T...>, tuple_size<tuple<T...>>::value - 1>::apply(os, t); }
    template <> ostream &operator<<(ostream &os, const tuple<> &t) { return os; }
    template <class Container, typename Value = typename Container::value_type, enable_if_t<!is_same<decay_t<Container>, string>::value, nullptr_t> = nullptr>
    istream& operator>>(istream& is, Container &cont) { for(auto&& e : cont) is >> e; return is; }
    template <class Container, typename Value = typename Container::value_type, enable_if_t<!is_same<decay_t<Container>, string>::value, nullptr_t> = nullptr>
    ostream& operator<<(ostream& os, const Container &cont) { bool flag = 1; for(auto&& e : cont) flag ? flag = 0 : (os << ' ', 0), os << e; return os; }
} // namespace std
#pragma endregion // std-overload

#pragma region executive-setting
namespace setting
{
    using namespace std;
    using namespace chrono;
    system_clock::time_point start_time, end_time;
    long long get_elapsed_time() { end_time = system_clock::now(); return duration_cast<milliseconds>(end_time - start_time).count(); }
    void print_elapsed_time() { cerr << "\n----- Exec time : " << get_elapsed_time() << " ms -----\n\n"; }
    void buffer_check() { char bufc; if(cin >> bufc) cerr << "\n\033[1;35mwarning\033[0m: buffer not empty.\n"; }
    struct setupper
    {
        setupper()
        {
            if(iostream_untie) ios::sync_with_stdio(false), cin.tie(nullptr);
            cout << fixed << setprecision(__precision__);
    #ifdef stderr_path
            freopen(stderr_path, "a", stderr);
    #endif
    #ifdef LOCAL
            cerr << fixed << setprecision(__precision__) << boolalpha << "\n----- stderr at LOCAL -----\n\n";
    #endif
    #ifdef __clock__
            start_time = system_clock::now();
            atexit(print_elapsed_time);
    #endif
    #ifdef __buffer_check__
            atexit(buffer_check);
    #endif
        }
    } __setupper; // struct setupper
} // namespace setting
#pragma endregion // executive-setting

#pragma region fucntion-utility
// lambda wrapper for recursive method.
template <class lambda_type>
class make_recursive
{
    lambda_type func;
public:
    make_recursive(lambda_type &&f) : func(std::move(f)) {}
    template <class... Args> auto operator()(Args &&... args) const { return func(*this, std::forward<Args>(args)...); }
};
template <class T, class... types> T read(types... args) noexcept { typename std::remove_const<T>::type obj(args...); std::cin >> obj; return obj; }
// #define input(type, var, ...) type var{read<type>(__VA_ARGS__)}
// substitute y for x if x > y.
template <class T> inline bool chmin(T &x, const T &y) { return x > y ? x = y, true : false; }
// substitute y for x if x < y.
template <class T> inline bool chmax(T &x, const T &y) { return x < y ? x = y, true : false; }
// binary search on discrete range.
template <class iter_type, class pred_type>
iter_type binary(iter_type __ok, iter_type __ng, pred_type pred)
{
    assert(__ok != __ng);
    std::ptrdiff_t dist(__ng - __ok);
    while(std::abs(dist) > 1)
    {
        iter_type mid(__ok + dist / 2);
        if(pred(mid)) __ok = mid, dist -= dist / 2;
        else __ng = mid, dist /= 2;
    }
    return __ok;
}
// binary search on real numbers.
template <class pred_type>
long double binary(long double __ok, long double __ng, const long double eps, pred_type pred)
{
    assert(__ok != __ng);
    while(std::abs(__ok - __ng) > eps)
    {
        long double mid{(__ok + __ng) / 2};
        (pred(mid) ? __ok : __ng) = mid;
    }
    return __ok;
}
// trinary search on discrete range.
template <class iter_type, class comp_type>
iter_type trinary(iter_type __first, iter_type __last, comp_type comp)
{
    assert(__first < __last);
    std::ptrdiff_t dist(__last - __first);
    while(dist > 2)
    {
        iter_type __left(__first + dist / 3), __right = (__first + dist * 2 / 3);
        if(comp(__left, __right)) __last = __right, dist = dist * 2 / 3;
        else __first = __left, dist -= dist / 3;
    }
    if(dist > 1 && comp(next(__first), __first)) ++__first;
    return __first;
}
// trinary search on real numbers.
template <class comp_type>
long double trinary(long double __first, long double __last, const long double eps, comp_type comp)
{
    assert(__first < __last);
    while(__last - __first > eps)
    {
        long double __left{(__first * 2 + __last) / 3}, __right{(__first + __last * 2) / 3};
        if(comp(__left, __right)) __last = __right;
        else __first = __left;
    }
    return __first;
}
// size of array.
template <class A, size_t N> size_t size(A (&array)[N]) { return N; }
// be careful that val is type-sensitive.
template <class T, class A, size_t N> void init(A (&array)[N], const T &val) { std::fill((T*)array, (T*)(array + N), val); }
#pragma endregion // function-utility

#pragma region using-alias
using namespace std;
using i32 = int_least32_t; using i64 = int_least64_t; using u32 = uint_least32_t; using u64 = uint_least64_t;
using p32 = pair<i32, i32>; using p64 = pair<i64, i64>;
template <class T, class Comp = less<T>> using heap = priority_queue<T, vector<T>, Comp>;
template <class T> using hashset = unordered_set<T>;
template <class Key, class Value> using hashmap = unordered_map<Key, Value>;
using namespace __gnu_cxx;
#pragma endregion // using-alias

#pragma region library



#pragma endregion // library

#pragma region main-code
struct solver; template <class> void main_(); int main() { main_<solver>(); }
template <class solver> void main_()
{
    unsigned t = 1;
#ifdef LOCAL
    t = 1;
#endif
    t = -1; // infinite loop
    // cin >> t; // case number given

    while(t--) solver();
}

struct solver
{

    solver()
    {
        int n; cin>>n;
        if(!n) exit(0);
        vector<int> l(n),r(n);
        for(int i=0; i<n; ++i)
        {
            cin>>l[i]>>r[i];
        }
        i64 dp[13][1<<13][10]={};
        dp[0][1][0]=1;
        for(int x=1; x<=12; x++)
        {
            for(int s=1; s<1<<(n*2+1); s++)
            {
                for(int d=0; d<10; d++)
                {
                    if(!dp[x-1][s][d]) continue;
                    for(int e=0; e<10; e++)
                    {
                        int ss=0;
                        for(int i=0; i<n*2; i++)
                        {
                            if(s>>i&1)
                            {
                                int p=i/2;
                                int q=i&1;
                                if(q)
                                {
                                    int nw=d*10+e;
                                    if(l[p]<=nw and r[p]>=nw)
                                    {
                                        ss|=1<<(i+1);
                                    }
                                }
                                else
                                {
                                    if(l[p]<=e and r[p]>=e) // use 1 digit
                                    {
                                        ss|=1<<(i+2);
                                    }
                                    if(e) // use 2 digit
                                    {
                                        if(l[p]<10*(e+1) and r[p]>=10*e)
                                        {
                                            ss|=1<<(i+1);
                                        }
                                    }
                                }
                            }
                        }
                        dp[x][ss][e]+=dp[x-1][s][d];
                    }
                }
            }
        }
        i64 ans=0;
        for(int x=1; x<=12; x++)
        {
            for(int d=0; d<10; ++d)
            {
                for(int s=0; s<1<<(n*2); s++)
                {
                    ans+=dp[x][s|1<<(n*2)][d];
                }
            }
        }
        cout << ans << "\n";
    }
};
#pragma endregion // main-code
accuracy: 1
time_ms: 110
memory_kb: 11488
final_rank: 8

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define DEBUG(x) cerr<<#x<<": "<<x<<endl;
#define DEBUG_VEC(v) cerr<<#v<<":";for(int i=0;i<v.size();i++) cerr<<" "<<v[i]; cerr<<endl;
#define DEBUG_MAT(v) cerr<<#v<<endl;for(int i=0;i<v.size();i++){for(int j=0;j<v[i].size();j++) {cerr<<v[i][j]<<" ";}cerr<<endl;}
typedef long long ll;
#define int ll
 
#define vi vector<int>
#define vl vector<ll>
#define vii vector< vector<int> >
#define vll vector< vector<ll> >
#define vs vector<string>
#define pii pair<int,int>
#define pis pair<int,string>
#define psi pair<string,int>
#define pll pair<ll,ll>
template<class S, class T> pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first + t.first, s.second + t.second); }
template<class S, class T> pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first - t.first, s.second - t.second); }
template<class S, class T> ostream& operator<<(ostream& os, pair<S, T> p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
#define X first
#define Y second
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define rrep1(i,n) for(int i=(int)(n);i>0;i--)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define in(x, a, b) (a <= x && x < b)
#define all(c) c.begin(),c.end()
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a = b; return 1; } return 0; }
#define UNIQUE(v) v.erase(std::unique(v.begin(), v.end()), v.end());
const ll inf = 1000000001;
const ll INF = (ll)1e18 + 1;
const long double pi = 3.1415926535897932384626433832795028841971L;
#define Sp(p) cout<<setprecision(25)<< fixed<<p<<endl;
//int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
//int dx2[8] = { 1,1,0,-1,-1,-1,0,1 }, dy2[8] = { 0,1,1,1,0,-1,-1,-1 };
vi dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};
vi dx2 = { 1,1,0,-1,-1,-1,0,1 }, dy2 = { 0,1,1,1,0,-1,-1,-1 };
#define fio() cin.tie(0); ios::sync_with_stdio(false);
const ll MOD = 1000000007;
// const ll MOD = 998244353;
// #define mp make_pair
//#define endl '\n'

void solve(int n) {
    vi low(n), high(n);
    rep (i, n) cin >> low[i] >> high[i];

    vector<vll> dp(2 * n + 1, vll(1 << (2 * n), vl(10)));
    rep (j, 10) {
        int ni = 0;
        if (in(j, low[0], high[0] + 1)) ni |= (1 << 1);
        if (j != 0 and in(j, low[0] / 10, high[0] / 10 + 1)) ni |= (1 << 0);
        dp[1][ni][j] = 1;
    }

    for (int i = 1; i < 2 * n; i++) {
        rep (j, 1 << (2 * n)) {
            if (j == 0) continue;
            rep (k, 10) {
                if (dp[i][j][k] == 0) continue;
                rep (nk, 10) {
                    int nj = 0;
                    rep (l, 2 * n) {
                        if ((j & (1 << l)) == 0) continue;
                        if (l % 2 == 0) {
                            int val = k * 10 + nk;
                            if (in(val, low[l / 2], high[l / 2] + 1)) nj |= 1 << (l + 1);
                        }
                        else {
                            if (l != 2 * n - 1) {
                                if (in(nk, low[(l + 1) / 2], high[(l + 1) / 2] + 1)) nj |= 1 << (l + 2);
                                if (nk != 0 and in(nk, low[(l + 1) / 2] / 10, high[(l + 1) / 2] / 10 + 1)) nj |= 1 << (l + 1);
                            }
                        }
                    }
                    dp[i + 1][nj][nk] += dp[i][j][k];
                }
            }
        }
    }

    // rep1 (i, 2 * n) {
    //     rep (j, 1 << (2 * n)) {
    //         rep (k, 10) {
    //             cout << dp[i][j][k] << " ";
    //         }
    //         cout << endl;
    //     }
    //     cout << endl;
    // }

    ll ans = 0;
    rep (i, 2 * n + 1) {
        rep (j, 1 << (2 * n)) {
            if ((j & (1 << (2 * n - 1))) == 0) continue;
            rep (k, 10) {
                ans += dp[i][j][k];
            }
        }
    }
    cout << ans << endl;
}

signed main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) return 0;
        solve(n);
    }
}
accuracy: 1
time_ms: 140
memory_kb: 9656
final_rank: 5

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<functional>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
#define MOD 1000000007
#define f(i,n) for(long long i=0;i<(long long)(n);i++)
#define N 1000


int main() {
	long long n;
	long long m[15][10][10];
	long long dp[12][4096][10];
	long long lo[7];
	long long hi[7];
	long long p2[15];
	long long x, y, z, s, ans;
	p2[0] = 1;
	f(i, 14)p2[i + 1] = p2[i] * 2;
	while(true) {
		ans = 0;
		scanf("%lld", &n);
		if (n == 0)return 0;
		f(i, n)scanf("%lld %lld", &lo[i], &hi[i]);
		f(i, 15) {
			f(ii, 10) {
				f(jj, 10)m[i][ii][jj] = 0;
			}
		}
		f(i, (2 * n) - 1) {
			f(ii, 10) {
				f(jj, 10) {
					if (i % 2 == 0) {
						if (ii == 0)m[i][ii][jj] = 0;
						else {
							x = 10 * ii + jj;
							y = i / 2;
							if ((lo[y] <= x) && (x <= hi[y]))m[i][ii][jj] = p2[i + 1];
							else m[i][ii][jj] = 0;
						}
					}
					else {
						m[i][ii][jj] = 0;
						if (jj != 0) {
						x = jj;
						y = (i + 1) / 2;
						if ((lo[y] <= x) && (x <= hi[y]))m[i][ii][jj] += p2[i + 2];
						x = 10 * jj;
						if ((lo[y] <= (x + 9)) && (x <= hi[y]))m[i][ii][jj] += p2[i + 1];
						}
					}
				}
			}
		}
		f(i, 12) {
			f(j, 4096) {
				f(ii, 10)dp[i][j][ii] = 0;
			}
		}
		for (long long i = 1; i <= 9; i++) {
			z = 0;
			x = i;
			if ((lo[0] <= x) && (x <= hi[0]))z += 2;
			x = 10 * i;
			if ((lo[0] <= (x + 9)) && (x <= hi[0]))z += 1;
			if (z > 0)dp[0][z][i] = 1;
		}
		f(i, 2 * n) {
			f(j, p2[(2 * n)]) {
				f(ii, 10) {
					if (dp[i][j][ii] > 0) {
						f(jj, 10) {
							x = j;
							y = 0;
							f(iii, 2 * n) {
								if (x % 2 == 1) {
									if (iii == ((2 * n) - 1)){
                                     if(jj==0) ans += dp[i][j][ii];
                                    }
									else {
										y = (y | m[iii][ii][jj]);
									}
								}
								x /= 2;
							}
							if (y > 0)dp[i + 1][y][jj] += dp[i][j][ii];
						}
					}
				}
			}
		}
		printf("%lld\n", ans);
	}


	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 6428
final_rank: 3

code_snippet: #include <iostream>
#define llint long long

using namespace std;

llint n;
llint l[6], r[6];
bool can10[6][10], can1[6][10], can[6][10][10];
llint dp[15][1<<13][10];
llint nx[1<<13][10][10];

int main(void)
{
	while(1){
		cin >> n;
		if(n == 0) break;
		for(int i = 0; i < n; i++) cin >> l[i] >> r[i];
		
		for(int i = 0; i < n; i++){
			for(int j = 0; j < 10; j++){
				can10[i][j] = can1[i][j] = false;
				for(int k = 0; k < 10; k++){
					can[i][j][k] = false;
				}
			}
		}
		for(int i = 0; i < n; i++){
			for(int j = l[i]; j <= r[i]; j++){
				if(j/10 > 0) can10[i][j/10] = true;
				if(j/10 > 0) can[i][j/10][j%10] = true;
				if(j <= 9) can1[i][j] = true;
			}
		}
		
		llint S = 1 << (2*n+1);
		for(int j = 0; j < S; j++){
			for(int k = 0; k < 10; k++){
				for(int l = 0; l < 10; l++){
					int nj = 0;
					for(int m = 0; m < 2*n; m++){
						if((j & (1<<m)) == 0) continue;
						int p = (m+1)/2-1;
						if(m % 2 == 0){
							if(can10[p+1][l]) nj |= 1<<(m+1);
							if(can1[p+1][l]) nj |= 1<<(m+2);
						}
						else if(can[p][k][l]) nj |= 1<<(m+1);
					}
					nx[j][k][l] = nj;
				}
			}
		}
		
		
		for(int i = 0; i <= 2*n; i++){
			for(int j = 0; j < S; j++){
				for(int k = 0; k < 10; k++){
					dp[i][j][k] = 0;
				}
			}
		}
		dp[0][1][0] = 1;
		
		for(int i = 0; i < 2*n; i++){
			for(int j = 0; j < S; j++){
				for(int k = 0; k < 10; k++){
					for(int l = 0; l < 10; l++){
						int nj = nx[j][k][l];
						dp[i+1][nj][l] += dp[i][j][k];
					}
				}
			}
		}
		
		llint ans = 0;
		for(int i = 1; i <= 2*n; i++){
			for(int j = 0; j < S; j++){
				if((j & (1<<(2*n))) == 0) continue;
				for(int k = 0; k < 10; k++){
					ans += dp[i][j][k];
				}
			}
		}
		cout << ans << endl;
	}
	
	return 0;
}
accuracy: 1
time_ms: 1120
memory_kb: 17772
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
// #define endl '\n'
#define ALL(V) (V).begin(), (V).end()
#define ALLR(V) (V).rbegin(), (V).rend()
// #define DEBUGGING

template <typename T> using V = vector<T>;
template <typename T> using VV = V<V<T>>;
template <typename T, typename U> using P = pair<T, U>;
using ll = int64_t;
using PLL = P<ll, ll>;

template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return max(low, min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { t = clamp(t, low, high); }

namespace __init {

struct InitIO {
    InitIO() {
        cin.tie(nullptr);
        ios_base::sync_with_stdio(false);
        cout << fixed << setprecision(30);
    }
} init_io;

}

#ifdef DEBUGGING
#include "../debug.cpp"
#else
#define DEBUG(...) 0
#define DEBUG_SEPARATOR_LINE 0
#endif

template <typename T>
T make_v(T init) { return init; }

template <typename T, typename... Tail>
auto make_v(T init, size_t s, Tail... tail) {
#define rec make_v(init, tail...)
    return V<decltype(rec)>(s, rec);
#undef rec
}

template <size_t Q, size_t Label>
class Automaton {
    
    template <size_t S>
    struct BitsetComparator {
        bool operator()(const bitset<S> &s1, const bitset<S> &s2) {
            return s1.to_string() < s2.to_string();
        }
    };
    
public:
    using State = ll;
    using States = bitset<Q>;
    using StatesComparator = BitsetComparator<Q>;
    using StatesSet = set<States, StatesComparator>;
    using Edge = array<V<ll>, Label>;
    using Edges = V<Edge>;

    ll start;
    V<ll> finish_v;
    States finish_states;
    Edges edges;

    Automaton(ll start, V<ll> finish_v, Edges edges)
        : start(start),
          finish_v(finish_v),
          finish_states(vec2states(finish_v)),
          edges(edges) 
    {
    }

    Automaton(ll start, V<ll> finish_v)
        : Automaton(start, finish_v, Edges(Q)) {}

    void add_edge(ll now, ll nxt, ll label) {
        // cout << label << " : " << now << " -> " << nxt << endl;
        edges[now][label].push_back(nxt); 
    }

    Automaton<Q, Label> nfa2dfa() {
        StatesSet states_set;
        StatesSet finish_states_set;
        queue<States> que;
        map<States, array<StatesSet, Label>, StatesComparator> dfa_edges;
        que.push(start_state());

        states_set.insert(start_state());

        while(que.size()) {
            trans_states(states_set, finish_states_set, que, dfa_edges);
        }

        return move(create_dfa(states_set, finish_states_set, dfa_edges));
    }

private:
    // TODO: 前計算したほうが良いかもしれないね
    States vec2states(const V<ll> &finish_v) {
        States ret(0);
        for(ll e : finish_v) ret.set(e, 1);
        return move(ret);
    }

    States start_state() { return move(States(0).set(start, 1)); }

    States next_states(const States &now, ll label) {
        States ret(0);
        for(ll q = 0; q < Q; q++) {
            if(!now.test(q)) continue;
            for(auto nxt : edges[q][label]) {
                ret.set(nxt, 1);
            }
        }
        return move(ret);
    }

    void trans_states(StatesSet &states_set,
                      StatesSet &finish_states_set,
                      queue<States> &que, 
                      map<States, array<StatesSet, Label>, StatesComparator> &dfa_edges)
    {
        States now = que.front();
        que.pop();
        
        for(ll label = 0; label < Label; label++) {
            auto nxt = next_states(now, label);
            if(nxt == States(0)) continue;
            dfa_edges[now][label].insert(nxt);
            if(states_set.find(nxt) != states_set.end()) continue;
            states_set.insert(nxt);
            if((nxt & finish_states).any()) finish_states_set.insert(nxt);
            que.push(nxt);
        }
    }

    map<States, ll, StatesComparator> create_states_id(const StatesSet &states_set) {
        map<States, ll, StatesComparator> states_id;
        for(const auto &states : states_set) {
            auto id = states_id.size();
            states_id[states] = id;
        }
        return move(states_id);
    }

    Automaton<Q, Label> create_dfa(const StatesSet &states_set,
                                   const StatesSet &finish_states_set,
                                   const map<States, array<StatesSet, Label>, StatesComparator> &dedges)
    {
        auto states_id = create_states_id(states_set);
        Edges dfa_edges(states_id.size());
        for(const auto &ele : dedges) {
            ll id = states_id[ele.first];
            for(ll label = 0; label < Label; label++) {
                for(auto next_states : ele.second[label]) {
                    dfa_edges[id][label].push_back(states_id[next_states]);
                }
            }
        }

        V<ll> dfa_finish_v;
        for(const auto &states : finish_states_set) {
            dfa_finish_v.push_back(states_id[states]);
        }
        sort(ALL(dfa_finish_v));

        ll start_id = states_id[start_state()];

        return move(Automaton<Q, Label>(start_id, dfa_finish_v, dfa_edges));
    }
};

ll get_idx(ll i, ll dnum) {
    return i * 10 + dnum;
}

using Auto = Automaton<256, 10>;

ll calc(ll now, const Auto::Edges &edges, V<ll> &memo, const Auto::States &finish) {
    if(memo[now] != -1) return memo[now];
    ll val = finish.test(now);
    for(ll label = 0; label < 10; label++) {
        const auto &edge = edges[now][label];
        for(ll nxt : edge) {
            val += calc(nxt, edges, memo, finish);
        }
    }
    return memo[now] = val;
}

bool solve() {
    ll N;
    cin >> N;

    if(!N) return false;

    V<PLL> ev;

    Auto atm(0, { 10 * N });
    V<PLL> elev;

    for(ll i = 0; i < N; i++) {
        ll low, high;
        cin >> low >> high;
        elev.emplace_back(low, high);
    }
    
    ll next_node = 0;
    reverse(ALL(elev));
    for(ll i = 0; i < N; i++) {
        ll low, high;
        tie(low, high) = elev[i];
        next_node += 10;
        for(ll j = 1; j <= 9; j++) atm.add_edge(get_idx(i, j), next_node, j);
        for(ll j = 1; j <= 99; j++) {
            if(!(low <= j && j <= high)) continue;
            if(j < 10) atm.add_edge(get_idx(i, 0), next_node, j);
            else atm.add_edge(get_idx(i, 0), get_idx(i, j / 10), j % 10);
        }
    }

    atm = atm.nfa2dfa();
    V<ll> memo(atm.edges.size() + 10, -1);
    ll start = atm.start;
    auto finish_states = atm.finish_states;
    calc(start, atm.edges, memo, finish_states);
    cout << memo[start] << endl;
    return true;
}

int main() {
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 3508
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
// #define endl '\n'
#define ALL(V) (V).begin(), (V).end()
#define ALLR(V) (V).rbegin(), (V).rend()
// #define DEBUGGING

template <typename T> using V = vector<T>;
template <typename T> using VV = V<V<T>>;
template <typename T, typename U> using P = pair<T, U>;
using ll = int64_t;
using PLL = P<ll, ll>;

template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return max(low, min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { t = clamp(t, low, high); }

namespace __init {

struct InitIO {
    InitIO() {
        cin.tie(nullptr);
        ios_base::sync_with_stdio(false);
        cout << fixed << setprecision(30);
    }
} init_io;

}

#ifdef DEBUGGING
#include "../debug.cpp"
#else
#define DEBUG(...) 0
#define DEBUG_SEPARATOR_LINE 0
#endif

template <typename T>
T make_v(T init) { return init; }

template <typename T, typename... Tail>
auto make_v(T init, size_t s, Tail... tail) {
#define rec make_v(init, tail...)
    return V<decltype(rec)>(s, rec);
#undef rec
}

template <size_t Q, size_t Label>
class Automaton {
    
    template <size_t S>
    struct BitsetComparator {
        bool operator()(const bitset<S> &s1, const bitset<S> &s2) {
            return s1.to_string() < s2.to_string();
        }
    };
    
public:
    using State = ll;
    using States = bitset<Q>;
    using StatesComparator = BitsetComparator<Q>;
    using StatesSet = set<States, StatesComparator>;
    using Edge = array<V<ll>, Label>;
    using Edges = V<Edge>;

    ll start;
    V<ll> finish_v;
    States finish_states;
    Edges edges;

    Automaton(ll start, V<ll> finish_v, Edges edges)
        : start(start),
          finish_v(finish_v),
          finish_states(vec2states(finish_v)),
          edges(edges) 
    {
    }

    Automaton(ll start, V<ll> finish_v)
        : Automaton(start, finish_v, Edges(Q)) {}

    void add_edge(ll now, ll nxt, ll label) {
        // cout << label << " : " << now << " -> " << nxt << endl;
        edges[now][label].push_back(nxt); 
    }

    Automaton<Q, Label> nfa2dfa() {
        StatesSet states_set;
        StatesSet finish_states_set;
        queue<States> que;
        map<States, array<StatesSet, Label>, StatesComparator> dfa_edges;
        que.push(start_state());

        states_set.insert(start_state());

        while(que.size()) {
            trans_states(states_set, finish_states_set, que, dfa_edges);
        }

        return move(create_dfa(states_set, finish_states_set, dfa_edges));
    }

private:
    // TODO: 前計算したほうが良いかもしれないね
    States vec2states(const V<ll> &finish_v) {
        States ret(0);
        for(ll e : finish_v) ret.set(e, 1);
        return move(ret);
    }

    States start_state() { return move(States(0).set(start, 1)); }

    States next_states(const States &now, ll label) {
        States ret(0);
        for(ll q = 0; q < Q; q++) {
            if(!now.test(q)) continue;
            for(auto nxt : edges[q][label]) {
                ret.set(nxt, 1);
            }
        }
        return move(ret);
    }

    void trans_states(StatesSet &states_set,
                      StatesSet &finish_states_set,
                      queue<States> &que, 
                      map<States, array<StatesSet, Label>, StatesComparator> &dfa_edges)
    {
        States now = que.front();
        que.pop();
        
        for(ll label = 0; label < Label; label++) {
            auto nxt = next_states(now, label);
            if(nxt == States(0)) continue;
            dfa_edges[now][label].insert(nxt);
            if(states_set.find(nxt) != states_set.end()) continue;
            states_set.insert(nxt);
            if((nxt & finish_states).any()) finish_states_set.insert(nxt);
            que.push(nxt);
        }
    }

    map<States, ll, StatesComparator> create_states_id(const StatesSet &states_set) {
        map<States, ll, StatesComparator> states_id;
        for(const auto &states : states_set) {
            auto id = states_id.size();
            states_id[states] = id;
        }
        return move(states_id);
    }

    Automaton<Q, Label> create_dfa(const StatesSet &states_set,
                                   const StatesSet &finish_states_set,
                                   const map<States, array<StatesSet, Label>, StatesComparator> &dedges)
    {
        auto states_id = create_states_id(states_set);
        Edges dfa_edges(states_id.size());
        for(const auto &ele : dedges) {
            ll id = states_id[ele.first];
            for(ll label = 0; label < Label; label++) {
                for(auto next_states : ele.second[label]) {
                    dfa_edges[id][label].push_back(states_id[next_states]);
                }
            }
        }

        V<ll> dfa_finish_v;
        for(const auto &states : finish_states_set) {
            dfa_finish_v.push_back(states_id[states]);
        }
        sort(ALL(dfa_finish_v));

        ll start_id = states_id[start_state()];

        return move(Automaton<Q, Label>(start_id, dfa_finish_v, dfa_edges));
    }
};

ll get_idx(ll i, ll dnum) {
    return i * 10 + dnum;
}

using Auto = Automaton<128, 10>;

ll calc(ll now, const Auto::Edges &edges, V<ll> &memo, const Auto::States &finish) {
    if(memo[now] != -1) return memo[now];
    ll val = finish.test(now);
    for(ll label = 0; label < 10; label++) {
        const auto &edge = edges[now][label];
        for(ll nxt : edge) {
            val += calc(nxt, edges, memo, finish);
        }
    }
    return memo[now] = val;
}

bool solve() {
    ll N;
    cin >> N;

    if(!N) return false;

    V<PLL> ev;

    Auto atm(0, { 10 * N });
    V<PLL> elev;

    for(ll i = 0; i < N; i++) {
        ll low, high;
        cin >> low >> high;
        elev.emplace_back(low, high);
    }
    
    ll next_node = 0;
    reverse(ALL(elev));
    for(ll i = 0; i < N; i++) {
        ll low, high;
        tie(low, high) = elev[i];
        next_node += 10;
        for(ll j = 1; j <= 9; j++) atm.add_edge(get_idx(i, j), next_node, j);
        for(ll j = 1; j <= 99; j++) {
            if(!(low <= j && j <= high)) continue;
            if(j < 10) atm.add_edge(get_idx(i, 0), next_node, j);
            else atm.add_edge(get_idx(i, 0), get_idx(i, j / 10), j % 10);
        }
    }

    atm = atm.nfa2dfa();
    V<ll> memo(atm.edges.size() + 10, -1);
    ll start = atm.start;
    auto finish_states = atm.finish_states;
    calc(start, atm.edges, memo, finish_states);
    cout << memo[start] << endl;
    return true;
}

int main() {
    while(solve());
    return 0;
}
accuracy: 0.5
time_ms: 250
memory_kb: 3440
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct TopologicalSort{
  Int n;
  vector<set<Int> > G;
  vector<bool> used;
  vector<Int> indeg,p;
  
  TopologicalSort(){}
  TopologicalSort(Int sz):n(sz),G(n),used(n),indeg(n),p(0){}

  void add_edge(Int s,Int t){
    G[s].insert(t);
  }
  
  void bfs(Int s){
    queue<Int> q;
    q.push(s);
    used[s]=1;
    while(!q.empty()){
      Int v=q.front();q.pop();
      p.push_back(v);
      for(Int u:G[v]){
        indeg[u]--;
        if(indeg[u]==0&&!used[u]){
          used[u]=1;
          q.push(u);
        }
      }
    }
  }
  
  vector<Int>  build(){
    fill(used.begin(),used.end(),0);
    fill(indeg.begin(),indeg.end(),0);
    
    for(Int i=0;i<n;i++)
      for(Int v:G[i]) indeg[v]++;
    
    for(Int i=0;i<n;i++)
      if(indeg[i]==0&&!used[i]) bfs(i);
    
    return p;
  }
};

//INSERT ABOVE HERE
signed main(){
  Int n;
  while(cin>>n,n){
    vector<Int> ls(n+1),hs(n+1);
    for(Int i=1;i<=n;i++) cin>>ls[i]>>hs[i];

    vector<Int> as(n+1),bs(n+1);
    vector<Int> a0(n+1),b0(n+1);
    vector<Int> a1(n+1),b1(n+1);
    vector<Int> a2(n+1),b2(n+1);
    for(Int i=1;i<=n;i++){
      a0[i]=ls[i]%10;
      b0[i]=10;
      if((ls[i]/10)==(hs[i]/10)) b0[i]=hs[i]%10+1;
    
      a1[i]=0;
      b1[i]=10;    
      a2[i]=0;
      b2[i]=hs[i]%10+1;
       
      if(ls[i]>=10){
        as[i]=10;bs[i]=-1;
        continue;
      }
      as[i]=ls[i];
      if(hs[i]>=10) bs[i]=10;
      else bs[i]=hs[i]+1;
    }

    auto calc=[&](Int k,Int p){return k*7+p;};  
    Int G[100][10]={};  
    for(Int i=1;i<=n;i++){
    
      for(Int c=0;c<10;c++){
        if(a0[i]<=c&&c<b0[i])
          G[calc(i,0)][c]|=1LL<<calc(i,3);
        if(a1[i]<=c&&c<b1[i])
          G[calc(i,1)][c]|=1LL<<calc(i,4);
        if(a2[i]<=c&&c<b2[i])
          G[calc(i,2)][c]|=1LL<<calc(i,5);
      }    
    
      if(i+1<=n){
        for(Int j=3;j<7;j++){
          for(Int c=0;c<10;c++){
            Int x=ls[i+1]/10;
            Int y=hs[i+1]/10;
        
            if(c==x&&x!=0)
              G[calc(i,j)][c]|=1LL<<calc(i+1,0);

            if(x<c&&c<y)
              G[calc(i,j)][c]|=1LL<<calc(i+1,1);
        
            if(x!=y&&c==y&&y!=0)
              G[calc(i,j)][c]|=1LL<<calc(i+1,2);
        
            if(as[i+1]<=c&&c<bs[i+1])
              G[calc(i,j)][c]|=1LL<<calc(i+1,6);
          }
        }
      }
    }
    
    for(Int c=0;c<10;c++){
      Int x=ls[1]/10;
      Int y=hs[1]/10;
        
      if(c==x&&x!=0)
        G[0][c]|=1LL<<calc(1,0);

      if(x<c&&c<y)
        G[0][c]|=1LL<<calc(1,1);
        
      if(x!=y&&c==y&&y!=0)
        G[0][c]|=1LL<<calc(1,2);
        
      if(as[1]<=c&&c<bs[1])
        G[0][c]|=1LL<<calc(1,6);
    }
     
    vector<Int> rev;
    map<Int, Int> idx;  
    idx[1]=rev.size();
    rev.emplace_back(1);
  
    TopologicalSort ts(1000);
    set<Int> used;
    queue<Int> que;
    used.emplace(1);
    que.emplace(1);
    while(!que.empty()){
      Int bit=que.front();que.pop();
      for(Int c=0;c<10;c++){
        Int nxt=0;
        for(Int i=0;i<60;i++)
          if((bit>>i)&1) nxt|=G[i][c];      
        if(nxt==0) continue;
        if(!idx.count(nxt)){
          idx[nxt]=rev.size();
          rev.emplace_back(nxt);
        }
        ts.add_edge(idx[bit],idx[nxt]);
        if(used.count(nxt)) continue;
        used.emplace(nxt);        
        que.emplace(nxt);
      }
    }
    //cout<<"sz:"<<rev.size()<<endl;

    vector<Int> ord=ts.build();  
    vector<Int> dp(ts.G.size(),0);
    dp[0]=1;  
    for(Int x:ord){
      if(x>=(Int)rev.size()) continue;
      //cout<<x<<":"<<dp[x]<<endl;
      
      Int bit=rev[x];    
      for(Int c=0;c<10;c++){
        Int nxt=0;
        for(Int i=0;i<60;i++)
          if((bit>>i)&1) nxt|=G[i][c];      
        if(nxt==0) continue;
        
        dp[idx[nxt]]+=dp[x];      
      }
    }
  
    Int ans=0;
    for(Int i=0;i<(Int)rev.size();i++){
      Int flg=0,bit=rev[i];
      for(Int j=3;j<7;j++)
        if((bit>>calc(n,j))&1) flg=1;
      if(flg) ans+=dp[i];    
    }  
    cout<<ans<<endl;
    //break;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3352
final_rank: 1

code_snippet: #include <iostream>
using namespace std;

long long N, A[7], B[7], dp[13][10][1 << 13];

void init() {
	for (int i = 0; i < 13; i++) {
		for (int j = 0; j < 10; j++) {
			for (int k = 0; k < (1 << 13); k++) dp[i][j][k] = -1;
		}
	}
}
long long solve(int pos, int mae, int mask) {
	if (mask == 0) return 0;
	if (dp[pos][mae][mask] >= 0) return dp[pos][mae][mask];

	int bit[13]; for (int j = 0; j <= N * 2; j++) bit[j] = (mask / (1 << j)) % 2;

	long long ans = 0;
	if (mask >= (1LL << (2 * N - 1)) && A[N - 1] <= mae && mae <= B[N - 1]) ans++;
	else if (mask >= (1LL << (2 * N))) ans++;

	for (int i = 0; i < 10; i++) {
		int bit2[13]; for (int j = 0; j <= N * 2; j++) bit2[j] = 0;

		for (int j = 0; j <= N * 2; j++) {
			if (bit[j] == 0) continue;
			int V1 = ((j - 1) >> 1), V2 = 0; if (j >= 1) V2 = ((j - 1) & 1) + 1; else V1 = 0;

			if (V2 == 0) {
				if (i >= 1 && i <= B[V1]) bit2[j + 1] = 1;
			}
			else if (V2 == 1) {
				if (A[V1] <= mae && i <= B[V1 + 1] && i >= 1) bit2[j + 2] = 1;
				if (A[V1] <= mae * 10 + i && mae * 10 + i <= B[V1]) bit2[j + 1] = 1;
			}
			else {
				if (i >= 1 && i <= B[V1 + 1]) bit2[j + 1] = 1;
			}
		}
		int F = 0; for (int j = 0; j <= N * 2; j++) F += (bit2[j] << j);

		ans += solve(pos + 1, i, F);
	}
	dp[pos][mae][mask] = ans;
	return ans;
}

int main() {
	while (true) {
		init();
		cin >> N; if (N == 0) break;
		for (int i = 0; i < N; i++) cin >> A[i] >> B[i];

		long long ret = solve(0, 0, 1);
		cout << ret << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 11408
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

const int PW = 10;
int pw[PW];

const int INF = 19191919;

int n;
int l[6],r[6];
int A,B;

vector<bool> va,vb;
vector<bool> appear;
int END;
void dfs(int idx, int val){
    if(idx == END){
        appear[val] = true;
        return;
    }

    for(int i=l[idx]; i<=r[idx]; ++i){
        if(i<10) dfs(idx+1, val*10 + i);
        else dfs(idx+1, val*100 + i);
    }
}


const int N = 1000000;
int low_a[N][4], high_b[N][4], val_b[N][4];

int main(){
    pw[0] = 1;
    for(int i=1; i<PW; ++i) pw[i] = pw[i-1]*10;

    memset(low_a,-1,sizeof(low_a));
    for(int i=1; i<N; ++i){
        int tv = i;
        int tmp = 0;
        for(int j=1; j<=3; ++j){
            tmp += (tv%10) * pw[j-1];
            low_a[i][j] = tmp;
            tv /= 10;
            if(tv==0) break;
        }
    }

    memset(high_b,-1,sizeof(high_b));
    memset(val_b,-1,sizeof(val_b));
    for(int i=1; i<N; ++i){
        int tv = i;
        vector<int> vv;
        while(tv>0){
            vv.pb(tv%10);
            tv /= 10;
        }
        reverse(all(vv));
        int VV = vv.size();

        int tmp = 0;
        for(int j=1; j<=min(3,VV); ++j){
            tmp = tmp*10 + vv[j-1];
            high_b[i][j] = tmp;

            val_b[i][j] = 0;
            for(int k=j; k<VV; ++k) val_b[i][j] = 10*val_b[i][j] + vv[k];
        }
        val_b[i][0] = i;
    }

    while(scanf(" %d", &n),n){
        rep(i,n) scanf(" %d %d", &l[i], &r[i]);

        A = n/2;
        B = n-A;

        appear = vector<bool>(N,false);
        END = A;
        dfs(0,0);
        va = appear;

        appear = vector<bool>(N,false);
        END = A+B;
        dfs(A,0);
        vb = appear;

        ll ans = 0;
        for(int D=A+B; D<=2*(A+B); ++D){
            // printf(" ---- D  %d ----\n",D);
            int W = min(D-(A+B), 2*(A+B)-D);

            rep(i,pw[W]){
                unordered_map<int,int> ppa,ppb;

                // calc pata,patb
                vector<int> pata(W+1),patb(W+1);
                rep(j,W+1){
                    patb[j] = -1;
                    if(j>0){
                        patb[j] = i%pw[j];

                        // no leading zero
                        int tmp = patb[j];
                        rep(_,j-1) tmp /= 10;
                        if(tmp%10==0) patb[j] = -INF;
                    }

                    pata[j] = -1;
                    if(j<W) pata[j] = i/pw[j];
                }

                int DB = B-1;
                int DA = D-DB;
                while(DA>2*A+1){
                    ++DB;
                    --DA;
                }

                rep(j,W+1){
                    ++DB;
                    --DA;
                    if(patb[j] == -INF) continue;
                    // printf("CHECK (%d %d)  DA DB ( %d %d )  pat ( %d %d )\n",i,j,DA,DB,pata[j],patb[j]);
                    // printf(" ?? %d digits,  %d digits \n", DA-(W-j), DB - j);

                    for(int k=pw[DA-(W-j)-1]; k<pw[DA-(W-j)]; ++k){
                        int num =  k*pw[W-j];
                        if(pata[j]>=0) num += pata[j];
                        if(!va[num]) continue;

                        // 下から W-j 桁
                        if(pata[j]<0 || (pata[j] == low_a[num][W-j])){
                            int val = num;
                            if(j<W) val /= pw[W-j];
                            // printf(" ! MATCH  A ! %d ,  val %d\n", num,val);
                            ppa[val] |= (1<<j);
                        }
                    }

                    int st = pw[DB-j-1];
                    if(st==1 || patb[j]>=0) st = 0;
                    for(int k=st; k<pw[DB-j]; ++k){
                        int num = k;
                        if(patb[j]>=0) num += patb[j]*pw[DB-j];
                        if(!vb[num]) continue;

                        // 上から j 桁
                        if(patb[j]<0 || (patb[j] == high_b[num][j])){
                            // printf(" ! MATCH  B ! %d ,  val %d\n", num,val_b[num][j]);
                            ppb[val_b[num][j]] |= (1<<j);
                        }
                    }
                }

                if(!ppa.empty() && !ppb.empty()){
                    vector<ll> cta(1<<(W+1)), ctb(1<<(W+1));
                    for(const auto &p:ppa) ++cta[p.se];
                    for(const auto &p:ppb) ++ctb[p.se];

                    // 高速ゼータ変換
                    rep(ii,W+1){
                        rep(jj,1<<(W+1)){
                            if((jj>>ii&1) == 0){
                                cta[jj] += cta[jj|(1<<ii)];
                                ctb[jj] += ctb[jj|(1<<ii)];
                            }
                        }
                    }

                    // 包除原理で数える
                    for(int j=1; j<(1<<(W+1)); ++j){
                        if(__builtin_popcount(j)%2==1) ans += cta[j]*ctb[j];
                        else ans -= cta[j]*ctb[j];
                    }
                }
            }
            // dbg(ans);
        }

        printf("%lld\n", ans);
    }
    return 0;
}
accuracy: 1
time_ms: 5210
memory_kb: 112144
final_rank: 16

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

int N;
int lo[6],hi[6];
ll dp[2][1<<6][1<<6][1<<6][10];
bool match0[6][10];
bool match1[6][10];
bool match2[6][10][10];

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  while(1){
    cin>>N;
    if(N==0)break;
    memset(match0,0,sizeof(match0)); memset(match1,0,sizeof(match1)); memset(match2,0,sizeof(match2));
    rep(i,N){
      cin>>lo[i]>>hi[i];
      repl(j,lo[i],hi[i]+1){
        if(j>=10){
          match0[i][j/10]=true;
          match2[i][j/10][j%10]=true;
        }
        if(j<10)match1[i][j]=true;
      }
    }
    int crt=0,nxt=1;
    rep(s0,1<<N)rep(s1,1<<N)rep(s2,1<<N)rep(j,10)dp[crt][s0][s1][s2][j]=0;
    dp[crt][1][1][0][0]=1;
    ll res=0;
    rep(i,N*2){
      rep(s0,1<<N)rep(s1,1<<N)rep(s2,1<<N)rep(j,10)dp[nxt][s0][s1][s2][j]=0;
      rep(s0,1<<N)rep(s1,1<<N)rep(s2,1<<N)rep(j,10){
        if(dp[crt][s0][s1][s2][j]==0)continue;
        rep(d,10){
          ll ns0=0,ns1=0,ns2=0;
          bool done=false;
          rep(l,N){
            if(((s0>>l)&1)&&match0[l][d]){
              ns2|=(1<<l);
            }
            if(((s1>>l)&1)&&match1[l][d]){
              if(l<N-1){
                ns0|=(1<<(l+1)); ns1|=(1<<(l+1));
              }else{
                done=true;
              }
            }
            if(((s2>>l)&1)&&match2[l][j][d]){
              if(l<N-1){
                ns0|=(1<<(l+1)); ns1|=(1<<(l+1));
              }else{
                done=true;
              }
            }
          }

          dp[nxt][ns0][ns1][ns2][d]+=dp[crt][s0][s1][s2][j];
          if(done)res+=dp[crt][s0][s1][s2][j];
        }
      }
      swap(crt,nxt);
    }
    cout<<res<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2930
memory_kb: 44064
final_rank: 12

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 7

enum Type{
	A,
	B,
};

struct Info{
	int low,high;
};

int N;
int POW_2[7],POW_10[7];
int MIN_LEN[2],MAX_LEN[2];
Info info[NUM];
ll dp[2][16];
map<int,bool> MAP[2];
ll num_list[2][NUM];
int head_table[1000][4][4];

vector<int> state_table[16];
vector<int> HEAD[NUM],TAIL[NUM];

int get_length(ll num){

	if(num == 0){
		return 1;
	}

	int ret = 0;

	while(num > 0){
		num /= 10;
		ret++;
	}

	return ret;
}

int substr_front(int num,int tmp_len,int cut_len){

	num /= POW_10[tmp_len-cut_len];
	return num;
}

int substr_tail(int num,int len){
	num %= POW_10[len];
	return num;
}

void recursive(Type type,int index,int finish_index,int num){

	int tmp_length;

	if(index == finish_index+1){

		auto at = MAP[type].find(num);
		if(at != MAP[type].end())return;

		MAP[type][num] = true;
		tmp_length = get_length(num);
		MAX_LEN[type] = max(MAX_LEN[type],tmp_length);
		MIN_LEN[type] = min(MIN_LEN[type],tmp_length);
		num_list[type][tmp_length] += 1;

		int tmp;

		if(type == A){

			for(int i = 1; i <= tmp_length; i++){
				tmp = substr_front(num,tmp_length,i);
				HEAD[i].push_back(tmp);
			}

		}else{

			for(int i = 1; i <= tmp_length; i++){
				tmp = substr_tail(num,i);
				TAIL[i].push_back(tmp);
			}
		}
		return;
	}

	int tmp_num,tmp_len,next_num;

	for(int i = info[index].low; i <= info[index].high; i++){
		tmp_len = get_length(i);
		next_num = num*POW_10[tmp_len]+i;
		recursive(type,index+1,finish_index,next_num);
	}
}

void init_dp(){

	for(int i = 0; i < 16; i++){
		dp[A][i] = 0;
		dp[B][i] = 0;
	}
}

bool rangeCheck(int num_B){
	if(num_B >= MIN_LEN[B] && num_B <= MAX_LEN[B]){
		return true;
	}else{
		return false;
	}
}

void func(){

	MAP[A].clear();
	MAP[B].clear();

	for(int i = 1; i < NUM; i++){
		num_list[A][i] = 0;
		num_list[B][i] = 0;

		HEAD[i].clear();
		TAIL[i].clear();
	}

	for(int i = 0; i < N; i++){
		scanf("%d %d",&info[i].low,&info[i].high);
	}

	MIN_LEN[A] = BIG_NUM;
	MIN_LEN[B] = BIG_NUM;

	MAX_LEN[A] = -1;
	MAX_LEN[B] = -1;

	recursive(A,0,N/2-1,0);
	recursive(B,N/2,N-1,0);

	for(int i = 1; i <= 5; i++){
		sort(HEAD[i].begin(), HEAD[i].end());
		HEAD[i].erase(unique(HEAD[i].begin(),HEAD[i].end()),HEAD[i].end());

		sort(TAIL[i].begin(),TAIL[i].end());
		TAIL[i].erase(unique(TAIL[i].begin(),TAIL[i].end()),TAIL[i].end());
	}

	int common_part_len;
	int common_max;

	ll ans = 0;

	bool is_First;
	int A_min,A_max,B_min,B_max;
	int tmp_A,tmp_B,add_A_len,add_B_len,part_num,tmp_num;
	int num_bit,a_len,b_len,tmp_state;

	for(int total_len = MIN_LEN[A]+MIN_LEN[B]; total_len <= MAX_LEN[A]+MAX_LEN[B]; total_len++){

		is_First = true;
		for(int a = MIN_LEN[A]; a <= min(MAX_LEN[A],total_len); a++){

			if(!rangeCheck(total_len-a))continue;

			if(is_First){

				A_min = a;
				A_max = a;

				B_min = total_len-a;
				B_max = total_len-a;
				is_First = false;
			}else{
				A_max = a;
				B_min = total_len-a;
			}
		}

		common_part_len = A_max-A_min;

		if(common_part_len == 0){

			ll count_A = num_list[A][A_min];
			ll count_B = num_list[B][B_max];

			ans += count_A*count_B;

			continue;
		}

		common_max = POW_10[common_part_len]-1;

		for(int common_num = 0; common_num <= common_max; common_num++){

			init_dp();

			a_len = A_min;

			for(int a = 0; a < HEAD[a_len].size(); a++){

				tmp_A = HEAD[a_len][a];

				tmp_state = 0;

				for(int loop = 0; loop < common_part_len+1; loop++){

					add_A_len = common_part_len-loop;

					if(add_A_len == 0){
						auto at = MAP[A].find(tmp_A);
						if(at == MAP[A].end()){
							//Do nothing
						}else{
							tmp_state += POW_2[loop];
						}
						continue;
					}

					part_num = head_table[common_num][common_part_len][add_A_len];

					tmp_num = tmp_A*POW_10[add_A_len]+part_num;

					auto at = MAP[A].find(tmp_num);

					if(at == MAP[A].end()){
						//Do nothing
					}else{
						tmp_state += POW_2[loop];
					}
				}

				for(int i = 0; i < state_table[tmp_state].size(); i++){
					dp[A][state_table[tmp_state][i]] += 1;
				}
			}

			b_len = B_min;

			for(int b = 0; b < TAIL[b_len].size(); b++){

				tmp_B = TAIL[b_len][b];

				tmp_state = 0;

				for(int loop = 0; loop < common_part_len+1; loop++){

					add_B_len = loop;

					if(add_B_len == 0){
						if(tmp_B < POW_10[b_len-1]){
							continue;
						}
						auto at = MAP[B].find(tmp_B);
						if(at == MAP[B].end()){
							//Do nothing
						}else{
							tmp_state += POW_2[loop];
						}
						continue;
					}

					part_num = substr_tail(common_num,add_B_len);

					if(part_num < POW_10[add_B_len-1]){
						continue;
					}

					tmp_num = part_num*POW_10[b_len]+tmp_B;

					auto at = MAP[B].find(tmp_num);

					if(at == MAP[B].end()){
						//Do nothing
					}else{
						tmp_state += POW_2[loop];
					}
				}

				for(int i = 0; i < state_table[tmp_state].size(); i++){
					dp[B][state_table[tmp_state][i]] += 1;
				}
			}

			for(int state = 1; state < POW_2[common_part_len+1]; state++){

				num_bit = 0;

				for(int loop = 0; loop < common_part_len+1; loop++){
					if(state & (1 << loop)){
						num_bit++;
					}
				}

				if(num_bit%2 == 1){

					ans += dp[A][state]*dp[B][state];

				}else{

					ans -= dp[A][state]*dp[B][state];
				}
			}
		}
	}
	printf("%lld\n",ans);
}

void make_state_table(){

	bool check[4];
	bool FLG;

	for(int state = 1; state < 16; state++){
		for(int loop = 0; loop < 4; loop++){
			if(state & (1 << loop)){
				check[loop] = true;
			}else{
				check[loop] = false;
			}
		}

		for(int add_state = 1; add_state < 16; add_state++){
			FLG = true;
			for(int loop = 0; loop < 4; loop++){
				if(add_state & (1 << loop)){
					if(!check[loop]){
						FLG = false;
						break;
					}
				}
			}
			if(FLG){
				state_table[state].push_back(add_state);
			}
		}
	}
}

void makeTable(){

	int work[3],tmp;
	stack<int> S;

	for(int num = 0; num <= 999; num++){

		tmp = num;

		for(int i = 2; i >= 0; i--){
			work[i] = tmp%10;
			tmp /= 10;
		}

		for(int common_part_len = 1; common_part_len <= 3; common_part_len++){
			for(int head_len = 1; head_len <= common_part_len; head_len++){
				tmp = 0;
				for(int k = 0; k < head_len; k++){
					tmp = 10*tmp+work[3-common_part_len+k];
				}
				head_table[num][common_part_len][head_len] = tmp;
			}
		}
	}
}

int main(){

	for(int i = 0; i < 7; i++){
		POW_2[i] = pow(2,i);
		POW_10[i] = pow(10,i);
	}

	makeTable();

	make_state_table();

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 7870
memory_kb: 118560
final_rank: 19

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 7

enum Type{
	A,
	B,
};

struct Info{
	int low,high;
};

int N;
int POW_2[7],POW_10[7];
int MIN_LEN[2],MAX_LEN[2];
Info info[NUM];
ll dp[2][16];
map<int,bool> MAP[2];
ll num_list[2][NUM]; //長さ別の数字のリスト
int head_min[NUM],head_max[NUM]; //先頭[len]文字の最小・最大数(A用)
int tail_min[NUM],tail_max[NUM]; //末尾[len]文字の最小・最大長(B用)
int head_table[1000][4][4]; //head_table[common_part_len][先頭から切り出す桁数] = 数

vector<int> state_table[16];
vector<int> HEAD[NUM],TAIL[NUM];

int get_length(ll num){

	if(num == 0){
		return 1;
	}

	int ret = 0;

	while(num > 0){
		num /= 10;
		ret++;
	}

	return ret;
}

//numの先頭len文字の数字を作る
int substr_front(int num,int tmp_len,int cut_len){

	num /= POW_10[tmp_len-cut_len];
	return num;
}

//numの末尾len文字の数字を作る
int substr_tail(int num,int len){
	num %= POW_10[len];
	return num;
}

//数字を作る
void recursive(Type type,int index,int finish_index,int num){

	int tmp_length;

	if(index == finish_index+1){

		auto at = MAP[type].find(num);
		if(at != MAP[type].end())return; //登録済

		MAP[type][num] = true;
		tmp_length = get_length(num);
		MAX_LEN[type] = max(MAX_LEN[type],tmp_length);
		MIN_LEN[type] = min(MIN_LEN[type],tmp_length);
		num_list[type][tmp_length] += 1;

		int tmp;

		if(type == A){

			for(int i = 1; i <= tmp_length; i++){
				tmp = substr_front(num,tmp_length,i);
				HEAD[i].push_back(tmp);
			}

		}else{

			for(int i = 1; i <= tmp_length; i++){
				tmp = substr_tail(num,i);
				TAIL[i].push_back(tmp);
			}
		}
		return;
	}

	int tmp_num,tmp_len,next_num;
	//次の数字を全探索する
	for(int i = info[index].low; i <= info[index].high; i++){
		tmp_len = get_length(i);
		next_num = num*POW_10[tmp_len]+i;
		recursive(type,index+1,finish_index,next_num);
	}
}

void init_dp(){

	for(int i = 0; i < 16; i++){
		dp[A][i] = 0;
		dp[B][i] = 0;
	}
}

bool rangeCheck(int num_B){
	if(num_B >= MIN_LEN[B] && num_B <= MAX_LEN[B]){
		return true;
	}else{
		return false;
	}
}

void func(){

	MAP[A].clear();
	MAP[B].clear();

	for(int i = 1; i < NUM; i++){
		num_list[A][i] = 0;
		num_list[B][i] = 0;

		head_min[i] = BIG_NUM;
		tail_min[i] = BIG_NUM;

		head_max[i] = 0;
		tail_max[i] = 0;

		HEAD[i].clear();
		TAIL[i].clear();
	}

	for(int i = 0; i < N; i++){
		scanf("%d %d",&info[i].low,&info[i].high);
	}

	MIN_LEN[A] = BIG_NUM;
	MIN_LEN[B] = BIG_NUM;

	MAX_LEN[A] = -1;
	MAX_LEN[B] = -1;

	//前半・後半でグループを作り、あらかじめ数字を作っておく
	recursive(A,0,N/2-1,0);
	recursive(B,N/2,N-1,0);

	for(int i = 1; i <= 5; i++){
		sort(HEAD[i].begin(), HEAD[i].end());
		HEAD[i].erase(unique(HEAD[i].begin(),HEAD[i].end()),HEAD[i].end());

		sort(TAIL[i].begin(),TAIL[i].end());
		TAIL[i].erase(unique(TAIL[i].begin(),TAIL[i].end()),TAIL[i].end());
	}

	int common_part_len; //中央部の長さ:0～3であるはず
	int common_max;

	ll ans = 0;

	bool is_First;
	int A_min,A_max,B_min,B_max;
	int tmp_A,tmp_B,add_A_len,add_B_len,part_num,tmp_num;
	int num_bit,a_len,b_len,tmp_state;

	bool FLG;

	for(int total_len = MIN_LEN[A]+MIN_LEN[B]; total_len <= MAX_LEN[A]+MAX_LEN[B]; total_len++){

		//中央部の長さと、中央部の数の上限を求める
		is_First = true;
		for(int a = MIN_LEN[A]; a <= min(MAX_LEN[A],total_len); a++){

			if(!rangeCheck(total_len-a))continue; //Bの長さが不適ならSKIP

			if(is_First){

				A_min = a;
				A_max = a;

				B_min = total_len-a;
				B_max = total_len-a;
				is_First = false;
			}else{
				A_max = a;
				B_min = total_len-a;
			}
		}

		common_part_len = A_max-A_min;

		if(common_part_len == 0){ //共通部の長さが0

			//包除原理の適用不要
			ll count_A = num_list[A][A_min];
			ll count_B = num_list[B][B_max];

			ans += count_A*count_B;

			continue;
		}

		//★共通部として考えられる、長さcommon_part_lenの数字を全探索★
		common_max = POW_10[common_part_len]-1;

		for(int common_num = 0; common_num <= common_max; common_num++){

			//★★★★共通の数字別に数え上げる★★★★
			init_dp();

			a_len = A_min;

			//Aの数字全探索
			for(int a = 0; a < HEAD[a_len].size(); a++){

				int tmp_A = HEAD[a_len][a];

				tmp_state = 0;

				for(int loop = 0; loop < common_part_len+1; loop++){

					//★common_numのうち、先頭common_part_len-loopがcommon_numにおけるAの専有部
					add_A_len = common_part_len-loop;

					if(add_A_len == 0){
						auto at = MAP[A].find(tmp_A);
						if(at == MAP[A].end()){ //tmp_Aが存在しない数字なら不可
							//Do nothing
						}else{
							tmp_state += POW_2[loop];
						}
						continue;
					}

					part_num = head_table[common_num][common_part_len][add_A_len];

					//先頭から現れるべき数字
					tmp_num = tmp_A*POW_10[add_A_len]+part_num;

					auto at = MAP[A].find(tmp_num);

					if(at == MAP[A].end()){ //条件を満たす数字がないので、今回のsateは計上しない
						//Do nothing
					}else{
						tmp_state += POW_2[loop];
					}
				}

				for(int i = 0; i < state_table[tmp_state].size(); i++){
					dp[A][state_table[tmp_state][i]] += 1;
				}
			}

			b_len = B_min;

			//Bの数字全探索
			for(int b = 0; b < TAIL[b_len].size(); b++){ //★★Bは左に数字を付け加えるので0スタート★★

				tmp_B = TAIL[b_len][b];

				tmp_state = 0;

				for(int loop = 0; loop < common_part_len+1; loop++){
					//★common_numのうち、末尾loopがcommon_numにおけるBの専有部

					add_B_len = loop;

					if(add_B_len == 0){
						if(tmp_B < POW_10[b_len-1]){ //先頭0は不可
							continue;
						}
						auto at = MAP[B].find(tmp_B);
						if(at == MAP[B].end()){ //作れない数字は不可
							//Do nothing
						}else{
							tmp_state += POW_2[loop];
						}
						continue;
					}

					part_num = substr_tail(common_num,add_B_len);

					if(part_num < POW_10[add_B_len-1]){ //★★先頭0は不可★★
						continue;
					}

					//Bとして現れるべき数字
					tmp_num = part_num*POW_10[b_len]+tmp_B;

					auto at = MAP[B].find(tmp_num);

					if(at == MAP[B].end()){ //条件を満たす数字がないので、今回のsateは計上しない
						//Do nothing
					}else{
						tmp_state += POW_2[loop];
					}
				}

				for(int i = 0; i < state_table[tmp_state].size(); i++){
					dp[B][state_table[tmp_state][i]] += 1;
				}
			}

			//★中央の数字ごとにdp集計<包除原理>★
			for(int state = 1; state < POW_2[common_part_len+1]; state++){

				num_bit = 0;

				for(int loop = 0; loop < common_part_len+1; loop++){
					if(state & (1 << loop)){
						num_bit++;
					}
				}

				if(num_bit%2 == 1){

					ans += dp[A][state]*dp[B][state];

				}else{

					ans -= dp[A][state]*dp[B][state];
				}
			}
		}
	}
	printf("%lld\n",ans);
}

//1～15の状態の、サブstateをあらかじめ求める関数
void make_state_table(){

	bool check[4];
	bool FLG;

	for(int state = 1; state < 16; state++){
		for(int loop = 0; loop < 4; loop++){
			if(state & (1 << loop)){
				check[loop] = true;
			}else{
				check[loop] = false;
			}
		}

		for(int add_state = 1; add_state < 16; add_state++){
			FLG = true;
			for(int loop = 0; loop < 4; loop++){
				if(add_state & (1 << loop)){
					if(!check[loop]){
						FLG = false;
						break;
					}
				}
			}
			if(FLG){
				state_table[state].push_back(add_state); //stateにおいて、add_stateがsub stateとして存在
			}
		}
	}
}

//0～999の数字の、先頭1～3桁の数の事前計算
void makeTable(){

	int work[3],tmp;
	stack<int> S;

	for(int num = 0; num <= 999; num++){ //数字

		tmp = num;

		for(int i = 2; i >= 0; i--){ //右詰めで数字を配置
			work[i] = tmp%10;
			tmp /= 10;
		}

		for(int common_part_len = 1; common_part_len <= 3; common_part_len++){ //全体の桁数
			for(int head_len = 1; head_len <= common_part_len; head_len++){
				tmp = 0;
				for(int k = 0; k < head_len; k++){
					tmp = 10*tmp+work[3-common_part_len+k];
				}
				head_table[num][common_part_len][head_len] = tmp;
			}
		}
	}
}

int main(){

	for(int i = 0; i < 7; i++){
		POW_2[i] = pow(2,i);
		POW_10[i] = pow(10,i);
	}

	makeTable();

	make_state_table();

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 7870
memory_kb: 118496
final_rank: 18

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

ll dp[13][1<<13][10]; //桁数, 現在のエレベーター,　前の桁 

bool solve(){
  int n;
  int low[7], up[7];
  
  scanf("%d", &n);
  if(n == 0) return false;
  
  for(int i=0;i<n;i++) scanf("%d%d", low+i, up+i);

  memset(dp, 0, sizeof(dp));

  dp[0][1][0] = 1;

  ll ans = 0;

  for(int i=0;i<n*2;i++){
    for(int j=0;j<(1<<(2*n));j++){
      for(int k=0;k<10;k++){
        if(!dp[i][j][k]) continue;
        int next[10] = {};

        for(int l=0;l<n;l++){
          //1桁目
          if((1 << (l*2)) & j){
            for(int x=max(1,low[l]);x<=min(9, up[l]);x++)
              next[x] |= 1 << (l*2+2);
            for(int x=max(1,low[l]/10);x<=min(9,up[l]/10);x++)
              next[x] |= 1 << (l*2+1);
          }
          //2桁目
          if((1 << (l*2+1)) & j){
            for(int x=max(0,(low[l]-k*10));x<=min(9, up[l]-k*10);x++)
              next[x] |= 1 << (l*2+2);
          }
        }

        for(int l=0;l<10;l++){
          dp[i+1][next[l] & ((1 << n*2) - 1)][l] += dp[i][j][k];
          if(next[l] & (1 << (n*2))) ans += dp[i][j][k];
        }
        
      }
    }
  }
  
  cout << ans << endl;
  return true;
}

int main(){
  while(solve());
  
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 11464
final_rank: 6

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

ll dp[13][1<<13][10]; //桁数, 現在のエレベーター,　前の桁 

bool solve(){
  int n;
  int low[7], up[7];
  
  scanf("%d", &n);
  if(n == 0) return false;
  
  for(int i=0;i<n;i++) scanf("%d%d", low+i, up+i);

  memset(dp, 0, sizeof(dp));

  dp[0][1][0] = 1;

  ll ans = 0;

  for(int i=0;i<n*2;i++){
    for(int j=0;j<(1<<(2*n));j++){
      for(int k=0;k<10;k++){
        int next[10] = {};

        for(int l=0;l<n;l++){
          //1桁目
          if((1 << (l*2)) & j){
            for(int x=max(1,low[l]);x<=min(9, up[l]);x++)
              next[x] |= 1 << (l*2+2);
            for(int x=max(1,low[l]/10);x<=min(9,up[l]/10);x++)
              next[x] |= 1 << (l*2+1);
          }
          //2桁目
          if((1 << (l*2+1)) & j){
            for(int x=max(0,(low[l]-k*10));x<=min(9, up[l]-k*10);x++)
              next[x] |= 1 << (l*2+2);
          }
        }

        for(int l=0;l<10;l++){
          dp[i+1][next[l] & ((1 << n*2) - 1)][l] += dp[i][j][k];
          if(next[l] & (1 << (n*2))) ans += dp[i][j][k];
        }
        
      }
    }
  }
  
  cout << ans << endl;
  return true;
}

int main(){
  while(solve());
  
  return 0;
}
accuracy: 1
time_ms: 1200
memory_kb: 11468
final_rank: 9

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

ll dp[13][1<<13][10]; //桁数, 現在のエレベーター,　前の桁 

bool solve(){
  int n;
  int low[7], up[7];
  
  scanf("%d", &n);
  if(n == 0) return false;
  
  for(int i=0;i<n;i++) scanf("%d%d", low+i, up+i);

  memset(dp, 0, sizeof(dp));

  dp[0][1][0] = 1;

  for(int i=0;i<n*2;i++){
    for(int j=0;j<(1<<(2*n+1));j++){
      for(int k=0;k<10;k++){
        int next[10] = {};

        for(int l=0;l<n;l++){
          //1桁目
          if((1 << (l*2)) & j){
            for(int x=max(1,low[l]);x<=min(9, up[l]);x++)
              next[x] |= 1 << (l*2+2);
            for(int x=max(1,low[l]/10);x<=min(9,up[l]/10);x++)
              next[x] |= 1 << (l*2+1);
          }
          //2桁目
          if((1 << (l*2+1)) & j){
            for(int x=max(0,(low[l]-k*10));x<=min(9, up[l]-k*10);x++)
              next[x] |= 1 << (l*2+2);
          }
        }

        for(int l=0;l<10;l++){
          dp[i+1][next[l]][l] += dp[i][j][k];
        }
        
      }
    }
  }

  ll ans = 0;
  
  for(int i=0;i<=n*2;i++)
    for(int j=0;j<(1<<(2*n));j++)
      for(int k=0;k<10;k++)
        ans += dp[i][j + (1<<n*2)][k];

  cout << ans << endl;
  return true;
}

int main(){
  while(solve());
  
  return 0;
}
accuracy: 1
time_ms: 2190
memory_kb: 11560
final_rank: 11