#include <bits/stdc++.h>
#define int long long
#define double long double
#define rep(i, a, n) for(int i = (int)(a);(i) < (int)(n);++(i))
#define repe(i, a, n) for(int i = (int)(a);(i) <= (int)(n);++(i))
#define repif(i, a, x) for(int i = (int)(a);(x);++(i))
#define repr(i, a, n) for(int i = ((int)(a)-1);(i) >= (int)(n);--(i))
#define reper(i, a, n) for(int i = (int)(a);(i) >= (int)(n);--(i))
#define SZ(x) ((int)(x).size())
#define ALL(x) begin(x), end(x)
#define CEIL(x) ((int)ceil(((double)x)))
#define POW(x, y) ((int)pow(x, y))
#define UNIQUE(x) (x).erase(unique(ALL((x))), end(x))
#define gcd(x, y) __gcd(x, y)
#define lcm(x, y) ((x)/gcd(x,y)*(y))
using namespace std;
using VI = vector<int>;
using VVI = vector<vector<int>>;
using PII = pair<int, int>;
using TIII = tuple<int, int, int>;
using VPII = vector<pair<int, int>>;
using VTIII = vector<tuple<int, int, int>>;
using Complex = complex<double>;
template<typename T> inline bool chmax(T& a, const T& b, bool t = false){ if(a<b or (t and a==b)){ a=b; return true; } return false; }
template<typename T> inline bool chmin(T& a, const T& b, bool t = false){ if(a>b or (t and a==b)){ a=b; return true; } return false; }
template<typename T> inline bool isin(const T& x, const T& l, const T& r){ return l <= x and x < r; }
inline ostream& fcout(int n = 10){ return cout << fixed << setprecision(n); }
inline ostream& rcout(int n = 2){ return cout << right << setw(n); }
constexpr int64_t INF = numeric_limits<int64_t>::max();
constexpr int32_t INF32 = numeric_limits<int32_t>::max();
constexpr int64_t MOD = 1000000007LL;
constexpr double PI = 3.14159265358979323846264338327950288;
constexpr double EPS = 1e-10;


template<typename T>
struct CumulativeSum2D {
    vector<vector<T>> dat;
    CumulativeSum2D() = default;
    CumulativeSum2D(int h, int w) : dat(h+1, vector<T>(w+1)){}
    CumulativeSum2D(const vector<vector<T>>& v){
        int h = v.size(), w = v[0].size();
        dat.resize(h+1);
        for(int i = 0;i < h+1;++i) dat[i].resize(w+1);
        for(int i = 0;i < h;++i) for(int j = 0;j < w;++j) dat[i+1][j+1] = dat[i+1][j]+dat[i][j+1]-dat[i][j]+v[i][j];
    }
    inline void add(int x, int y, T a){
        dat[y+1][x+1] += a;
    }
    inline void build(){
        int h = dat.size()-1, w = dat[0].size()-1;
        for(int i = 0;i < h;++i) for(int j = 0;j < w;++j) dat[i+1][j+1] += dat[i+1][j]+dat[i][j+1]-dat[i][j];
    }
    //[x1, x2)×[y1, y2)
    inline T query(int x1, int x2, int y1, int y2) const {
        return dat[y2][x2]-dat[y2][x1]-dat[y1][x2]+dat[y1][x1];
    }
};


int M, N;
int K;
CumulativeSum2D<int> S[3];


int32_t main(){
    cin >> M >> N;
    cin >> K;
    rep(i, 0, 3) S[i] = CumulativeSum2D<int>(M, N);
    rep(i, 0, M) rep(j, 0, N){
        char c;
        cin >> c;
        if(c == 'J') S[0].add(j, i, 1);
        else if(c == 'O') S[1].add(j, i, 1);
        else S[2].add(j, i, 1);
    }
    rep(i, 0, 3) S[i].build();

    rep(i, 0, K){
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        a--;
        b--;
        c--;
        d--;
        rep(i, 0, 2) cout << S[i].query(b, d+1, a, c+1) << ' ';
        cout << S[2].query(b, d+1, a, c+1) << endl;
    }

    return 0;
}


Measured memory_bytes: 26040