// clang-format off
	#include <bits/stdc++.h>
	using namespace std; using ll = long long; using uint = unsigned int; using ull = unsigned long long;
	#define SFINAE(x, ...)	template <class, class = void> struct x : false_type {}; template <class T> struct x<T, void_t<__VA_ARGS__>> : true_type {};
	SFINAE(DefaultIO, decltype(cout << declval<T &>()))
	SFINAE(IsTuple, typename tuple_size<T>::type)
	SFINAE(Iterable, decltype(begin(declval<T>())))
	template <class T> constexpr char Space(const T &) { return (Iterable<T>::value or IsTuple<T>::value) ? '\n' : ' '; }
	template <auto &os> struct Writer {
		template <class T> void Impl(T const &t) const {
			if constexpr (DefaultIO<T>::value) os << t;
			else if constexpr (Iterable<T>::value) { int i = 0; for (auto &&x : t) ((i++) ? (os << Space(x), Impl(x)) : Impl(x)); }
			else if constexpr (IsTuple<T>::value) apply([this](auto const &... args) { int i = 0; (((i++) ? (os << ' ', Impl(args)) : Impl(args)), ...);}, t);
			else static_assert(IsTuple<T>::value, "No matching type for print");
		}
		template <class F, class... Ts> auto &operator()(F const &f, Ts const &... ts) const { return Impl(f), ((os << ' ', Impl(ts)), ...), os << '\n', *this; }
	};
	template <auto &is> struct Reader {
		template <class T> auto& Rd(T &t) const {
			if constexpr (DefaultIO<T>::value) is >> t;
			else if constexpr (Iterable<T>::value) for (auto &x : t) Rd(x);
			else if constexpr (IsTuple<T>::value) apply([this](auto &... args) { (Rd(args), ...); }, t);
			else static_assert(IsTuple<T>::value, "No matching type for read");
			return *this;
		}
		template <class T> auto operator[](T t) const { Rd(t); return t; }	
		template <class... Ts> auto operator()(Ts... ts) const { (Rd(ts), ...); return tuple{move(ts)...}; }
	};
	#ifdef NARUT_LOCAL
	#define Debug(...) cerr << "\033[0;31m", Writer<cerr>{}(__VA_ARGS__), cerr << "\033[0m\n"
	#else
	#define Debug(...) 0
	#endif
	[[maybe_unused]] constexpr Reader<cin> Cin; [[maybe_unused]] constexpr Writer<cout> Cout;
	#define FOR(i, j, n) for (int i = int(j); i < int(n); ++i)
	#define ROF(i, j, n) for (int i = int(n) - 1; i >= int(j); --i)
	#define let auto const
// clang-format on

// auto rmq = RangeQuery<int>(v.begin(), v.end());
template <class T> struct RangeQuery { //+
	uint sz = 0;
	vector<T> tree;

	RangeQuery() = default;
	RangeQuery(uint n) : sz(getSz(n)), tree(2 * sz) {}
	template <class It> RangeQuery(It first, It last) : sz(getSz((last - first))) {
		tree.reserve(2 * sz), tree.resize(sz);
		tree.insert(tree.end(), first, last), tree.resize(2 * sz);
		build();
	}

	const T &operator[](uint u) const { return tree[u + sz]; }

	void Rebuild(uint u) {
		for (u /= 2; u > 0; u /= 2) tree[u] = tree[2 * u] + tree[2 * u + 1];
	}

	template <class F> T const &Modify(uint u, F &&func) {
		func(tree[u += sz]);
		Rebuild(u);
		return tree[u];
	}

	void Set(uint u, T elem) {
		tree[u += sz] = move(elem);
		Rebuild(u);
	}

	T const &Add(uint u, T const &elem) {
		return Modify(u, [&](auto &e) { e = e + elem; });
	}

	T QueryExc(uint l, uint r) const { // [l, r)
		T left{}, right{};
		for (l += sz, r += sz; l < r; l /= 2, r /= 2) {
			if (l % 2) left = left + tree[l++];
			if (r % 2) right = tree[--r] + right;
		}
		return left + right;
	}

	T QueryInc(uint l, uint r) const { return QueryExc(l, r + 1); }

	// Dir = 0 for left, 1 for right
	template <uint Dir, class F> uint BinSearch(F &&func) const {
		if (!func(tree[1])) return -1u;
		uint u = 1;
		for (T cur{}; u < sz;) {
			if (auto nxt = cur + tree[2 * u + Dir]; func(nxt))
				u = 2 * u + Dir;
			else
				u = 2 * u + !Dir, cur = move(nxt);
		}
		return u - sz;
	}

	static uint getSz(uint n) {
		if (n < 2) return 1;
		return 1u << (sizeof(uint) * 8 - __builtin_clz(n - 1));
	}

  private:
	void build() {
		for (uint i = sz - 1; i; --i) tree[i] = tree[2 * i] + tree[2 * i + 1];
	}
};


using ull = unsigned long long;

auto Parse(string s) {
	auto dot = s.find('.');
	if(dot == s.npos) {
		s.insert(s.end(), 9, '0');
	} else {
		s.insert(s.end(), 10-(s.length()-dot), '0');
		s.erase(s.begin()+dot);
	}
	return stoll(s);
}

auto Factor(ull x) {
	uint f = 0, t = 0;
	while(x % 5 == 0) f++, x/= 5;
	while(x % 2 == 0) t++, x/= 2;
	return pair{f,t};	
}

auto Main() {
	let n = Cin[0];
	vector<pair<int, int> > F;
	
	array<RangeQuery<int>, 26> R;
	for(auto& rq: R) {
		rq = RangeQuery<int>(60);
	}
	
	FOR(ni,0,n) {
		let a = Parse(Cin[""s]);
		let [f,t] = Factor(a);
		F.emplace_back(f,t);
		R[f].Add(t, 1);		
	}
	ull ans = 0;
	for(auto [f, t] : F) {
		auto needf = max(0, 18 - f);
		auto needt = max(0, 18 - t);
		FOR(ff, needf, 26) {
			ans += R[ff].QueryExc(needt, 60);
		}
		if (needf <= f and needt <= t) ans--;
		R[f].Add(t, -1);
	}		
	cout << ans;	
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(10);
#ifdef NARUT_LOCAL
	assert(freopen("io/test.in", "r", stdin));
	cin.exceptions(cin.badbit | cin.failbit);
	cerr << fixed << setprecision(10);
#endif

	Main();
}


Measured memory_bytes: 5160