#include <cassert>
#include <vector>

//===
// memory: O(HW)
// time: O(logH * logW)
template<class CommutativeMonoid>
struct SegmentTree2D {
    using M = CommutativeMonoid;
    using T = typename M::value_type;
    const std::size_t H, W;
    std::vector<std::vector<T>> tree;

    SegmentTree2D(size_t H, size_t W):H(H), W(W) {
        tree.assign(H << 1, std::vector<T>(W << 1, M::identity()));
    };

    void update(int sy, int sx, T dat) {
        sy += H;
        sx += W;
        int ty, tx;
        tree[sy][sx] = dat;
        tx = sx;
        while (tx > 1) {
            tx >>= 1;
            tree[sy][tx] = M::operation(tree[sy][(tx << 1)],
                    tree[sy][(tx << 1) | 1]);
        }

        ty = sy;
        while (ty > 1) {
            ty >>= 1;
            tx = sx;
            tree[ty][tx] = M::operation(tree[(ty << 1)][tx],
                    tree[(ty << 1) | 1][tx]);
            while (tx > 1) {
                tx >>= 1;
                tree[ty][tx] = M::operation(tree[(ty << 1)][tx],
                        tree[(ty << 1) | 1][tx]);
            }
        }
    };

    T fold(int sy, int sx, int ty, int tx) {
        sy += H;
        ty += H;

        T ret = M::identity();
        while (sy < ty) {
            if (sy & 1) ret = M::operation(ret, fold_x(sy++, sx, tx));
            if (ty & 1) ret = M::operation(fold_x(--ty, sx, tx), ret);
            sy >>= 1;
            ty >>= 1;
        }
        return ret;
    };
    T fold_x(int y, int l, int r) {
        l += W;
        r += W;
        T ret = M::identity();
        while (l < r) {
            if (l & 1) ret = M::operation(ret, tree[y][l++]);
            if (r & 1) ret = M::operation(tree[y][--r], ret);
            l >>= 1;
            r >>= 1;
        }
        return ret;
    };

    T at(int sy, int sx) const {
        return tree[sy + H][sx + W];
    };
};
//===


#include <iostream>
#include <algorithm>
#include <cmath>

using i64 = long long;
#define _overload(_1, _2, _3, _4, name, ...) name
#define _rep1(Itr, N) _rep3(Itr, 0, N, 1)
#define _rep2(Itr, a, b) _rep3(Itr, a, b, 1)
#define _rep3(Itr, a, b, step) for (i64 (Itr) = a; (Itr) < b; (Itr) += step)
#define repeat(...) _overload(__VA_ARGS__, _rep3, _rep2, _rep1)(__VA_ARGS__)

using namespace std;
using llong = long long;

struct Monoid {
    using value_type = llong;
    inline static llong operation(llong a, llong b) {
        return a + b;
    };
    inline static llong identity() {
        return 0;
    };
};

llong n;
llong a[200005];
llong two[200005];
llong five[200005];
SegmentTree2D<Monoid> seg(64, 64);

int main() {
    auto f = [](llong x, llong d) {
        llong ret = 0;
        while (x > 0 && x % d == 0) {
            x /= d;
            ret++;
        }
        return ret;
    };
    auto deg = [](llong x) {
        llong ret = 0;
        while (x > 0) {
            ret++;
            x /= 10;
        }
        return ret;
    };

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    repeat(i, n) {
        string s;
        cin >> s;
        char ch;
        bool flg = false;
        int cnt = 0;

        for (char ch:s) {
            if (ch == '.') {
                flg = true;
                continue;
            }
            a[i] *= 10;
            a[i] += ch - '0';
            if (flg) cnt++;
        }

        repeat(j, 9 - cnt) {
            a[i] *= 10;
        }
    }

    repeat(i, n) {
        two[i] = f(a[i], 2);
        five[i] = f(a[i], 5);
    }

    llong ans = 0;
    repeat(i, n) {
        llong y = max(0ll, 18 - two[i]);
        llong x = max(0ll, 18 - five[i]);

        ans += seg.fold(y, x, 64, 64);

        seg.update(two[i], five[i], seg.at(two[i], five[i]) + 1);
    }

    cout << ans << endl;

    return 0;
};


Measured memory_bytes: 8408