import std.stdio;
import std.ascii;
import std.c.stdio;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.regex;
import std.typecons;

class AhoCorasick {
    class Trie {
        Trie fail;
        Trie[2] next; // 0 or 1
        int[] accept;
    }
    Trie PMA;
    int[string] patternId;
    this(string[] patterns) {
        patterns = patterns.sort.uniq.array;
        PMA = new Trie;
        foreach (int id, pattern; patterns) {
            Trie t = PMA;
            foreach (x; pattern) {
                int c = cast(int)(x - '0');
                if (t.next[c] is null) t.next[c] = new Trie;
                t = t.next[c];
            }
            t.accept ~= id + 1;
            patternId[pattern] = id + 1;
        }
        DList!Trie Q;
        foreach (x; "01") {
            int c = cast(int)(x - '0');
            if (PMA.next[c] is null) {
                PMA.next[c] = PMA;
            } else {
                PMA.next[c].fail = PMA;
                Q.insert(PMA.next[c]);
            }
        }
        while (!Q.empty) {
            Trie t = Q.front; Q.removeFront;
            foreach (x; "01") {
                int c = cast(int)(x - '0');
                if (t.next[c] is null) continue;
                Q.insert(t.next[c]);
                Trie r = t.fail;
                while (r.next[c] is null) r = r.fail;
                t.next[c].fail = r.next[c];
                t.next[c].accept ~= r.next[c].accept;
            }
        }
    }
    int[] match(string s) {
        auto Ret = new int[s.length];
        Ret[] = -1;
        Trie v = PMA;
        foreach (int i, x; s) {
            int c = cast(int)(x - '0');
            while (v.next[c] is null) v = v.fail;
            v = v.next[c];
            //assert(v.accept.empty || v.accept.length == 1);
            foreach (ac; v.accept) {
                Ret[i] = ac;
            }
        }
        return Ret;
    }
}

int[][] transform(int[][] X) {
    auto H = X.length, W = X[0].length;
    int[][] Ret = new int[][](W, H);
    foreach (i; 0 .. H) {
        foreach (j; 0 .. W) {
            Ret[j][i] = X[i][j];
        }
    }
    return Ret;
}

class KMP {
    immutable int[] s;
    int[] PMA;
    this(in int[] s) {
        this.s = s.idup;
        /* Pattern Matching Automaton を作る */
        auto M = s.length;
        PMA = new int[M + 1];
        PMA[0] = 0; PMA[1] = 0;
        for (int i = 2; i <= M; i++) {
            int j = PMA[i - 1];
            while (true) {
                if (s[j] == s[i - 1]) { PMA[i] = j + 1; break; }
                if (j == 0 && PMA[j] == 0) { PMA[i] = 0; break; }
                j = PMA[j];
            }
        }
    }
    int match(in int[] t) {
        auto N = t.length, M = s.length;
        int Count = 0;
        auto si = 0, ti = 0;
        try {
            while (ti < N) {
                if (s[si] == t[ti]) {
                    si++; ti++;
                } else {
                    if (si == 0) ti++;
                    si = PMA[si];
                }
                if (si == M) {
                    Count++;
                    si = PMA[si];
                    //assert(si < M);
                }
            }
        } catch (core.exception.RangeError e) {}
        return Count;
    }
}

void main() {
    int W, H, Pn;
    string[] F;
    string[] P;
    string decode(string s, int w) {
        int[] xs;
        foreach (c; s) {
            if (c.isUpper) xs ~= cast(int)(c - 'A');
            else if (c.isLower) xs ~= cast(int)(c - 'a' + 26);
            else if (c.isDigit) xs ~= cast(int)(c - '0' + 52);
            else if (c == '+') xs ~= 62;
            else if (c == '/') xs ~= 63;
            //else assert(0);
        }
        string Ret = xs.map!((x) => format("%06b", x)).join;
        return Ret[ 0 .. w ];
    }
    bool input() {
        readf("%d %d %d\n", &W, &H, &Pn);
        if (W == 0 && H == 0 && Pn == 0) return false;
        F = new string[H];
        foreach (i; 0 .. H) {
            F[i] = decode(readln.chomp, W);
        }
        P = new string[Pn];
        foreach (i; 0 .. Pn) {
            P[i] = decode(readln.chomp, Pn);
        }
        return true;
    }
    string[] dupP() {
        string[] Ret = new string[Pn];
        foreach (i; 0 .. Pn) Ret[i] = P[i].idup;
        return Ret;
    }
    int match() {
        auto nP = dupP;
        auto matcher = new AhoCorasick(nP);
        int[][] MatchTable = new int[][H];
        foreach (i; 0 .. H) {
            MatchTable[i] = matcher.match(F[i]);
        }
        MatchTable = transform(MatchTable);
        int[] index = new int[Pn];
        foreach (i, pL; P) {
            index[i] = matcher.patternId[pL];
        }
        auto colMatcher = new KMP(index);
        int Ret = 0;
        foreach (i; 0 .. W) {
            Ret += colMatcher.match(MatchTable[i]);
        }
        return Ret;
    }

    void mirror() {
        auto nP = new string[Pn];
        foreach (i; 0 .. Pn) {
            nP[i] = P[ Pn - i - 1 ].idup;
        }
        P = nP;
    }
    void rotate90() {
        auto nP = new char[][](Pn, Pn);
        foreach (i; 0 .. Pn) {
            foreach (j; 0 .. Pn) {
                nP[j][Pn - i - 1] = P[i][j];
            }
        }
        P = cast(string[])nP;
    }

    void solve() {
        import core.memory;
        GC.collect;
        int Ans = 0;
        bool[string] used;
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 4; j++) {
                if (!used.get(P.join(""), false)) {
                    Ans += match();
                    used[P.join("")] = true;
                }
                rotate90;
            }
            mirror;
        }
        writeln(Ans);
    }
    while (input) solve;
}

Measured memory_bytes: 17672